diff --git a/react/src/components/SessionTemplateModal.tsx b/react/src/components/SessionTemplateModal.tsx index a192695fbe..78f47336f8 100644 --- a/react/src/components/SessionTemplateModal.tsx +++ b/react/src/components/SessionTemplateModal.tsx @@ -1,11 +1,53 @@ import BAIModal, { BAIModalProps } from './BAIModal'; +import { Table, Tabs } from 'antd'; import React from 'react'; +import { useTranslation } from 'react-i18next'; interface SessionTemplateModalProps extends BAIModalProps {} const SessionTemplateModal: React.FC = ({ ...modalProps }) => { - return ; + const { t } = useTranslation(); + return ( + + Template, + }, + { + key: 'history', + label: t('session.launcher.RecentHistory'), + children: ( + + ), + }, + ]} + /> + + ); }; export default SessionTemplateModal; diff --git a/react/src/hooks/backendai.tsx b/react/src/hooks/backendai.tsx index f6209ad038..1b3479c365 100644 --- a/react/src/hooks/backendai.tsx +++ b/react/src/hooks/backendai.tsx @@ -1,10 +1,16 @@ import { useSuspendedBackendaiClient, useUpdatableState } from '.'; -import { maskString, useBaiSignedRequestWithPromise } from '../helper'; +import { + generateRandomString, + maskString, + useBaiSignedRequestWithPromise, +} from '../helper'; import { useSuspenseTanQuery, useTanMutation, useTanQuery, } from './reactQueryAlias'; +import { SessionHistory, useBAISettingUserState } from './useBAISetting'; +import { useEventNotStable } from './useEventNotStable'; import _ from 'lodash'; import { useCallback, useEffect, useMemo, useState } from 'react'; @@ -304,3 +310,43 @@ export const useAllowedHostNames = () => { }); return allowedHosts?.allowed; }; + +export const useRecentSessionHistory = () => { + const [recentSessionHistory, setRecentSessionHistory] = + useBAISettingUserState('recentSessionHistory'); + + const push = useEventNotStable( + ({ + id, + params, + createdAt, + }: SelectivePartial) => { + const newHistory: SessionHistory = { + id: id ?? generateRandomString(8), + params, + createdAt: createdAt ?? new Date().toISOString(), + }; + // push new history to the top of recentSessionHistory and keep it up to 5 + const newRecentSessionHistory = [ + newHistory, + ...(recentSessionHistory || []), + ].slice(0, 5); + setRecentSessionHistory(newRecentSessionHistory); + }, + ); + const clear = useEventNotStable(() => setRecentSessionHistory([])); + const remove = useEventNotStable((id: string) => { + const newRecentSessionHistory = (recentSessionHistory || []).filter( + (item) => item.id !== id, + ); + setRecentSessionHistory(newRecentSessionHistory); + }); + return [ + recentSessionHistory, + { + push, + clear, + remove, + }, + ] as const; +}; diff --git a/react/src/hooks/useBAISetting.tsx b/react/src/hooks/useBAISetting.tsx index c95ef48b94..da49cd00f6 100644 --- a/react/src/hooks/useBAISetting.tsx +++ b/react/src/hooks/useBAISetting.tsx @@ -17,8 +17,15 @@ interface UserSettings { summary_items?: Array>; selected_language?: string; classic_session_launcher?: boolean; + recentSessionHistory?: Array; } +export type SessionHistory = { + id: string; + params: string; + createdAt: string; +}; + interface GeneralSettings { last_login?: number; login_attempt?: number; @@ -28,8 +35,9 @@ interface GeneralSettings { export const useBAISettingUserState = ( name: K, ): [UserSettings[K], (newValue: UserSettings[K]) => void] => { - return useAtom(SettingAtomFamily('user.' + name)); + return useAtom(SettingAtomFamily('user.' + name)); }; + export const useBAISettingGeneralState = ( name: K, ): [GeneralSettings[K], (newValue: GeneralSettings[K]) => void] => { diff --git a/react/src/pages/SessionLauncherPage.tsx b/react/src/pages/SessionLauncherPage.tsx index f6e1385be1..d403c66bab 100644 --- a/react/src/pages/SessionLauncherPage.tsx +++ b/react/src/pages/SessionLauncherPage.tsx @@ -31,6 +31,7 @@ import SessionOwnerSetterCard, { SessionOwnerSetterFormValues, } from '../components/SessionOwnerSetterCard'; import { SessionOwnerSetterPreviewCard } from '../components/SessionOwnerSetterCard'; +import SessionTemplateModal from '../components/SessionTemplateModal'; import SourceCodeViewer from '../components/SourceCodeViewer'; import VFolderTableFormItem, { VFolderTableFormValues, @@ -45,7 +46,10 @@ import { useUpdatableState, useWebUINavigate, } from '../hooks'; -import { useCurrentUserRole } from '../hooks/backendai'; +import { + useCurrentUserRole, + useRecentSessionHistory, +} from '../hooks/backendai'; import { useSetBAINotification } from '../hooks/useBAINotification'; import { useCurrentProjectValue } from '../hooks/useCurrentProject'; import { useThemeMode } from '../hooks/useThemeMode'; @@ -59,7 +63,7 @@ import { QuestionCircleOutlined, RightOutlined, } from '@ant-design/icons'; -import { useDebounceFn } from 'ahooks'; +import { useDebounceFn, useToggle } from 'ahooks'; import { Alert, App, @@ -230,7 +234,10 @@ const SessionLauncherPage = () => { const webuiNavigate = useWebUINavigate(); const currentProject = useCurrentProjectValue(); + const [isOpenTemplateModal, { toggle: toggleIsOpenTemplateModal }] = + useToggle(); const { upsertNotification } = useSetBAINotification(); + const [, { push: pushSessionHistory }] = useRecentSessionHistory(); const { run: syncFormToURLWithDebounce } = useDebounceFn( () => { @@ -540,6 +547,7 @@ const SessionLauncherPage = () => { }); await Promise.all(sessionPromises) .then(([firstSession]) => { + // pushSessionHistory() // console.log('##sessionPromises', firstSession); if ( values.num_of_sessions === 1 && @@ -649,21 +657,22 @@ const SessionLauncherPage = () => { align="stretch" style={{ flex: 1, maxWidth: 700 }} > - {/* - + + {t('session.launcher.StartNewSession')} - */} + {/* }> */} { @@ -1769,13 +1778,15 @@ const SessionLauncherPage = () => { )} - {/* { - setSelectedFolderName(undefined); + { + toggleIsOpenTemplateModal(); + }} + onOk={() => { + toggleIsOpenTemplateModal(); }} - /> */} + /> {currentStep === steps.length - 1 ? ( = { : T[P]; }; +type SelectivePartial = Partial> & Omit; + type NonNullableItem = NonNullable['items']>>[0]; type NonNullableNodeOnEdges = NonNullable< diff --git a/resources/i18n/de.json b/resources/i18n/de.json index af25679c49..47f1498007 100644 --- a/resources/i18n/de.json +++ b/resources/i18n/de.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Das Format der Anschlussnummer ist falsch.", "DuplicatedPort": "Es gibt doppelte Anschlüsse.", "FolderAliasOverlappingToAutoMount": "Es existiert ein Auto-Mount-Ordner mit demselben Namen.", - "InsufficientAllocationOfResourcesWarning": "Die zuweisbaren Ressourcen liegen unter der im ausgewählten Bild erforderlichen Mindestressource." + "InsufficientAllocationOfResourcesWarning": "Die zuweisbaren Ressourcen liegen unter der im ausgewählten Bild erforderlichen Mindestressource.", + "RecentHistory": "Jüngste Sitzungen" }, "Preparing": "Vorbereitung...", "PreparingSession": "Sitzung vorbereiten...", diff --git a/resources/i18n/el.json b/resources/i18n/el.json index cee1365ccc..9f77583d02 100644 --- a/resources/i18n/el.json +++ b/resources/i18n/el.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Η μορφή του αριθμού θύρας είναι λανθασμένη.", "DuplicatedPort": "Υπάρχουν διπλές θύρες.", "FolderAliasOverlappingToAutoMount": "Υπάρχει ένας φάκελος αυτόματης προσάρτησης με το ίδιο όνομα.", - "InsufficientAllocationOfResourcesWarning": "Οι κατανεμητέοι πόροι πέφτουν κάτω από τον ελάχιστο απαιτούμενο πόρο στην επιλεγμένη εικόνα." + "InsufficientAllocationOfResourcesWarning": "Οι κατανεμητέοι πόροι πέφτουν κάτω από τον ελάχιστο απαιτούμενο πόρο στην επιλεγμένη εικόνα.", + "RecentHistory": "Πρόσφατες συνεδρίες" }, "Preparing": "Προετοιμασία ...", "PreparingSession": "Προετοιμασία συνεδρίας ...", diff --git a/resources/i18n/en.json b/resources/i18n/en.json index 4a3cbc373c..3b970ac74e 100644 --- a/resources/i18n/en.json +++ b/resources/i18n/en.json @@ -293,7 +293,8 @@ "InvalidPortFormat": "The port number format is incorrect.", "DuplicatedPort": "There are duplicate ports.", "FolderAliasOverlappingToAutoMount": "An auto-mount folder with the same name exists.", - "InsufficientAllocationOfResourcesWarning": "Allocatable resources falls below the minimum resource required in the selected image." + "InsufficientAllocationOfResourcesWarning": "Allocatable resources falls below the minimum resource required in the selected image.", + "RecentHistory": "Recent Sessions" }, "Preparing": "Preparing...", "PreparingSession": "Preparing session...", diff --git a/resources/i18n/es.json b/resources/i18n/es.json index 489a07c790..a8c897ab7e 100644 --- a/resources/i18n/es.json +++ b/resources/i18n/es.json @@ -1300,7 +1300,8 @@ "InvalidPortFormat": "El formato del número de puerto es incorrecto.", "DuplicatedPort": "Hay puertos duplicados.", "FolderAliasOverlappingToAutoMount": "Existe una carpeta de montaje automático con el mismo nombre.", - "InsufficientAllocationOfResourcesWarning": "Los recursos asignables están por debajo del recurso mínimo requerido en la imagen seleccionada." + "InsufficientAllocationOfResourcesWarning": "Los recursos asignables están por debajo del recurso mínimo requerido en la imagen seleccionada.", + "RecentHistory": "Sesiones recientes" }, "ExpiresAfter": "Tiempo restante", "CPU": "CPU", diff --git a/resources/i18n/fi.json b/resources/i18n/fi.json index 8fff1da6dc..35ac5680e9 100644 --- a/resources/i18n/fi.json +++ b/resources/i18n/fi.json @@ -1297,7 +1297,8 @@ "InvalidPortFormat": "Porttinumeron muoto on virheellinen.", "DuplicatedPort": "Portteja on päällekkäin.", "FolderAliasOverlappingToAutoMount": "Samanniminen automaattinen kiinnityskansio on olemassa.", - "InsufficientAllocationOfResourcesWarning": "Allokoitavat resurssit jäävät alle valitussa kuvassa vaaditun vähimmäisresurssin." + "InsufficientAllocationOfResourcesWarning": "Allokoitavat resurssit jäävät alle valitussa kuvassa vaaditun vähimmäisresurssin.", + "RecentHistory": "Viimeisimmät istunnot" }, "ExpiresAfter": "Jäljellä oleva aika", "CPU": "CPU", diff --git a/resources/i18n/fr.json b/resources/i18n/fr.json index bef9c61277..78004cd545 100644 --- a/resources/i18n/fr.json +++ b/resources/i18n/fr.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Le format du numéro de port est incorrect.", "DuplicatedPort": "Il y a des ports en double.", "FolderAliasOverlappingToAutoMount": "Il existe un dossier de montage automatique portant le même nom.", - "InsufficientAllocationOfResourcesWarning": "Les ressources allouables sont inférieures à la ressource minimale requise dans l'image sélectionnée." + "InsufficientAllocationOfResourcesWarning": "Les ressources allouables sont inférieures à la ressource minimale requise dans l'image sélectionnée.", + "RecentHistory": "Sessions récentes" }, "Preparing": "En train de préparer...", "PreparingSession": "Séance de préparation...", diff --git a/resources/i18n/id.json b/resources/i18n/id.json index 2e7d25cb27..a2429349e6 100644 --- a/resources/i18n/id.json +++ b/resources/i18n/id.json @@ -280,7 +280,8 @@ "InvalidPortFormat": "Format nomor port salah.", "DuplicatedPort": "Terdapat port ganda.", "FolderAliasOverlappingToAutoMount": "Folder pemasangan otomatis dengan nama yang sama tersedia.", - "InsufficientAllocationOfResourcesWarning": "Sumber daya yang dapat dialokasikan berada di bawah sumber daya minimum yang diperlukan pada gambar yang dipilih." + "InsufficientAllocationOfResourcesWarning": "Sumber daya yang dapat dialokasikan berada di bawah sumber daya minimum yang diperlukan pada gambar yang dipilih.", + "RecentHistory": "Sesi Terbaru" }, "Preparing": "Mempersiapkan...", "PreparingSession": "Mempersiapkan sesi...", diff --git a/resources/i18n/it.json b/resources/i18n/it.json index c025df134f..5ee0f76d58 100644 --- a/resources/i18n/it.json +++ b/resources/i18n/it.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Il formato del numero di porta non è corretto.", "DuplicatedPort": "Ci sono porte duplicate.", "FolderAliasOverlappingToAutoMount": "Esiste una cartella di montaggio automatico con lo stesso nome.", - "InsufficientAllocationOfResourcesWarning": "Le risorse assegnabili sono inferiori alla risorsa minima richiesta nell'immagine selezionata." + "InsufficientAllocationOfResourcesWarning": "Le risorse assegnabili sono inferiori alla risorsa minima richiesta nell'immagine selezionata.", + "RecentHistory": "Sessioni recenti" }, "Preparing": "Preparazione...", "PreparingSession": "Preparazione della sessione...", diff --git a/resources/i18n/ja.json b/resources/i18n/ja.json index f5969d8639..8def7a88e5 100644 --- a/resources/i18n/ja.json +++ b/resources/i18n/ja.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "ポート番号の形式が正しくない。", "DuplicatedPort": "ポートが重複している。", "FolderAliasOverlappingToAutoMount": "同名の自動マウントフォルダが存在する。", - "InsufficientAllocationOfResourcesWarning": "割り当て可能なリソースが、選択したイメージに必要な最小リソースを下回ります。" + "InsufficientAllocationOfResourcesWarning": "割り当て可能なリソースが、選択したイメージに必要な最小リソースを下回ります。", + "RecentHistory": "最近のセッション" }, "Preparing": "準備...", "PreparingSession": "セッションの準備...", diff --git a/resources/i18n/ko.json b/resources/i18n/ko.json index 4da982ba19..b61d9d298d 100644 --- a/resources/i18n/ko.json +++ b/resources/i18n/ko.json @@ -280,7 +280,9 @@ "InvalidPortFormat": "포트 형식이 올바르지 않습니다.", "DuplicatedPort": "중복된 포트가 있습니다.", "FolderAliasOverlappingToAutoMount": "동일한 이름의 자동 마운트 폴더가 존재합니다.", - "InsufficientAllocationOfResourcesWarning": "할당 가능한 자원이 선택된 이미지에서 요구되는 최소 자원보다 부족합니다." + "InsufficientAllocationOfResourcesWarning": "할당 가능한 자원이 선택된 이미지에서 요구되는 최소 자원보다 부족합니다.", + "RecentHistory": "최근 세션", + "CreatedAt": "생성 시간" }, "Preparing": "준비중...", "PreparingSession": "세션 준비중...", diff --git a/resources/i18n/mn.json b/resources/i18n/mn.json index 5790e293ee..766e80a2ca 100644 --- a/resources/i18n/mn.json +++ b/resources/i18n/mn.json @@ -280,7 +280,8 @@ "InvalidPortFormat": "Портын дугаарын формат буруу байна.", "DuplicatedPort": "Давхардсан портууд байна.", "FolderAliasOverlappingToAutoMount": "Ижил нэртэй автоматаар холбох хавтас байна.", - "InsufficientAllocationOfResourcesWarning": "Хуваарилах нөөц нь сонгосон зурагт шаардагдах хамгийн бага нөөцөөс доогуур байна." + "InsufficientAllocationOfResourcesWarning": "Хуваарилах нөөц нь сонгосон зурагт шаардагдах хамгийн бага нөөцөөс доогуур байна.", + "RecentHistory": "Сүүлийн хуралдаанууд" }, "Preparing": "Бэлтгэж байна ...", "PreparingSession": "Session бэлтгэж байна ...", diff --git a/resources/i18n/ms.json b/resources/i18n/ms.json index 5f8ddfbaa9..f22750e64d 100644 --- a/resources/i18n/ms.json +++ b/resources/i18n/ms.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Format nombor port tidak betul.", "DuplicatedPort": "Terdapat port pendua.", "FolderAliasOverlappingToAutoMount": "Folder auto-lekap dengan nama yang sama wujud.", - "InsufficientAllocationOfResourcesWarning": "Sumber yang boleh diperuntukkan berada di bawah sumber minimum yang diperlukan dalam imej yang dipilih." + "InsufficientAllocationOfResourcesWarning": "Sumber yang boleh diperuntukkan berada di bawah sumber minimum yang diperlukan dalam imej yang dipilih.", + "RecentHistory": "Sesi Terkini" }, "Preparing": "Menyiapkan ...", "PreparingSession": "Menyiapkan sesi ...", diff --git a/resources/i18n/pl.json b/resources/i18n/pl.json index 21dd039ebc..d29fd21b53 100644 --- a/resources/i18n/pl.json +++ b/resources/i18n/pl.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Format numeru portu jest nieprawidłowy.", "DuplicatedPort": "Istnieją zduplikowane porty.", "FolderAliasOverlappingToAutoMount": "Istnieje folder automatycznego montażu o tej samej nazwie.", - "InsufficientAllocationOfResourcesWarning": "Zasoby, które można przydzielić, są mniejsze niż minimalne zasoby wymagane w wybranym obrazie." + "InsufficientAllocationOfResourcesWarning": "Zasoby, które można przydzielić, są mniejsze niż minimalne zasoby wymagane w wybranym obrazie.", + "RecentHistory": "Ostatnie sesje" }, "Preparing": "Przygotowuję...", "PreparingSession": "Przygotowuję sesję...", diff --git a/resources/i18n/pt-BR.json b/resources/i18n/pt-BR.json index 031e7955fa..899de01705 100644 --- a/resources/i18n/pt-BR.json +++ b/resources/i18n/pt-BR.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "O formato do número da porta está incorreto.", "DuplicatedPort": "Existem portas duplicadas.", "FolderAliasOverlappingToAutoMount": "Existe uma pasta de montagem automática com o mesmo nome.", - "InsufficientAllocationOfResourcesWarning": "Os recursos alocáveis ​​ficam abaixo do recurso mínimo exigido na imagem selecionada." + "InsufficientAllocationOfResourcesWarning": "Os recursos alocáveis ​​ficam abaixo do recurso mínimo exigido na imagem selecionada.", + "RecentHistory": "Sessões recentes" }, "Preparing": "Preparando...", "PreparingSession": "Preparando sessão ...", diff --git a/resources/i18n/pt.json b/resources/i18n/pt.json index b513e53701..c756103bf1 100644 --- a/resources/i18n/pt.json +++ b/resources/i18n/pt.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "O formato do número da porta está incorreto.", "DuplicatedPort": "Existem portas duplicadas.", "FolderAliasOverlappingToAutoMount": "Existe uma pasta de montagem automática com o mesmo nome.", - "InsufficientAllocationOfResourcesWarning": "Os recursos alocáveis ​​ficam abaixo do recurso mínimo exigido na imagem selecionada." + "InsufficientAllocationOfResourcesWarning": "Os recursos alocáveis ​​ficam abaixo do recurso mínimo exigido na imagem selecionada.", + "RecentHistory": "Sessões recentes" }, "Preparing": "Preparando...", "PreparingSession": "Preparando sessão ...", diff --git a/resources/i18n/ru.json b/resources/i18n/ru.json index b14055dae0..1306a18b3d 100644 --- a/resources/i18n/ru.json +++ b/resources/i18n/ru.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Неверный формат номера порта.", "DuplicatedPort": "Имеются дублирующиеся порты.", "FolderAliasOverlappingToAutoMount": "Существует папка автомонтирования с таким же именем.", - "InsufficientAllocationOfResourcesWarning": "Выделяемые ресурсы ниже минимального ресурса, необходимого для выбранного изображения." + "InsufficientAllocationOfResourcesWarning": "Выделяемые ресурсы ниже минимального ресурса, необходимого для выбранного изображения.", + "RecentHistory": "Последние сеансы" }, "Preparing": "Подготовка ...", "PreparingSession": "Подготовка сеанса ...", diff --git a/resources/i18n/th.json b/resources/i18n/th.json index 2943f970a9..7cc755b517 100644 --- a/resources/i18n/th.json +++ b/resources/i18n/th.json @@ -293,7 +293,8 @@ "InvalidPortFormat": "รูปแบบหมายเลขพอร์ตไม่ถูกต้อง", "DuplicatedPort": "มีพอร์ตที่ซ้ำกัน", "FolderAliasOverlappingToAutoMount": "มีโฟลเดอร์ที่เมาท์อัตโนมัติที่มีชื่อเดียวกันอยู่แล้ว", - "InsufficientAllocationOfResourcesWarning": "ทรัพยากรที่จัดสรรได้อยู่ต่ำกว่าทรัพยากรขั้นต่ำที่จำเป็นในรูปภาพที่เลือก" + "InsufficientAllocationOfResourcesWarning": "ทรัพยากรที่จัดสรรได้อยู่ต่ำกว่าทรัพยากรขั้นต่ำที่จำเป็นในรูปภาพที่เลือก", + "RecentHistory": "เซสชันล่าสุด" }, "Preparing": "กำลังเตรียมการ...", "PreparingSession": "กำลังเตรียมเซสชัน...", diff --git a/resources/i18n/tr.json b/resources/i18n/tr.json index 9e770decc0..c24eb24773 100644 --- a/resources/i18n/tr.json +++ b/resources/i18n/tr.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Bağlantı noktası numarası biçimi yanlış.", "DuplicatedPort": "Çift bağlantı noktaları var.", "FolderAliasOverlappingToAutoMount": "Aynı ada sahip bir otomatik montaj klasörü mevcut.", - "InsufficientAllocationOfResourcesWarning": "Tahsis edilebilir kaynaklar, seçilen görüntüde gereken minimum kaynağın altına düşüyor." + "InsufficientAllocationOfResourcesWarning": "Tahsis edilebilir kaynaklar, seçilen görüntüde gereken minimum kaynağın altına düşüyor.", + "RecentHistory": "Son Oturumlar" }, "Preparing": "hazırlanıyor...", "PreparingSession": "Oturum hazırlanıyor...", diff --git a/resources/i18n/vi.json b/resources/i18n/vi.json index 4fb2180544..7595c4ef8c 100644 --- a/resources/i18n/vi.json +++ b/resources/i18n/vi.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "Định dạng số cổng không chính xác.", "DuplicatedPort": "Có cổng trùng lặp.", "FolderAliasOverlappingToAutoMount": "Đã tồn tại một thư mục tự động gắn kết có cùng tên.", - "InsufficientAllocationOfResourcesWarning": "Tài nguyên có thể phân bổ giảm xuống dưới mức tài nguyên tối thiểu được yêu cầu trong hình ảnh đã chọn." + "InsufficientAllocationOfResourcesWarning": "Tài nguyên có thể phân bổ giảm xuống dưới mức tài nguyên tối thiểu được yêu cầu trong hình ảnh đã chọn.", + "RecentHistory": "Phiên gần đây" }, "Preparing": "Đang chuẩn bị ...", "PreparingSession": "Đang chuẩn bị phiên ...", diff --git a/resources/i18n/zh-CN.json b/resources/i18n/zh-CN.json index 702f3c63fc..5e445ab883 100644 --- a/resources/i18n/zh-CN.json +++ b/resources/i18n/zh-CN.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "端口号格式不正确。", "DuplicatedPort": "有重复的端口。", "FolderAliasOverlappingToAutoMount": "存在同名的自动挂载文件夹。", - "InsufficientAllocationOfResourcesWarning": "可分配资源低于所选映像所需的最低资源。" + "InsufficientAllocationOfResourcesWarning": "可分配资源低于所选映像所需的最低资源。", + "RecentHistory": "近期会议" }, "Preparing": "正在准备...", "PreparingSession": "正在准备会议...", diff --git a/resources/i18n/zh-TW.json b/resources/i18n/zh-TW.json index 192dc173b4..6b18a32345 100644 --- a/resources/i18n/zh-TW.json +++ b/resources/i18n/zh-TW.json @@ -279,7 +279,8 @@ "InvalidPortFormat": "端口号格式不正确。", "DuplicatedPort": "有重复的端口。", "FolderAliasOverlappingToAutoMount": "存在同名的自动挂载文件夹。", - "InsufficientAllocationOfResourcesWarning": "可分配資源低於所選映像所需的最低資源。" + "InsufficientAllocationOfResourcesWarning": "可分配資源低於所選映像所需的最低資源。", + "RecentHistory": "近期会议" }, "Preparing": "正在準備...", "PreparingSession": "正在準備會議...",