Skip to content

Commit 004bc3f

Browse files
committed
feat(FR-1568): migrate app launcher notifications from Lit to React
- Integrate React notification system with existing Lit app launcher - Add unified notification key system for state synchronization - Implement progress tracking with backgroundTask support - Update notification flow throughout app launch process - Maintain backward compatibility during migration phase - Add comprehensive error handling with user-friendly messages
1 parent 4c0bf66 commit 004bc3f

File tree

25 files changed

+234
-57
lines changed

25 files changed

+234
-57
lines changed

react/src/components/ComputeSessionNodeItems/AppLauncherModal.tsx

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,20 @@ import {
1818
Row,
1919
Typography,
2020
} from 'antd';
21-
import { BAIFlex, BAIModal, BAISelect, BAIText } from 'backend.ai-ui';
21+
import {
22+
BAIButton,
23+
BAIFlex,
24+
BAILink,
25+
BAIModal,
26+
BAISelect,
27+
BAIText,
28+
} from 'backend.ai-ui';
2229
import _ from 'lodash';
2330
import { useRef, useState } from 'react';
2431
import { Trans, useTranslation } from 'react-i18next';
2532
import { graphql, useFragment } from 'react-relay';
33+
import { useNavigate } from 'react-router-dom';
34+
import { useSetBAINotification } from 'src/hooks/useBAINotification';
2635

