diff --git a/react/src/components/KeypairInfoModal.tsx b/react/src/components/KeypairInfoModal.tsx index aac88e307e..423e40d156 100644 --- a/react/src/components/KeypairInfoModal.tsx +++ b/react/src/components/KeypairInfoModal.tsx @@ -1,125 +1,133 @@ -/** - @license - Copyright (c) 2015-2024 Lablup Inc. All rights reserved. - */ -import { useSuspendedBackendaiClient } from '../hooks'; -import { useCurrentUserInfo } from '../hooks/backendai'; -import { useTanQuery } from '../hooks/reactQueryAlias'; -import BAIModal, { BAIModalProps } from './BAIModal'; +import BAIModal from './BAIModal'; import Flex from './Flex'; +import { KeypairInfoModalFragment$key } from './__generated__/KeypairInfoModalFragment.graphql'; import { KeypairInfoModalQuery } from './__generated__/KeypairInfoModalQuery.graphql'; -import { Button, Table, Typography, Tag } from 'antd'; +import { Descriptions, ModalProps, Tag, Typography, theme } from 'antd'; import graphql from 'babel-plugin-relay/macro'; -import React from 'react'; -import { useTranslation } from 'react-i18next'; -import { useLazyLoadQuery } from 'react-relay'; +import dayjs from 'dayjs'; +import { t } from 'i18next'; +import { useFragment, useLazyLoadQuery } from 'react-relay'; -interface KeypairInfoModalProps extends BAIModalProps { +interface KeypairInfoModalProps extends ModalProps { + keypairInfoModalFrgmt: KeypairInfoModalFragment$key | null; onRequestClose: () => void; } const KeypairInfoModal: React.FC = ({ + keypairInfoModalFrgmt = null, onRequestClose, - ...baiModalProps + ...modalProps }) => { - const { t } = useTranslation(); - const [userInfo] = useCurrentUserInfo(); - const baiClient = useSuspendedBackendaiClient(); - const { data: keypairs } = useTanQuery({ - queryKey: ['baiClient.keypair.list', baiModalProps.open], // refetch on open state - queryFn: () => { - return baiModalProps.open - ? baiClient.keypair - .list( - userInfo.email, - ['access_key', 'secret_key', 'is_active'], - true, - ) - .then((res: any) => res.keypairs) - : null; - }, - staleTime: 0, - }); + const { token } = theme.useToken(); - const supportMainAccessKey = baiClient?.supports('main-access-key'); + const keypair = useFragment( + graphql` + fragment KeypairInfoModalFragment on KeyPair { + user_id + access_key + secret_key + is_admin + created_at + last_used + resource_policy + num_queries + rate_limit + concurrency_used @since(version: "24.09.0") + } + `, + keypairInfoModalFrgmt, + ); + // FIXME: Keypair query does not support main_access_key info. const { user } = useLazyLoadQuery( graphql` - query KeypairInfoModalQuery($email: String) { - user(email: $email) { - email - main_access_key @since(version: "23.09.7") + query KeypairInfoModalQuery($domain_name: String, $email: String) { + user(domain_name: $domain_name, email: $email) { + main_access_key @since(version: "24.03.0") } } `, { - email: userInfo.email, + email: keypair?.user_id, + }, + { + fetchPolicy: + modalProps.open && keypair?.user_id ? 'network-only' : 'store-only', }, ); return ( { - onRequestClose(); - }} - > - {t('button.Close')} - , - ]} + title={ + + + {t('credential.KeypairDetail')} + + {user?.main_access_key === keypair?.access_key && ( + {t('credential.MainAccessKey')} + )} + + } + onCancel={() => onRequestClose()} + footer={null} + {...modalProps} > - { - ++index; - return index; - }, - showSorterTooltip: false, - rowScope: 'row', - }, - { - title: t('general.AccessKey'), - key: 'accessKey', - dataIndex: 'access_key', - fixed: 'left', - render: (value) => ( - - - {value} - - {supportMainAccessKey && value === user?.main_access_key && ( - {t('credential.MainAccessKey')} - )} - - ), - }, - { - title: t('general.SecretKey'), - key: 'secretKey', - dataIndex: 'secret_key', - fixed: 'left', - render: (value) => ( - - {value} - - ), - }, - ]} - /> + + + {keypair?.user_id} + + + {keypair?.access_key} + + + + {keypair?.secret_key ? '********' : ''} + + + + {keypair?.is_admin ? ( + <> + admin + user + + ) : ( + user + )} + + + {dayjs(keypair?.created_at).format('lll')} + + + {keypair?.last_used ? dayjs(keypair?.last_used).format('lll') : '-'} + + +
+ + + {keypair?.resource_policy} + + + {keypair?.num_queries} + + + {keypair?.concurrency_used} + + + {keypair?.rate_limit} + + ); }; diff --git a/react/src/components/KeypairResourcePolicySelector.tsx b/react/src/components/KeypairResourcePolicySelector.tsx new file mode 100644 index 0000000000..d7394d61b0 --- /dev/null +++ b/react/src/components/KeypairResourcePolicySelector.tsx @@ -0,0 +1,53 @@ +import { localeCompare } from '../helper'; +import useControllableState from '../hooks/useControllableState'; +import { KeypairResourcePolicySelectorQuery } from './__generated__/KeypairResourcePolicySelectorQuery.graphql'; +import { Select, SelectProps } from 'antd'; +import graphql from 'babel-plugin-relay/macro'; +import _ from 'lodash'; +import { useTranslation } from 'react-i18next'; +import { useLazyLoadQuery } from 'react-relay'; + +interface KeypairResourcePolicySelectorProps extends SelectProps {} + +const KeypairResourcePolicySelector: React.FC< + KeypairResourcePolicySelectorProps +> = ({ ...selectProps }) => { + const { t } = useTranslation(); + const [value, setValue] = useControllableState({ + value: selectProps.value, + onChange: selectProps.onChange, + }); + + const { keypair_resource_policies } = + useLazyLoadQuery( + graphql` + query KeypairResourcePolicySelectorQuery { + keypair_resource_policies { + name + } + } + `, + {}, + { fetchPolicy: 'store-and-network' }, + ); + + return ( + + + )} + + + + + + + + + + + + + + + ); +}; + +export default KeypairSettingModal; diff --git a/react/src/components/MyKeypairInfoModal.tsx b/react/src/components/MyKeypairInfoModal.tsx new file mode 100644 index 0000000000..fcc4fb25a0 --- /dev/null +++ b/react/src/components/MyKeypairInfoModal.tsx @@ -0,0 +1,126 @@ +/** + @license + Copyright (c) 2015-2024 Lablup Inc. All rights reserved. + */ +import { useSuspendedBackendaiClient } from '../hooks'; +import { useCurrentUserInfo } from '../hooks/backendai'; +import { useTanQuery } from '../hooks/reactQueryAlias'; +import BAIModal, { BAIModalProps } from './BAIModal'; +import Flex from './Flex'; +import { MyKeypairInfoModalQuery } from './__generated__/MyKeypairInfoModalQuery.graphql'; +import { Button, Table, Typography, Tag } from 'antd'; +import graphql from 'babel-plugin-relay/macro'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useLazyLoadQuery } from 'react-relay'; + +interface MyKeypairInfoModalProps extends BAIModalProps { + onRequestClose: () => void; +} + +const MyKeypairInfoModal: React.FC = ({ + onRequestClose, + ...baiModalProps +}) => { + const { t } = useTranslation(); + const [userInfo] = useCurrentUserInfo(); + const baiClient = useSuspendedBackendaiClient(); + const { data: keypairs } = useTanQuery({ + queryKey: ['baiClient.keypair.list', baiModalProps.open], // refetch on open state + queryFn: () => { + return baiModalProps.open + ? baiClient.keypair + .list( + userInfo.email, + ['access_key', 'secret_key', 'is_active'], + true, + ) + .then((res: any) => res.keypairs) + : null; + }, + staleTime: 0, + }); + + const supportMainAccessKey = baiClient?.supports('main-access-key'); + + const { user } = useLazyLoadQuery( + graphql` + query MyKeypairInfoModalQuery($email: String) { + user(email: $email) { + email + main_access_key @since(version: "23.09.7") + } + } + `, + { + email: userInfo.email, + }, + ); + + return ( + { + onRequestClose(); + }} + > + {t('button.Close')} + , + ]} + > +
{ + ++index; + return index; + }, + rowScope: 'row', + }, + { + title: t('general.AccessKey'), + key: 'accessKey', + dataIndex: 'access_key', + fixed: 'left', + render: (value) => ( + + + {value} + + {supportMainAccessKey && value === user?.main_access_key && ( + {t('credential.MainAccessKey')} + )} + + ), + }, + { + title: t('general.SecretKey'), + key: 'secretKey', + dataIndex: 'secret_key', + fixed: 'left', + render: (value) => ( + + {value} + + ), + }, + ]} + /> + + ); +}; + +export default MyKeypairInfoModal; diff --git a/react/src/components/UserCredentialList.tsx b/react/src/components/UserCredentialList.tsx index dab5a9571d..849abd4fcf 100644 --- a/react/src/components/UserCredentialList.tsx +++ b/react/src/components/UserCredentialList.tsx @@ -8,9 +8,15 @@ import { useBAIPaginationOptionState } from '../hooks/reactPaginationQueryOption import BAIPropertyFilter from './BAIPropertyFilter'; import BAITable from './BAITable'; import Flex from './Flex'; +import KeypairInfoModal from './KeypairInfoModal'; +import KeypairSettingModal from './KeypairSettingModal'; +import { KeypairSettingModalFragment$key } from './__generated__/KeypairSettingModalFragment.graphql'; import { UserCredentialListDeleteMutation } from './__generated__/UserCredentialListDeleteMutation.graphql'; import { UserCredentialListModifyMutation } from './__generated__/UserCredentialListModifyMutation.graphql'; -import { UserCredentialListQuery } from './__generated__/UserCredentialListQuery.graphql'; +import { + UserCredentialListQuery, + UserCredentialListQuery$data, +} from './__generated__/UserCredentialListQuery.graphql'; import { DeleteOutlined, InfoCircleOutlined, @@ -36,6 +42,10 @@ import { useState, useTransition } from 'react'; import { useTranslation } from 'react-i18next'; import { useLazyLoadQuery, useMutation } from 'react-relay'; +type Keypair = NonNullable< + NonNullable['items'][number] +>; + const UserCredentialList: React.FC = () => { const { t } = useTranslation(); const { token } = theme.useToken(); @@ -45,10 +55,20 @@ const UserCredentialList: React.FC = () => { const [activeType, setActiveType] = useState<'active' | 'inactive'>('active'); const [order, setOrder] = useState(undefined); const [filterString, setFilterString] = useState(); + const [keypairSettingModalFrgmt, setKeypairSettingModalFrgmt] = + useState(null); + const [openUserKeypairSettingModal, setOpenUserKeypairSettingModal] = + useState(false); + const [keypairInfoModalFrgmt, setKeypairInfoModalFrgmt] = useState(null); + const [isPendingRefresh, startRefreshTransition] = useTransition(); const [isActiveTypePending, startActiveTypeTransition] = useTransition(); const [isPendingPageChange, startPageChangeTransition] = useTransition(); const [isPendingFilter, startFilterTransition] = useTransition(); + const [isPendingInfoModalOpen, startInfoModalOpenTransition] = + useTransition(); + const [isPendingSettingModalOpen, startSettingModalOpenTransition] = + useTransition(); const { baiPaginationOption, @@ -89,6 +109,9 @@ const UserCredentialList: React.FC = () => { rate_limit num_queries concurrency_used @since(version: "24.09.0") + + ...KeypairSettingModalFragment + ...KeypairInfoModalFragment } total_count } @@ -216,12 +239,18 @@ const UserCredentialList: React.FC = () => { icon={} /> - - // resizable rowKey={'id'} scroll={{ x: 'max-content' }} @@ -238,10 +267,13 @@ const UserCredentialList: React.FC = () => { { key: 'userID', title: t('credential.UserID'), - dataIndex: 'user_id', + dataIndex: 'email', fixed: 'left', - // FIXME: sorter is not working - // sorter: true, + sorter: true, + // TODO: user_id field in keypair_list is used as user's email, but sorting is done by email field + render: (value, record) => { + return record.user_id; + }, }, { key: 'accessKey', @@ -344,7 +376,7 @@ const UserCredentialList: React.FC = () => { key: 'control', title: t('general.Control'), fixed: 'right', - render: (record) => { + render: (value, record) => { return ( , - ]} + footer={null} onCancel={onRequestClose} {...baiModalProps} > -
{ {curTabKey === 'general' && } {curTabKey === 'logs' && } - diff --git a/resources/i18n/de.json b/resources/i18n/de.json index 472d733054..a4a584597f 100644 --- a/resources/i18n/de.json +++ b/resources/i18n/de.json @@ -538,7 +538,6 @@ "Allocation": "Zuweisung", "Information": "Information", "Created": "Erstellt", - "Lastused": "Zuletzt verwendeten", "ResourcePolicy": "Ressourcenrichtlinie", "NumberOfQueries": "Anzahl der Abfragen", "ConcurrentSessions": "Gleichzeitige Sitzungen", @@ -610,7 +609,9 @@ "CreatedAt": "Erstellt am", "SignoutSuccessfullyFinished": "Die Abmeldung ist erfolgreich abgeschlossen", "AccessKey": "Zugriffsschlüssel", + "SecretKey": "Geheimer Schlüssel", "StatusUpdatedSuccessfully": "Der Benutzerstatus hat sich geändert.", + "LastUsed": "Zuletzt verwendeten", "Queries": "Abfragen", "ReqPer15Min": "Erforderlich pro 15 Min", "Sessions": "Sitzungen", diff --git a/resources/i18n/el.json b/resources/i18n/el.json index 71dc8a6568..e4db01f925 100644 --- a/resources/i18n/el.json +++ b/resources/i18n/el.json @@ -538,7 +538,6 @@ "Allocation": "Κατανομή", "Information": "Πληροφορίες", "Created": "Δημιουργήθηκε", - "Lastused": "Τελευταία χρήση", "ResourcePolicy": "Πολιτική πόρων", "NumberOfQueries": "Αριθμός ερωτημάτων", "ConcurrentSessions": "Ταυτόχρονες συνεδρίες", @@ -610,7 +609,9 @@ "CreatedAt": "Δημιουργήθηκε στο", "SignoutSuccessfullyFinished": "Η αποσύνδεση ολοκληρώθηκε επιτυχώς", "AccessKey": "Κλειδί πρόσβασης", + "SecretKey": "Μυστικό κλειδί", "StatusUpdatedSuccessfully": "Η κατάσταση του χρήστη έχει αλλάξει.", + "LastUsed": "Τελευταία χρήση", "Queries": "Ερωτήματα", "ReqPer15Min": "Απαίτηση ανά 15 λεπτά", "Sessions": "Συνεδρίες", diff --git a/resources/i18n/en.json b/resources/i18n/en.json index e1ee1aec0d..7076fd1b70 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -665,7 +665,6 @@ "Allocation": "Allocation", "Information": "Information", "Created": "Created", - "Lastused": "Last used", "ResourcePolicy": "Resource Policy", "NumberOfQueries": "Number Of Queries", "ConcurrentSessions": "Concurrent Sessions", @@ -737,10 +736,12 @@ "CreatedAt": "Created At", "SignoutSuccessfullyFinished": "Signout is seccessfully finished", "AccessKey": "Access Key", + "SecretKey": "Secret Key", "StatusUpdatedSuccessfully": "The user status has changed.", "Queries": "Queries", "ReqPer15Min": "Req per 15 min", "Sessions": "Sessions", + "LastUsed": "Last Used", "KeypairStatusUpdatedSuccessfully": "The keypair status has changed.", "KeypairSuccessfullyDeleted": "KeyPair is successfully deleted.", "ActivateUser": "Activate user", diff --git a/resources/i18n/es.json b/resources/i18n/es.json index e7508c8d6a..55e1e46125 100644 --- a/resources/i18n/es.json +++ b/resources/i18n/es.json @@ -177,7 +177,6 @@ "KeyAge": "Edad clave", "KeypairCreated": "Par de claves creado con éxito.", "KeypairDetail": "Detalle del par de claves", - "Lastused": "Último utilizado", "Max#": "Máx. # de carpetas", "ModifyKeypairResourcePolicy": "Modificar la política de recursos de pares de claves", "ModifyUserDetail": "Modificar detalle de usuario", @@ -229,10 +228,12 @@ "CreatedAt": "Creado en", "SignoutSuccessfullyFinished": "El proceso de registro ha finalizado", "AccessKey": "Clave de acceso", + "SecretKey": "clave secreta", "StatusUpdatedSuccessfully": "El estado del usuario ha cambiado.", "Queries": "Consultas", "ReqPer15Min": "Requerido por 15 min", "Sessions": "Sesiones", + "LastUsed": "Último utilizado", "KeypairStatusUpdatedSuccessfully": "El estado del par de claves ha cambiado.", "KeypairSuccessfullyDeleted": "KeyPair se eliminó correctamente.", "ActivateUser": "Activar usuario", diff --git a/resources/i18n/fi.json b/resources/i18n/fi.json index dac8af21b4..55c3e627ae 100644 --- a/resources/i18n/fi.json +++ b/resources/i18n/fi.json @@ -177,7 +177,6 @@ "KeyAge": "Avain Ikä", "KeypairCreated": "Avainparin luominen onnistui.", "KeypairDetail": "Avainparin tiedot", - "Lastused": "Viimeksi käytetty", "Max#": "Max. # Kansioiden määrä", "ModifyKeypairResourcePolicy": "Muokkaa avainparin resurssikäytäntöä", "ModifyUserDetail": "Muokkaa käyttäjän tietoja", @@ -229,10 +228,12 @@ "CreatedAt": "Luotu klo", "SignoutSuccessfullyFinished": "Uloskirjautuminen on päättynyt hetkessä", "AccessKey": "Pääsyavain", + "SecretKey": "Salainen avain", "StatusUpdatedSuccessfully": "Käyttäjän tila on muuttunut.", "Queries": "Kyselyt", "ReqPer15Min": "Req per 15 min", "Sessions": "Istunnot", + "LastUsed": "Viimeksi käytetty", "KeypairStatusUpdatedSuccessfully": "Näppäinparin tila on muuttunut.", "KeypairSuccessfullyDeleted": "Avainparin poistaminen onnistui.", "ActivateUser": "Aktivoi käyttäjä", diff --git a/resources/i18n/fr.json b/resources/i18n/fr.json index c452defd16..a604177229 100644 --- a/resources/i18n/fr.json +++ b/resources/i18n/fr.json @@ -538,7 +538,6 @@ "Allocation": "Allocation", "Information": "Informations", "Created": "Créé", - "Lastused": "Dernière utilisation", "ResourcePolicy": "Politique de ressources", "NumberOfQueries": "Nombre de requêtes", "ConcurrentSessions": "Sessions simultanées", @@ -610,10 +609,12 @@ "CreatedAt": "Créé à", "SignoutSuccessfullyFinished": "La signature est terminée en toute sécurité", "AccessKey": "Clé d'accès", + "SecretKey": "Clé secrète", "StatusUpdatedSuccessfully": "Le statut de l'utilisateur a changé.", "Queries": "Requêtes", "ReqPer15Min": "Demande par 15 min", "Sessions": "Séances", + "LastUsed": "Dernière utilisation", "KeypairStatusUpdatedSuccessfully": "L'état de la paire de clés a changé.", "KeypairSuccessfullyDeleted": "KeyPair est supprimé avec succès.", "ActivateUser": "Activer l'utilisateur", diff --git a/resources/i18n/id.json b/resources/i18n/id.json index 048acd7ff9..d7e108e9e1 100644 --- a/resources/i18n/id.json +++ b/resources/i18n/id.json @@ -539,7 +539,6 @@ "Allocation": "Alokasi", "Information": "Informasi", "Created": "Dibuat", - "Lastused": "Terakhir digunakan", "ResourcePolicy": "Kebijakan Sumber Daya", "NumberOfQueries": "Jumlah Kueri", "ConcurrentSessions": "Sesi Serentak", @@ -611,10 +610,12 @@ "CreatedAt": "Dibuat Pada", "SignoutSuccessfullyFinished": "Keluar dengan aman selesai", "AccessKey": "Kunci Akses", + "SecretKey": "Kunci Rahasia", "StatusUpdatedSuccessfully": "Status pengguna telah berubah.", "Queries": "Pertanyaan", "ReqPer15Min": "Persyaratan per 15 menit", "Sessions": "Sesi", + "LastUsed": "Terakhir digunakan", "KeypairStatusUpdatedSuccessfully": "Status pasangan kunci telah berubah.", "KeypairSuccessfullyDeleted": "KeyPair berhasil dihapus.", "ActivateUser": "Aktifkan pengguna", diff --git a/resources/i18n/it.json b/resources/i18n/it.json index 84d23ffbe8..50af52d3e9 100644 --- a/resources/i18n/it.json +++ b/resources/i18n/it.json @@ -539,7 +539,6 @@ "Allocation": "Allocazione", "Information": "Informazione", "Created": "Creato", - "Lastused": "Ultimo uso", "ResourcePolicy": "Politica delle risorse", "NumberOfQueries": "Numero di query", "ConcurrentSessions": "Sessioni simultanee", @@ -611,10 +610,12 @@ "CreatedAt": "Creato a", "SignoutSuccessfullyFinished": "Il signout è terminato in modo sicuro", "AccessKey": "Chiave di accesso", + "SecretKey": "Chiave segreta", "StatusUpdatedSuccessfully": "Lo stato dell'utente è cambiato.", "Queries": "Domande", "ReqPer15Min": "Richiesto ogni 15 min", "Sessions": "Sessioni", + "LastUsed": "Ultimo uso", "KeypairStatusUpdatedSuccessfully": "Lo stato della coppia di chiavi è cambiato.", "KeypairSuccessfullyDeleted": "KeyPair è stato eliminato con successo.", "ActivateUser": "Attiva utente", diff --git a/resources/i18n/ja.json b/resources/i18n/ja.json index 7ae606870c..0bc7f69eaa 100644 --- a/resources/i18n/ja.json +++ b/resources/i18n/ja.json @@ -538,7 +538,6 @@ "Allocation": "割り当て", "Information": "情報", "Created": "作成した", - "Lastused": "最後に使用した", "ResourcePolicy": "リソースポリシー", "NumberOfQueries": "クエリの数", "ConcurrentSessions": "同時セッション", @@ -610,10 +609,12 @@ "CreatedAt": "作成日", "SignoutSuccessfullyFinished": "ユーザーアカウントが正常に削除されました。", "AccessKey": "アクセスキー", + "SecretKey": "秘密鍵", "StatusUpdatedSuccessfully": "ユーザーステータスが変更されました。", "Queries": "クエリ", "ReqPer15Min": "15分あたりの要求", "Sessions": "セッション", + "LastUsed": "最後に使用した", "KeypairStatusUpdatedSuccessfully": "キーペアのステータスが変更されました。", "KeypairSuccessfullyDeleted": "キーペアは正常に削除されました。", "ActivateUser": "ユーザーをアクティブ化する", diff --git a/resources/i18n/ko.json b/resources/i18n/ko.json index 60a03696a1..357d208b8f 100644 --- a/resources/i18n/ko.json +++ b/resources/i18n/ko.json @@ -653,7 +653,6 @@ "Allocation": "할당", "Information": "정보", "Created": "생성일", - "Lastused": "최종 사용일", "ResourcePolicy": "자원 정책", "NumberOfQueries": "쿼리 수", "ConcurrentSessions": "동시 세션수", @@ -725,10 +724,12 @@ "CreatedAt": "생성 날짜", "SignoutSuccessfullyFinished": "사용자 계정이 성공적으로 삭제되었습니다.", "AccessKey": "접근키", + "SecretKey": "비밀 키", "StatusUpdatedSuccessfully": "사용자 상태가 변경되었습니다.", "Queries": "쿼리", "ReqPer15Min": "15분당 요청 수", "Sessions": "세션", + "LastUsed": "최종 사용일", "KeypairStatusUpdatedSuccessfully": "키페어 상태가 변경되었습니다.", "KeypairSuccessfullyDeleted": "키페어가 정상적으로 삭제되었습니다.", "ActivateUser": "사용자 활성화", diff --git a/resources/i18n/mn.json b/resources/i18n/mn.json index 502673ccd1..607d579b93 100644 --- a/resources/i18n/mn.json +++ b/resources/i18n/mn.json @@ -540,7 +540,6 @@ "Allocation": "Хуваарилалт", "Information": "Мэдээлэл", "Created": "Үүсгэсэн", - "Lastused": "Сүүлд ашигласан", "ResourcePolicy": "Нөөцийн бодлого", "NumberOfQueries": "Query тоо", "ConcurrentSessions": "Зэрэгцээ Session-үүд", @@ -612,10 +611,12 @@ "CreatedAt": "Үүсгэсэн", "SignoutSuccessfullyFinished": "Гарах ажиллагаа амжилттай дууслаа", "AccessKey": "Хандалтын түлхүүр", + "SecretKey": "Нууц түлхүүр", "StatusUpdatedSuccessfully": "Хэрэглэгчийн статус өөрчлөгдсөн.", "Queries": "Асуултууд", "ReqPer15Min": "15 минут тутамд хэрэгцээ", "Sessions": "Хурал", + "LastUsed": "Сүүлд ашигласан", "KeypairStatusUpdatedSuccessfully": "Товчлуурын хослол өөрчлөгдсөн.", "KeypairSuccessfullyDeleted": "KeyPair амжилттай устгагдлаа.", "ActivateUser": "Хэрэглэгчийг идэвхжүүлэх", diff --git a/resources/i18n/ms.json b/resources/i18n/ms.json index fbf58506f8..e81e38dbca 100644 --- a/resources/i18n/ms.json +++ b/resources/i18n/ms.json @@ -538,7 +538,6 @@ "Allocation": "Peruntukan", "Information": "Maklumat", "Created": "Dicipta", - "Lastused": "Kali terakhir digunakan", "ResourcePolicy": "Dasar Sumber", "NumberOfQueries": "Bilangan Pertanyaan", "ConcurrentSessions": "Sesi Serentak", @@ -610,10 +609,12 @@ "CreatedAt": "Dicipta Pada", "SignoutSuccessfullyFinished": "Log keluar telah selesai dengan selamat", "AccessKey": "Kunci Akses", + "SecretKey": "Kunci Rahsia", "StatusUpdatedSuccessfully": "Status pengguna telah berubah.", "Queries": "Pertanyaan", "ReqPer15Min": "Req setiap 15 min", "Sessions": "Sesi", + "LastUsed": "Kali terakhir digunakan", "KeypairStatusUpdatedSuccessfully": "Status pasangan kekunci telah berubah.", "KeypairSuccessfullyDeleted": "KeyPair berjaya dipadamkan.", "ActivateUser": "Aktifkan pengguna", diff --git a/resources/i18n/pl.json b/resources/i18n/pl.json index 4ed2a82417..7d57095da5 100644 --- a/resources/i18n/pl.json +++ b/resources/i18n/pl.json @@ -538,7 +538,6 @@ "Allocation": "Przydział", "Information": "Informacja", "Created": "Utworzony", - "Lastused": "Ostatnio używane", "ResourcePolicy": "Polityka zasobów", "NumberOfQueries": "Liczba zapytań", "ConcurrentSessions": "Sesje równoległe", @@ -610,7 +609,9 @@ "CreatedAt": "Utworzono o godz", "SignoutSuccessfullyFinished": "Wylogowanie zostało pomyślnie zakończone", "AccessKey": "Klucz dostępu", + "SecretKey": "Tajny klucz", "StatusUpdatedSuccessfully": "Status użytkownika uległ zmianie.", + "LastUsed": "Ostatnio używane", "Queries": "Zapytania", "ReqPer15Min": "Zapotrzebowanie na 15 min", "Sessions": "Sesje", diff --git a/resources/i18n/pt-BR.json b/resources/i18n/pt-BR.json index a672937819..5bbeda483c 100644 --- a/resources/i18n/pt-BR.json +++ b/resources/i18n/pt-BR.json @@ -538,7 +538,6 @@ "Allocation": "Alocação", "Information": "Em formação", "Created": "Criada", - "Lastused": "Usado por último", "ResourcePolicy": "Política de Recursos", "NumberOfQueries": "Número de consultas", "ConcurrentSessions": "Sessões Simultâneas", @@ -610,10 +609,12 @@ "CreatedAt": "Criado em", "SignoutSuccessfullyFinished": "O registo foi concluído com êxito", "AccessKey": "Chave de acesso", + "SecretKey": "Chave secreta", "StatusUpdatedSuccessfully": "O estado do utilizador foi alterado.", "Queries": "Consultas", "ReqPer15Min": "Solicitação por 15 min", "Sessions": "Sessões", + "LastUsed": "Usado por último", "KeypairStatusUpdatedSuccessfully": "O status do par de chaves mudou.", "KeypairSuccessfullyDeleted": "KeyPair foi excluído com sucesso.", "ActivateUser": "Ativar usuário", diff --git a/resources/i18n/pt.json b/resources/i18n/pt.json index 34b0d7826d..12f91e61bc 100644 --- a/resources/i18n/pt.json +++ b/resources/i18n/pt.json @@ -538,7 +538,6 @@ "Allocation": "Alocação", "Information": "Em formação", "Created": "Criada", - "Lastused": "Usado por último", "ResourcePolicy": "Política de Recursos", "NumberOfQueries": "Número de consultas", "ConcurrentSessions": "Sessões Simultâneas", @@ -610,10 +609,12 @@ "CreatedAt": "Criado em", "SignoutSuccessfullyFinished": "O registo foi concluído com êxito", "AccessKey": "Chave de acesso", + "SecretKey": "Chave secreta", "StatusUpdatedSuccessfully": "O estado do utilizador foi alterado.", "Queries": "Consultas", "ReqPer15Min": "Solicitação por 15 min", "Sessions": "Sessões", + "LastUsed": "Usado por último", "KeypairStatusUpdatedSuccessfully": "O status do par de chaves mudou.", "KeypairSuccessfullyDeleted": "KeyPair foi excluído com sucesso.", "ActivateUser": "Ativar usuário", diff --git a/resources/i18n/ru.json b/resources/i18n/ru.json index 3c3547377d..50967d6075 100644 --- a/resources/i18n/ru.json +++ b/resources/i18n/ru.json @@ -538,7 +538,6 @@ "Allocation": "Распределение", "Information": "Информация", "Created": "Созданный", - "Lastused": "Последний раз был использован", "ResourcePolicy": "Политика ресурсов", "NumberOfQueries": "Количество запросов", "ConcurrentSessions": "Параллельные сеансы", @@ -610,10 +609,12 @@ "CreatedAt": "Создано в", "SignoutSuccessfullyFinished": "Выход из системы завершен", "AccessKey": "Ключ доступа", + "SecretKey": "Секретный ключ", "StatusUpdatedSuccessfully": "Статус пользователя изменился.", "Queries": "Запросы", "ReqPer15Min": "Запрос за 15 минут", "Sessions": "Сессии", + "LastUsed": "Последний раз был использован", "KeypairStatusUpdatedSuccessfully": "Статус пары ключей изменился.", "KeypairSuccessfullyDeleted": "KeyPair успешно удалена.", "ActivateUser": "Активировать пользователя", diff --git a/resources/i18n/th.json b/resources/i18n/th.json index fba3254707..e262202b7b 100644 --- a/resources/i18n/th.json +++ b/resources/i18n/th.json @@ -661,7 +661,6 @@ "Allocation": "การจัดสรร", "Information": "ข้อมูล", "Created": "สร้างเมื่อ", - "Lastused": "ใช้ครั้งล่าสุด", "ResourcePolicy": "นโยบายทรัพยากร", "NumberOfQueries": "จำนวนคำขอ", "ConcurrentSessions": "เซสชันพร้อมกัน", @@ -733,10 +732,12 @@ "CreatedAt": "สร้างเมื่อ", "SignoutSuccessfullyFinished": "ออกจากระบบสำเร็จแล้ว", "AccessKey": "คีย์การเข้าถึง", + "SecretKey": "รหัสลับ", "StatusUpdatedSuccessfully": "สถานะผู้ใช้มีการเปลี่ยนแปลง", "Queries": "แบบสอบถาม", "ReqPer15Min": "ต้องการต่อ 15 นาที", "Sessions": "เซสชัน", + "LastUsed": "ใช้ครั้งล่าสุด", "KeypairStatusUpdatedSuccessfully": "สถานะคู่กุญแจเปลี่ยนไป", "KeypairSuccessfullyDeleted": "ลบ KeyPair สำเร็จแล้ว", "ActivateUser": "เปิดใช้งานผู้ใช้", diff --git a/resources/i18n/tr.json b/resources/i18n/tr.json index 9e70726d15..9f7fb8d452 100644 --- a/resources/i18n/tr.json +++ b/resources/i18n/tr.json @@ -537,7 +537,6 @@ "Allocation": "Tahsis", "Information": "Bilgi", "Created": "oluşturuldu", - "Lastused": "Son kullanılan", "ResourcePolicy": "Kaynak Politikası", "NumberOfQueries": "Sorgu Sayısı", "ConcurrentSessions": "Birleşen oturumlar", @@ -609,7 +608,9 @@ "CreatedAt": "Oluşturulma Tarihi", "SignoutSuccessfullyFinished": "Çıkış işlemi başarıyla tamamlandı", "AccessKey": "Erişim Anahtarı", + "SecretKey": "Gizli Anahtar", "StatusUpdatedSuccessfully": "Kullanıcı durumu değişti.", + "LastUsed": "Son kullanılan", "Queries": "Sorgular", "ReqPer15Min": "15 dakika başına talep", "Sessions": "Oturumlar", diff --git a/resources/i18n/vi.json b/resources/i18n/vi.json index 186b8a3217..2982d8d978 100644 --- a/resources/i18n/vi.json +++ b/resources/i18n/vi.json @@ -538,7 +538,6 @@ "Allocation": "Phân bổ", "Information": "Thông tin", "Created": "Tạo", - "Lastused": "Lần sử dụng cuối cùng", "ResourcePolicy": "Chính sách tài nguyên", "NumberOfQueries": "Số lượng truy vấn", "ConcurrentSessions": "Phiên đồng thời", @@ -610,10 +609,12 @@ "CreatedAt": "Được tạo tại", "SignoutSuccessfullyFinished": "Đăng xuất đã hoàn tất thành công", "AccessKey": "Khóa truy cập", + "SecretKey": "Khóa bí mật", "StatusUpdatedSuccessfully": "Trạng thái người dùng đã thay đổi.", "Queries": "Truy vấn", "ReqPer15Min": "Yêu cầu mỗi 15 phút", "Sessions": "Phiên", + "LastUsed": "Lần sử dụng cuối cùng", "KeypairStatusUpdatedSuccessfully": "Trạng thái cặp khóa đã thay đổi.", "KeypairSuccessfullyDeleted": "KeyPair đã được xóa thành công.", "ActivateUser": "Kích hoạt người dùng", diff --git a/resources/i18n/zh-CN.json b/resources/i18n/zh-CN.json index 1581f3cbdf..6f1ab2c525 100644 --- a/resources/i18n/zh-CN.json +++ b/resources/i18n/zh-CN.json @@ -538,7 +538,6 @@ "Allocation": "分配", "Information": "信息", "Created": "已创建", - "Lastused": "最后使用", "ResourcePolicy": "资源政策", "NumberOfQueries": "查询数", "ConcurrentSessions": "并发会话", @@ -610,12 +609,14 @@ "CreatedAt": "创建于", "SignoutSuccessfullyFinished": "签出已顺利完成", "AccessKey": "访问密钥", + "SecretKey": "秘密钥匙", "StatusUpdatedSuccessfully": "用户状态已更改。", "Queries": "查询", "ReqPer15Min": "每 15 分钟请求数", "Sessions": "会议", "KeypairStatusUpdatedSuccessfully": "密钥对状态已更改。", "KeypairSuccessfullyDeleted": "密钥对已成功删除。", + "LastUsed": "最后使用", "ActivateUser": "激活用户", "DeactivateUser": "停用用户", "Deactivate": "停用", diff --git a/resources/i18n/zh-TW.json b/resources/i18n/zh-TW.json index 6dd9d45c21..2013ee18d9 100644 --- a/resources/i18n/zh-TW.json +++ b/resources/i18n/zh-TW.json @@ -538,7 +538,6 @@ "Allocation": "分配", "Information": "信息", "Created": "已創建", - "Lastused": "最後使用", "ResourcePolicy": "資源政策", "NumberOfQueries": "查詢數", "ConcurrentSessions": "並發會話", @@ -610,12 +609,14 @@ "CreatedAt": "創建於", "SignoutSuccessfullyFinished": "签出已顺利完成", "AccessKey": "存取密鑰", + "SecretKey": "秘密鑰匙", "StatusUpdatedSuccessfully": "用户状态已更改。", "Queries": "查詢", "ReqPer15Min": "每 15 分鐘請求數", "Sessions": "會議", "KeypairStatusUpdatedSuccessfully": "密鑰對狀態已變更。", "KeypairSuccessfullyDeleted": "密鑰對已成功刪除。", + "LastUsed": "最後使用", "ActivateUser": "啟用用戶", "DeactivateUser": "停用用戶", "Deactivate": "停用",