Minor: Fix the token expiry options order (#22049)

* Fix the token expiry options order

* Improve the logic and fix playwright tests

* fix sonar cloud issue

* Fix the type error
This commit is contained in:
Aniket Katkar 2025-07-02 15:41:40 +05:30 committed by GitHub
parent ce11e83e29
commit a35883fe76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 304 additions and 70 deletions

View File

@ -65,7 +65,7 @@ export const createBot = async (page: Page) => {
// Select expiry time // Select expiry time
await page.click('[data-testid="token-expiry"]'); await page.click('[data-testid="token-expiry"]');
await page.locator('[title="1 hr"] div').click(); await page.locator('[title="1 hour"] div').click();
await page.locator(descriptionBox).fill(BOT_DETAILS.description); await page.locator(descriptionBox).fill(BOT_DETAILS.description);
@ -165,7 +165,9 @@ export const tokenExpirationForDays = async (page: Page) => {
await page.click('[data-testid="token-expiry"]'); await page.click('[data-testid="token-expiry"]');
// Select the expiration period // Select the expiration period
await page.locator(`text=${expiryTime} days`).click(); await page
.locator(`text=${expiryTime} day${expiryTime > 1 ? 's' : ''}`)
.click();
// Save the updated date // Save the updated date
const expiryDate = customFormatDateTime( const expiryDate = customFormatDateTime(
@ -194,7 +196,7 @@ export const tokenExpirationUnlimitedDays = async (page: Page) => {
// Click on expiry token dropdown // Click on expiry token dropdown
await page.click('[data-testid="token-expiry"]'); await page.click('[data-testid="token-expiry"]');
// Select unlimited days // Select unlimited days
await page.getByText('Unlimited days').click(); await page.getByText('Unlimited').click();
// Save the selected changes // Save the selected changes
await page.click('[data-testid="save-edit"]'); await page.click('[data-testid="save-edit"]');
@ -238,7 +240,7 @@ export const resetTokenFromBotPage = async (page: Page, botName: string) => {
await expect(page.getByTestId('token-expiry').locator('div')).toBeVisible(); await expect(page.getByTestId('token-expiry').locator('div')).toBeVisible();
await page.getByText('hr').click(); await page.getByText('hr').click();
await page.getByText('Unlimited days').click(); await page.getByText('Unlimited').click();
await expect(page.getByTestId('save-edit')).toBeVisible(); await expect(page.getByTestId('save-edit')).toBeVisible();

View File

@ -468,7 +468,7 @@ export const generateToken = async (page: Page) => {
await page.click('[data-testid="token-expiry"]'); await page.click('[data-testid="token-expiry"]');
await page.locator('[title="1 hr"] div').click(); await page.locator('[title="1 hour"] div').click();
await expect(page.locator('[data-testid="token-expiry"]')).toBeVisible(); await expect(page.locator('[data-testid="token-expiry"]')).toBeVisible();
@ -491,9 +491,9 @@ export const revokeToken = async (page: Page, isBot?: boolean) => {
await expect(page.locator('[data-testid="revoke-button"]')).not.toBeVisible(); await expect(page.locator('[data-testid="revoke-button"]')).not.toBeVisible();
}; };
export const updateExpiration = async (page: Page, expiry: number | string) => { export const updateExpiration = async (page: Page, expiry: number) => {
await page.click('[data-testid="token-expiry"]'); await page.click('[data-testid="token-expiry"]');
await page.click(`text=${expiry} days`); await page.click(`text=${expiry} day${expiry > 1 ? 's' : ''}`);
const expiryDate = customFormatDateTime( const expiryDate = customFormatDateTime(
getEpochMillisForFutureDays(expiry as number), getEpochMillisForFutureDays(expiry as number),

View File

@ -112,17 +112,7 @@ const AuthMechanismForm: FC<Props> = ({
className="w-full" className="w-full"
data-testid="token-expiry" data-testid="token-expiry"
placeholder={t('message.select-token-expiration')}> placeholder={t('message.select-token-expiration')}>
{isBot {getJWTTokenExpiryOptions(!isBot)}
? getJWTTokenExpiryOptions().map((option) => (
<Option key={option.value}>{option.label}</Option>
))
: getJWTTokenExpiryOptions()
.filter((option) => option.value !== 'Unlimited')
.map((filteredOption) => (
<Option key={filteredOption.value}>
{filteredOption.label}
</Option>
))}
</Select> </Select>
</Form.Item> </Form.Item>

View File

@ -63,8 +63,6 @@ import Loader from '../../../common/Loader/Loader';
import TeamsSelectable from '../../Team/TeamsSelectable/TeamsSelectable'; import TeamsSelectable from '../../Team/TeamsSelectable/TeamsSelectable';
import { CreateUserProps } from './CreateUser.interface'; import { CreateUserProps } from './CreateUser.interface';
const { Option } = Select;
const CreateUser = ({ const CreateUser = ({
roles, roles,
isLoading, isLoading,
@ -262,9 +260,7 @@ const CreateUser = ({
className="w-full" className="w-full"
data-testid="token-expiry" data-testid="token-expiry"
placeholder={t('message.select-token-expiration')}> placeholder={t('message.select-token-expiration')}>
{getJWTTokenExpiryOptions().map((option) => ( {getJWTTokenExpiryOptions()}
<Option key={option.value}>{option.label}</Option>
))}
</Select> </Select>
</Form.Item> </Form.Item>
)} )}

View File

@ -12,9 +12,25 @@
*/ */
import { TokenType } from '../generated/auth/personalAccessToken'; import { TokenType } from '../generated/auth/personalAccessToken';
import { JWTTokenExpiry } from '../generated/entity/teams/user';
export const USER_DEFAULT_AUTHENTICATION_MECHANISM = { export const USER_DEFAULT_AUTHENTICATION_MECHANISM = {
tokenType: TokenType.PersonalAccessToken, tokenType: TokenType.PersonalAccessToken,
}; };
// Mapping of JWTTokenExpiry enum to numeric values in days
// This is used to sort the options in the JWTTokenExpiry dropdown
export const TOKEN_EXPIRY_NUMERIC_VALUES_IN_DAYS: Record<
JWTTokenExpiry,
number
> = {
[JWTTokenExpiry.OneHour]: 0.0417,
[JWTTokenExpiry.The1]: 1,
[JWTTokenExpiry.The7]: 7,
[JWTTokenExpiry.The30]: 30,
[JWTTokenExpiry.The60]: 60,
[JWTTokenExpiry.The90]: 90,
[JWTTokenExpiry.Unlimited]: Infinity,
};
export const MASKED_EMAIL = '********@masked.com'; export const MASKED_EMAIL = '********@masked.com';

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 Tag",
"1-hr": "1 Stunde",
"aborted": "Abgebrochen", "aborted": "Abgebrochen",
"accept": "Akzeptieren", "accept": "Akzeptieren",
"accept-all": "Alle akzeptieren", "accept-all": "Alle akzeptieren",
@ -937,6 +939,8 @@
"november": "November", "november": "November",
"null": "Null", "null": "Null",
"number": "Nummer", "number": "Nummer",
"number-day-plural": "{{number}} Tage",
"number-hr-plural": "{{number}} Stunden",
"number-of-object-plural": "Anzahl von Objekten", "number-of-object-plural": "Anzahl von Objekten",
"number-of-retries": "Anzahl der Wiederholungen", "number-of-retries": "Anzahl der Wiederholungen",
"number-of-rows": "Anzahl der Zeilen", "number-of-rows": "Anzahl der Zeilen",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "deinstalliert", "uninstalled-lowercase": "deinstalliert",
"unique": "Einzigartig", "unique": "Einzigartig",
"unit-of-measurement": "Maßeinheit", "unit-of-measurement": "Maßeinheit",
"unlimited": "Unbegrenzt",
"unpause": "Fortsetzen", "unpause": "Fortsetzen",
"unprocessed": "Unverarbeitet", "unprocessed": "Unverarbeitet",
"up-vote": "Upvote", "up-vote": "Upvote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 day",
"1-hr": "1 hour",
"aborted": "Aborted", "aborted": "Aborted",
"accept": "Accept", "accept": "Accept",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "November", "november": "November",
"null": "Null", "null": "Null",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} days",
"number-hr-plural": "{{number}} hours",
"number-of-object-plural": "Number of Objects", "number-of-object-plural": "Number of Objects",
"number-of-retries": "Number of Retries", "number-of-retries": "Number of Retries",
"number-of-rows": "Number of rows", "number-of-rows": "Number of rows",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "Unique", "unique": "Unique",
"unit-of-measurement": "Measurement Unit", "unit-of-measurement": "Measurement Unit",
"unlimited": "Unlimited",
"unpause": "UnPause", "unpause": "UnPause",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 día",
"1-hr": "1 hora",
"aborted": "Abortado", "aborted": "Abortado",
"accept": "Aceptar", "accept": "Aceptar",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "Noviembre", "november": "Noviembre",
"null": "Nulo", "null": "Nulo",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} días",
"number-hr-plural": "{{number}} horas",
"number-of-object-plural": "Número de objetos", "number-of-object-plural": "Número de objetos",
"number-of-retries": "Número de intentos", "number-of-retries": "Número de intentos",
"number-of-rows": "Número de filas", "number-of-rows": "Número de filas",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "Único", "unique": "Único",
"unit-of-measurement": "medida Unidad", "unit-of-measurement": "medida Unidad",
"unlimited": "Sin límite",
"unpause": "Reanudar", "unpause": "Reanudar",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Voto Positivo", "up-vote": "Voto Positivo",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 jour",
"1-hr": "1 heure",
"aborted": "Interrompu", "aborted": "Interrompu",
"accept": "Accepter", "accept": "Accepter",
"accept-all": "Tout Accepter", "accept-all": "Tout Accepter",
@ -937,6 +939,8 @@
"november": "Novembre", "november": "Novembre",
"null": "Null", "null": "Null",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} jours",
"number-hr-plural": "{{number}} heures",
"number-of-object-plural": "Nombre d'Objets", "number-of-object-plural": "Nombre d'Objets",
"number-of-retries": "Nombre de Tentatives", "number-of-retries": "Nombre de Tentatives",
"number-of-rows": "Nombre de lignes", "number-of-rows": "Nombre de lignes",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "désinstallé", "uninstalled-lowercase": "désinstallé",
"unique": "Unique", "unique": "Unique",
"unit-of-measurement": "Unité de mesure", "unit-of-measurement": "Unité de mesure",
"unlimited": "Illimité",
"unpause": "Réactiver", "unpause": "Réactiver",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Voter", "up-vote": "Voter",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 día",
"1-hr": "1 hora",
"aborted": "Abortado", "aborted": "Abortado",
"accept": "Aceptar", "accept": "Aceptar",
"accept-all": "Aceptar todo", "accept-all": "Aceptar todo",
@ -937,6 +939,8 @@
"november": "Novembro", "november": "Novembro",
"null": "Nulo", "null": "Nulo",
"number": "Número", "number": "Número",
"number-day-plural": "{{number}} días",
"number-hr-plural": "{{number}} horas",
"number-of-object-plural": "Número de obxectos", "number-of-object-plural": "Número de obxectos",
"number-of-retries": "Número de reintentos", "number-of-retries": "Número de reintentos",
"number-of-rows": "Número de filas", "number-of-rows": "Número de filas",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "desinstalado", "uninstalled-lowercase": "desinstalado",
"unique": "Único", "unique": "Único",
"unit-of-measurement": "Unidade de medida", "unit-of-measurement": "Unidade de medida",
"unlimited": "Sen límite",
"unpause": "Reanudar", "unpause": "Reanudar",
"unprocessed": "Sen procesar", "unprocessed": "Sen procesar",
"up-vote": "Voto positivo", "up-vote": "Voto positivo",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 יום",
"1-hr": "1 שעה",
"aborted": "בוטל", "aborted": "בוטל",
"accept": "קבל", "accept": "קבל",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "נובמבר", "november": "נובמבר",
"null": "ריק", "null": "ריק",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} ימים",
"number-hr-plural": "{{number}} שעות",
"number-of-object-plural": "מספר אובייקטים", "number-of-object-plural": "מספר אובייקטים",
"number-of-retries": "מספר ניסיונות מחדש", "number-of-retries": "מספר ניסיונות מחדש",
"number-of-rows": "מספר השורות", "number-of-rows": "מספר השורות",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "ייחודי", "unique": "ייחודי",
"unit-of-measurement": "יחידת מדידה", "unit-of-measurement": "יחידת מדידה",
"unlimited": "ללא מגבלה",
"unpause": "בטל השהייה", "unpause": "בטל השהייה",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 日",
"1-hr": "1 時間",
"aborted": "中断", "aborted": "中断",
"accept": "Accept", "accept": "Accept",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "11月", "november": "11月",
"null": "Null", "null": "Null",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} 日",
"number-hr-plural": "{{number}} 時間",
"number-of-object-plural": "Number of Objects", "number-of-object-plural": "Number of Objects",
"number-of-retries": "Number of Retries", "number-of-retries": "Number of Retries",
"number-of-rows": "行数", "number-of-rows": "行数",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "ユニーク", "unique": "ユニーク",
"unit-of-measurement": "単位", "unit-of-measurement": "単位",
"unlimited": "無制限",
"unpause": "再開", "unpause": "再開",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 일",
"1-hr": "1 시간",
"aborted": "중단됨", "aborted": "중단됨",
"accept": "수락", "accept": "수락",
"accept-all": "모두 수락", "accept-all": "모두 수락",
@ -937,6 +939,8 @@
"november": "11월", "november": "11월",
"null": "널", "null": "널",
"number": "숫자", "number": "숫자",
"number-day-plural": "{{number}} 일",
"number-hr-plural": "{{number}} 시간",
"number-of-object-plural": "객체 수", "number-of-object-plural": "객체 수",
"number-of-retries": "재시도 횟수", "number-of-retries": "재시도 횟수",
"number-of-rows": "행 수", "number-of-rows": "행 수",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "제거됨", "uninstalled-lowercase": "제거됨",
"unique": "고유", "unique": "고유",
"unit-of-measurement": "측정 단위", "unit-of-measurement": "측정 단위",
"unlimited": "무제한",
"unpause": "일시 중지 해제", "unpause": "일시 중지 해제",
"unprocessed": "처리되지 않음", "unprocessed": "처리되지 않음",
"up-vote": "추천", "up-vote": "추천",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 दिवस",
"1-hr": "1 तास",
"aborted": "निरस्त केले", "aborted": "निरस्त केले",
"accept": "स्वीकार करा", "accept": "स्वीकार करा",
"accept-all": "सर्व स्वीकार करा", "accept-all": "सर्व स्वीकार करा",
@ -937,6 +939,8 @@
"november": "नोव्हेंबर", "november": "नोव्हेंबर",
"null": "नल", "null": "नल",
"number": "संख्या", "number": "संख्या",
"number-day-plural": "{{number}} दिवस",
"number-hr-plural": "{{number}} तास",
"number-of-object-plural": "वस्तूंची संख्या", "number-of-object-plural": "वस्तूंची संख्या",
"number-of-retries": "पुन्हा प्रयत्नांची संख्या", "number-of-retries": "पुन्हा प्रयत्नांची संख्या",
"number-of-rows": "पंक्तींची संख्या", "number-of-rows": "पंक्तींची संख्या",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "अनइंस्टॉल केले", "uninstalled-lowercase": "अनइंस्टॉल केले",
"unique": "अद्वितीय", "unique": "अद्वितीय",
"unit-of-measurement": "मोजण्याचे एकक", "unit-of-measurement": "मोजण्याचे एकक",
"unlimited": "अनिर्धारित",
"unpause": "पुन्हा सुरू करा", "unpause": "पुन्हा सुरू करा",
"unprocessed": "प्रक्रिया न केलेले", "unprocessed": "प्रक्रिया न केलेले",
"up-vote": "वर मत द्या", "up-vote": "वर मत द्या",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 dag",
"1-hr": "1 uur",
"aborted": "Afgebroken", "aborted": "Afgebroken",
"accept": "Accepteren", "accept": "Accepteren",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "november", "november": "november",
"null": "Null", "null": "Null",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} dagen",
"number-hr-plural": "{{number}} uren",
"number-of-object-plural": "Aantal objecten", "number-of-object-plural": "Aantal objecten",
"number-of-retries": "Aantal herhalingen", "number-of-retries": "Aantal herhalingen",
"number-of-rows": "Aantal rijen", "number-of-rows": "Aantal rijen",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "Uniek", "unique": "Uniek",
"unit-of-measurement": "Meeteenheid", "unit-of-measurement": "Meeteenheid",
"unlimited": "Onbeperkt",
"unpause": "Hervatten", "unpause": "Hervatten",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 روز",
"1-hr": "1 ساعت",
"aborted": "لغو شده", "aborted": "لغو شده",
"accept": "پذیرفتن", "accept": "پذیرفتن",
"accept-all": "پذیرفتن همه", "accept-all": "پذیرفتن همه",
@ -937,6 +939,8 @@
"november": "نوامبر", "november": "نوامبر",
"null": "تهی", "null": "تهی",
"number": "عدد", "number": "عدد",
"number-day-plural": "{{number}} روز",
"number-hr-plural": "{{number}} ساعت",
"number-of-object-plural": "تعداد اشیا", "number-of-object-plural": "تعداد اشیا",
"number-of-retries": "تعداد تلاش‌ها", "number-of-retries": "تعداد تلاش‌ها",
"number-of-rows": "تعداد ردیف‌ها", "number-of-rows": "تعداد ردیف‌ها",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "حذف شده", "uninstalled-lowercase": "حذف شده",
"unique": "منحصر به فرد", "unique": "منحصر به فرد",
"unit-of-measurement": "واحد اندازه‌گیری", "unit-of-measurement": "واحد اندازه‌گیری",
"unlimited": "بدون محدودیت",
"unpause": "ادامه", "unpause": "ادامه",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "رای مثبت", "up-vote": "رای مثبت",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 dia",
"1-hr": "1 hora",
"aborted": "Abortado", "aborted": "Abortado",
"accept": "Aceitar", "accept": "Aceitar",
"accept-all": "Aceitar todos", "accept-all": "Aceitar todos",
@ -937,6 +939,8 @@
"november": "Novembro", "november": "Novembro",
"null": "Nulo", "null": "Nulo",
"number": "Número", "number": "Número",
"number-day-plural": "{{number}} dias",
"number-hr-plural": "{{number}} horas",
"number-of-object-plural": "Número de Objetos", "number-of-object-plural": "Número de Objetos",
"number-of-retries": "Número de Tentativas", "number-of-retries": "Número de Tentativas",
"number-of-rows": "Número de linhas", "number-of-rows": "Número de linhas",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "desinstalado", "uninstalled-lowercase": "desinstalado",
"unique": "Único", "unique": "Único",
"unit-of-measurement": "Medida Unidade ", "unit-of-measurement": "Medida Unidade ",
"unlimited": "Ilimitado",
"unpause": "Continuar", "unpause": "Continuar",
"unprocessed": "Não processado", "unprocessed": "Não processado",
"up-vote": "Voto positivo", "up-vote": "Voto positivo",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 dia",
"1-hr": "1 hora",
"aborted": "Abortado", "aborted": "Abortado",
"accept": "Aceitar", "accept": "Aceitar",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "Novembro", "november": "Novembro",
"null": "Nulo", "null": "Nulo",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} dias",
"number-hr-plural": "{{number}} horas",
"number-of-object-plural": "Número de Objetos", "number-of-object-plural": "Número de Objetos",
"number-of-retries": "Número de Tentativas", "number-of-retries": "Número de Tentativas",
"number-of-rows": "Número de linhas", "number-of-rows": "Número de linhas",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "Único", "unique": "Único",
"unit-of-measurement": "Unidade de medida", "unit-of-measurement": "Unidade de medida",
"unlimited": "Ilimitado",
"unpause": "Continuar", "unpause": "Continuar",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 день",
"1-hr": "1 час",
"aborted": "Прервано", "aborted": "Прервано",
"accept": "Принять", "accept": "Принять",
"accept-all": "Accept All", "accept-all": "Accept All",
@ -937,6 +939,8 @@
"november": "Ноябрь", "november": "Ноябрь",
"null": "Пустые значения", "null": "Пустые значения",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} дней",
"number-hr-plural": "{{number}} часов",
"number-of-object-plural": "Количество объектов", "number-of-object-plural": "Количество объектов",
"number-of-retries": "Number of Retries", "number-of-retries": "Number of Retries",
"number-of-rows": "Количество строк", "number-of-rows": "Количество строк",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "uninstalled", "uninstalled-lowercase": "uninstalled",
"unique": "Уникальные значения", "unique": "Уникальные значения",
"unit-of-measurement": "Единица измерения", "unit-of-measurement": "Единица измерения",
"unlimited": "Без ограничений",
"unpause": "Снять паузу", "unpause": "Снять паузу",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 วัน",
"1-hr": "1 ชั่วโมง",
"aborted": "ยกเลิก", "aborted": "ยกเลิก",
"accept": "ยอมรับ", "accept": "ยอมรับ",
"accept-all": "ยอมรับทั้งหมด", "accept-all": "ยอมรับทั้งหมด",
@ -937,6 +939,8 @@
"november": "พฤศจิกายน", "november": "พฤศจิกายน",
"null": "ค่าว่าง", "null": "ค่าว่าง",
"number": "หมายเลข", "number": "หมายเลข",
"number-day-plural": "{{number}} วัน",
"number-hr-plural": "{{number}} ชั่วโมง",
"number-of-object-plural": "จำนวนวัตถุ", "number-of-object-plural": "จำนวนวัตถุ",
"number-of-retries": "จำนวนครั้งที่ลองใหม่", "number-of-retries": "จำนวนครั้งที่ลองใหม่",
"number-of-rows": "จำนวนแถว", "number-of-rows": "จำนวนแถว",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "ถอนการติดตั้งแล้ว", "uninstalled-lowercase": "ถอนการติดตั้งแล้ว",
"unique": "ไม่ซ้ำ", "unique": "ไม่ซ้ำ",
"unit-of-measurement": "หน่วยการวัด", "unit-of-measurement": "หน่วยการวัด",
"unlimited": "ไม่จำกัด",
"unpause": "เลิกหยุดชั่วคราว", "unpause": "เลิกหยุดชั่วคราว",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "โหวตขึ้น", "up-vote": "โหวตขึ้น",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 gün",
"1-hr": "1 saat",
"aborted": "İptal Edildi", "aborted": "İptal Edildi",
"accept": "Kabul Et", "accept": "Kabul Et",
"accept-all": "Tümünü Kabul Et", "accept-all": "Tümünü Kabul Et",
@ -937,6 +939,8 @@
"november": "Kasım", "november": "Kasım",
"null": "Boş", "null": "Boş",
"number": "Sayı", "number": "Sayı",
"number-day-plural": "{{number}} gün",
"number-hr-plural": "{{number}} saat",
"number-of-object-plural": "Nesne Sayısı", "number-of-object-plural": "Nesne Sayısı",
"number-of-retries": "Yeniden Deneme Sayısı", "number-of-retries": "Yeniden Deneme Sayısı",
"number-of-rows": "Satır sayısı", "number-of-rows": "Satır sayısı",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "kaldırıldı", "uninstalled-lowercase": "kaldırıldı",
"unique": "Benzersiz", "unique": "Benzersiz",
"unit-of-measurement": "Ölçü Birimi", "unit-of-measurement": "Ölçü Birimi",
"unlimited": "Sınırsız",
"unpause": "Devam Ettir", "unpause": "Devam Ettir",
"unprocessed": "İşlenmemiş", "unprocessed": "İşlenmemiş",
"up-vote": "Yukarı Oy", "up-vote": "Yukarı Oy",

View File

@ -1,5 +1,7 @@
{ {
"label": { "label": {
"1-day": "1 天",
"1-hr": "1 小时",
"aborted": "已中止", "aborted": "已中止",
"accept": "接受", "accept": "接受",
"accept-all": "接受所有", "accept-all": "接受所有",
@ -937,6 +939,8 @@
"november": "十一月", "november": "十一月",
"null": "Null", "null": "Null",
"number": "Number", "number": "Number",
"number-day-plural": "{{number}} 天",
"number-hr-plural": "{{number}} 小时",
"number-of-object-plural": "对象个数", "number-of-object-plural": "对象个数",
"number-of-retries": "重试次数", "number-of-retries": "重试次数",
"number-of-rows": "行数", "number-of-rows": "行数",
@ -1479,6 +1483,7 @@
"uninstalled-lowercase": "已卸载", "uninstalled-lowercase": "已卸载",
"unique": "唯一", "unique": "唯一",
"unit-of-measurement": "计量单位", "unit-of-measurement": "计量单位",
"unlimited": "无限制",
"unpause": "取消暂停", "unpause": "取消暂停",
"unprocessed": "Unprocessed", "unprocessed": "Unprocessed",
"up-vote": "Up Vote", "up-vote": "Up Vote",

View File

@ -0,0 +1,106 @@
/*
* Copyright 2022 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { render, screen } from '@testing-library/react';
import { getJWTTokenExpiryOptions } from './BotsUtils';
jest.mock('antd', () => ({
...jest.requireActual('antd'),
Select: {
Option: ({ children }: { children: React.ReactNode }) => {
return <div className="ant-select-option">{children}</div>;
},
},
}));
describe('getJWTTokenExpiryOptions', () => {
it('should return all JWT token expiry options when filterUnlimited is false (default)', () => {
const result = getJWTTokenExpiryOptions();
render(<>{result}</>);
// Check for specific options (using the actual translation keys from global mock)
expect(screen.getByText('label.1-hr')).toBeInTheDocument();
expect(screen.getByText('label.1-day')).toBeInTheDocument();
expect(screen.getAllByText('label.number-day-plural')).toHaveLength(4);
expect(screen.getByText('label.unlimited')).toBeInTheDocument();
});
it('should return all JWT token expiry options when filterUnlimited is explicitly false', () => {
const result = getJWTTokenExpiryOptions(false);
const { container } = render(<>{result}</>);
// Should contain all 7 options including Unlimited
expect(container.querySelectorAll('.ant-select-option')).toHaveLength(7);
expect(container.textContent).toContain('label.unlimited');
});
it('should filter out Unlimited option when filterUnlimited is true', () => {
const result = getJWTTokenExpiryOptions(true);
const { container } = render(<>{result}</>);
// Should contain only 6 options (excluding Unlimited)
expect(container.querySelectorAll('.ant-select-option')).toHaveLength(6);
// Check for specific options (using the actual translation keys from global mock)
expect(container.textContent).toContain('label.1-hr');
expect(container.textContent).toContain('label.1-day');
expect(container.textContent).toContain('label.number-day-plural');
expect(container.textContent).toContain('label.number-day-plural');
expect(container.textContent).toContain('label.number-day-plural');
expect(container.textContent).toContain('label.number-day-plural');
// Should NOT contain Unlimited
expect(container.textContent).not.toContain('label.unlimited');
});
it('should return Option components with correct key and content', () => {
const result = getJWTTokenExpiryOptions();
const { container } = render(<>{result}</>);
const options = container.querySelectorAll('.ant-select-option');
// Check that each option has the correct structure
options.forEach((option) => {
expect(option).toBeInTheDocument();
expect(option.tagName).toBe('DIV');
});
// Check first option specifically (using actual translation keys)
expect(options[0].textContent).toBe('label.1-hr');
expect(options[1].textContent).toBe('label.1-day');
expect(options[2].textContent).toBe('label.number-day-plural');
expect(options[3].textContent).toBe('label.number-day-plural');
expect(options[4].textContent).toBe('label.number-day-plural');
expect(options[5].textContent).toBe('label.number-day-plural');
expect(options[6].textContent).toBe('label.unlimited');
});
it('should maintain correct order of options', () => {
const result = getJWTTokenExpiryOptions();
const { container } = render(<>{result}</>);
const options = container.querySelectorAll('.ant-select-option');
const optionTexts = Array.from(options).map((option) => option.textContent);
// Check the order matches the expected order (using actual translation keys)
expect(optionTexts).toEqual([
'label.1-hr',
'label.1-day',
'label.number-day-plural',
'label.number-day-plural',
'label.number-day-plural',
'label.number-day-plural',
'label.unlimited',
]);
});
});

View File

@ -1,47 +0,0 @@
/*
* Copyright 2022 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { JWTTokenExpiry } from '../generated/entity/teams/user';
import {
DATE_TIME_WEEKDAY_WITH_ORDINAL,
formatDateTimeLong,
} from './date-time/DateTimeUtils';
export const getJWTTokenExpiryOptions = () => {
return Object.keys(JWTTokenExpiry).map((expiry) => {
const expiryValue = JWTTokenExpiry[expiry as keyof typeof JWTTokenExpiry];
const isHourOption = expiryValue === JWTTokenExpiry.OneHour;
return {
label: isHourOption ? '1 hr' : `${expiryValue} days`,
value: expiryValue,
};
});
};
/**
*
* @param expiry expiry timestamp
* @returns TokenExpiry
*/
export const getTokenExpiry = (expiry: number) => {
// get the current date timestamp
const currentTimeStamp = Date.now();
const isTokenExpired = currentTimeStamp >= expiry;
return {
tokenExpiryDate: formatDateTimeLong(expiry, DATE_TIME_WEEKDAY_WITH_ORDINAL),
isTokenExpired,
};
};

View File

@ -0,0 +1,86 @@
/*
* Copyright 2022 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Select } from 'antd';
import { TOKEN_EXPIRY_NUMERIC_VALUES_IN_DAYS } from '../constants/User.constants';
import { JWTTokenExpiry } from '../generated/entity/teams/user';
import {
DATE_TIME_WEEKDAY_WITH_ORDINAL,
formatDateTimeLong,
} from './date-time/DateTimeUtils';
import { t } from './i18next/LocalUtil';
const { Option } = Select;
const getJWTTokenExpiryLabel = (expiry: JWTTokenExpiry) => {
switch (expiry) {
case JWTTokenExpiry.OneHour:
return t('label.1-hr');
case JWTTokenExpiry.The1:
return t('label.1-day');
case JWTTokenExpiry.The7:
return t('label.number-day-plural', { number: 7 });
case JWTTokenExpiry.The30:
return t('label.number-day-plural', { number: 30 });
case JWTTokenExpiry.The60:
return t('label.number-day-plural', { number: 60 });
case JWTTokenExpiry.The90:
return t('label.number-day-plural', { number: 90 });
case JWTTokenExpiry.Unlimited:
return t('label.unlimited');
default:
return expiry;
}
};
export const getJWTTokenExpiryOptions = (filterUnlimited = false) => {
let finalOptions = Object.values(JWTTokenExpiry).map((expiry) => ({
label: getJWTTokenExpiryLabel(expiry),
value: expiry,
numericValue: TOKEN_EXPIRY_NUMERIC_VALUES_IN_DAYS[expiry],
}));
if (filterUnlimited) {
finalOptions = finalOptions.filter(
(option) => option.value !== JWTTokenExpiry.Unlimited
);
}
// Create a new array to avoid mutating the original array
// spread is necessary to avoid the sonar issue:
// Array-mutating methods should not be used misleadingly typescript:S4043
const sortedOptions = [...finalOptions].sort(
(a, b) => a.numericValue - b.numericValue
);
return sortedOptions.map((option) => (
<Option key={option.value}>{option.label}</Option>
));
};
/**
*
* @param expiry expiry timestamp
* @returns TokenExpiry
*/
export const getTokenExpiry = (expiry: number) => {
// get the current date timestamp
const currentTimeStamp = Date.now();
const isTokenExpired = currentTimeStamp >= expiry;
return {
tokenExpiryDate: formatDateTimeLong(expiry, DATE_TIME_WEEKDAY_WITH_ORDINAL),
isTokenExpired,
};
};