2736
interface AppLauncherModalProps extends ModalProps {
2837
onRequestClose: () => void;
@@ -43,6 +52,9 @@ const AppLauncherModal: React.FC<AppLauncherModalProps> = ({
4352
const [forceUseV2Proxy, setForceUseV2Proxy] = useState<boolean>(false);
4453
const [useSubDomain, setUseSubDomain] = useState<boolean>(false);
4554

55+
const { upsertNotification } = useSetBAINotification();
56+
const navigate = useNavigate();
57+
4658
const session = useFragment(
4759
graphql`
4860
fragment AppLauncherModalFragment on ComputeSessionNode {
@@ -92,9 +104,38 @@ const AppLauncherModal: React.FC<AppLauncherModalProps> = ({
92104
}
93105
});
94106

107+
// set notification for lit-element component
108+
upsertNotification({
109+
key: `session-app-${session?.row_id}`,
110+
message: (
111+
<span>
112+
{t('general.Session')}:&nbsp;
113+
<BAILink
114+
style={{
115+
fontWeight: 'normal',
116+
}}
117+
onClick={() => {
118+
const newSearchParams = new URLSearchParams(location.search);
119+
newSearchParams.set('sessionDetail', session?.row_id || '');
120+
navigate({
121+
pathname: `/session`,
122+
search: newSearchParams.toString(),
123+
});
124+
}}
125+
>
126+
{session?.name}
127+
</BAILink>
128+
</span>
129+
),
130+
description: t('session.appLauncher.LaunchingApp', {
131+
appName: app?.title || '',
132+
}),
133+
});
134+
95135
const appController = {
96136
'app-name': app?.name ?? '',
97137
'session-uuid': session?.row_id ?? '',
138+
'session-name': session?.name ?? '',
98139
'url-postfix': app?.redirect ?? '',
99140
};
100141

@@ -121,10 +162,7 @@ const AppLauncherModal: React.FC<AppLauncherModalProps> = ({
121162
return;
122163
}
123164
// @ts-ignore
124-
globalThis.appLauncher._runApp(appController).then(() => {});
125-
setOpenToPublic(false);
126-
setTryPreferredPort(false);
127-
onRequestClose();
165+
await globalThis.appLauncher._runApp(appController).then(() => {});
128166
};
129167

130168
return (
@@ -166,7 +204,7 @@ const AppLauncherModal: React.FC<AppLauncherModalProps> = ({
166204
gap={'xs'}
167205
style={{ height: '100%' }}
168206
>
169-
<Button
207+
<BAIButton
170208
icon={
171209
<Image
172210
src={app?.src}
@@ -175,8 +213,12 @@ const AppLauncherModal: React.FC<AppLauncherModalProps> = ({
175213
style={{ height: 36, width: 36 }}
176214
/>
177215
}
178-
onClick={() => {
179-
handleAppLaunch(app);
216+
action={async () => {
217+
await handleAppLaunch(app).then(() => {
218+
setOpenToPublic(false);
219+
setTryPreferredPort(false);
220+
onRequestClose();
221+
});
180222
}}
181223
style={{ height: 72, width: 72 }}
182224
/>

react/src/hooks/useBackendAIAppLauncher.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
import { useSetBAINotification } from './useBAINotification';
2+
import { BAILink } from 'backend.ai-ui';
3+
import { useTranslation } from 'react-i18next';
14
import { graphql, useFragment } from 'react-relay';
5+
import { useNavigate } from 'react-router-dom';
26
import { useBackendAIAppLauncherFragment$key } from 'src/__generated__/useBackendAIAppLauncherFragment.graphql';
37

48
export const useBackendAIAppLauncher = (
59
sessionFrgmt?: useBackendAIAppLauncherFragment$key | null,
610
) => {
11+
const { t } = useTranslation();
12+
const { upsertNotification } = useSetBAINotification();
13+
const navigate = useNavigate();
14+
715
// TODO: migrate backend-ai-app-launcher features to this hook using fragment data.
816
const session = useFragment(
917
graphql`
1018
fragment useBackendAIAppLauncherFragment on ComputeSessionNode {
19+
name
1120
row_id @required(action: NONE)
1221
vfolder_mounts
1322
}
@@ -17,7 +26,35 @@ export const useBackendAIAppLauncher = (
1726

1827
// @ts-ignore
1928
return {
29+
// TODO: AppLauncherModal should modify the hook to use, as it is currently separated,
30+
// to re-declare the notification for use by the backend-ai-app-launcher.
2031
runTerminal: () => {
32+
upsertNotification({
33+
key: `session-app-${session?.row_id}`,
34+
message: (
35+
<span>
36+
{t('general.Session')}:&nbsp;
37+
<BAILink
38+
style={{
39+
fontWeight: 'normal',
40+
}}
41+
onClick={() => {
42+
const newSearchParams = new URLSearchParams(location.search);
43+
newSearchParams.set('sessionDetail', session?.row_id || '');
44+
navigate({
45+
pathname: `/session`,
46+
search: newSearchParams.toString(),
47+
});
48+
}}
49+
>
50+
{session?.name}
51+
</BAILink>
52+
</span>
53+
),
54+
description: t('session.appLauncher.LaunchingApp', {
55+
appName: 'Console',
56+
}),
57+
});
2158
// @ts-ignore
2259
globalThis.appLauncher.runTerminal(session.row_id);
2360
},

resources/i18n/de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,7 @@
14171417
"ConfirmAndRun": "Ich habe nachgesehen und ich fange an",
14181418
"ConnectUrlIsNotValid": "Die Verbindungs-URL ist ungültig.",
14191419
"DownloadSSHKey": "SSH-Schlüssel herunterladen",
1420+
"LaunchingApp": "Die App {{appName}} wird gestartet.",
14201421
"NoExistingConnectionExample": "Keine Verbindung Zu kopierendes Beispiel.",
14211422
"OpenVSCodeRemote": "Lokalen Visual Studio Code öffnen",
14221423
"Prepared": "Bereit",

resources/i18n/el.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,7 @@
14161416
"ConfirmAndRun": "Έλεγξα και θα ξεκινήσω",
14171417
"ConnectUrlIsNotValid": "Η διεύθυνση URL σύνδεσης δεν είναι έγκυρη.",
14181418
"DownloadSSHKey": "Λήψη κλειδιού SSH",
1419+
"LaunchingApp": "Η εφαρμογή {{appName}} εκκινείται.",
14191420
"NoExistingConnectionExample": "Δεν υπάρχει σύνδεση Παράδειγμα προς αντιγραφή.",
14201421
"OpenVSCodeRemote": "Ανοίξτε τον τοπικό κώδικα του Visual Studio",
14211422
"Prepared": "Ετοιμος",

resources/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,7 @@
14251425
"ConfirmAndRun": "I checked and I'll start",
14261426
"ConnectUrlIsNotValid": "Connect URL is not valid.",
14271427
"DownloadSSHKey": "Download SSH Key",
1428+
"LaunchingApp": "Starting {{appName}} app.",
14281429
"NoExistingConnectionExample": "No Connection Example to be copied.",
14291430
"OpenVSCodeRemote": "Open local Visual Studio Code",
14301431
"Prepared": "Prepared",

resources/i18n/es.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@
14191419
"ConfirmAndRun": "Lo he comprobado y voy a empezar",
14201420
"ConnectUrlIsNotValid": "La URL de conexión no es válida.",
14211421
"DownloadSSHKey": "Descargar clave SSH",
1422+
"LaunchingApp": "{{appName}} se está iniciando.",
14221423
"NoExistingConnectionExample": "No hay conexión Ejemplo a copiar.",
14231424
"OpenVSCodeRemote": "Abrir código local de Visual Studio",
14241425
"Prepared": "Preparado",

resources/i18n/fi.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,7 @@
14181418
"ConfirmAndRun": "Tarkistin ja aloitan",
14191419
"ConnectUrlIsNotValid": "Yhteyden URL-osoite ei kelpaa.",
14201420
"DownloadSSHKey": "Lataa SSH-avain",
1421+
"LaunchingApp": "Käynnistetään {{appName}}-sovellusta.",
14211422
"NoExistingConnectionExample": "Ei yhteyttä Kopioitava esimerkki.",
14221423
"OpenVSCodeRemote": "Avaa paikallinen Visual Studio Code",
14231424
"Prepared": "Valmisteltu",

resources/i18n/fr.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,6 +1419,7 @@
14191419
"ConfirmAndRun": "j'ai vérifié et je vais commencer",
14201420
"ConnectUrlIsNotValid": "L'URL de connexion n'est pas valide.",
14211421
"DownloadSSHKey": "Télécharger la clé SSH",
1422+
"LaunchingApp": "Lancement de l'application {{appName}}.",
14221423
"NoExistingConnectionExample": "Aucun exemple de connexion à copier.",
14231424
"OpenVSCodeRemote": "Ouvrir le code local de Visual Studio",
14241425
"Prepared": "Préparé",

resources/i18n/id.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,7 @@
14171417
"ConfirmAndRun": "Saya sudah memeriksa dan saya akan mulai",
14181418
"ConnectUrlIsNotValid": "URL koneksi tidak valid.",
14191419
"DownloadSSHKey": "Unduh Kunci SSH",
1420+
"LaunchingApp": "Menjalankan aplikasi {{appName}}.",
14201421
"NoExistingConnectionExample": "Tidak Ada Koneksi Contoh untuk disalin.",
14211422
"OpenVSCodeRemote": "Buka kode Visual Studio lokal",
14221423
"Prepared": "Siap",

resources/i18n/it.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,7 @@
14161416
"ConfirmAndRun": "Ho controllato e comincio",
14171417
"ConnectUrlIsNotValid": "L'URL di connessione non è valido.",
14181418
"DownloadSSHKey": "Scarica la chiave SSH",
1419+
"LaunchingApp": "Avvio dell'app {{appName}} in corso.",
14191420
"NoExistingConnectionExample": "Nessun esempio di connessione da copiare.",
14201421
"OpenVSCodeRemote": "Aprire il codice locale di Visual Studio",
14211422
"Prepared": "Preparato",

0 commit comments

Comments
 (0)