Skip to content

Commit

Permalink
Add starting animation
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Jan 17, 2024
1 parent 4585624 commit 11b2ad1
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 62 deletions.
2 changes: 1 addition & 1 deletion frontend/src/common/ButtonWithConfirm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function _ButtonWithConfirm(props: IButtonWithConfirm) {
setLoading(true);
await props.action();
handleClose();
}, [props.action, setLoading]);
}, [props, setLoading]);

return (
<Fragment>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export function encodeUriComponents(uri: string): string {
}

export function formatTime(time: string): string {
if(!time || time.length === 0){
return 'unknown'
if (!time || time.length === 0) {
return 'unknown';
}
const units: { [key: string]: number } = {
year: 24 * 60 * 60 * 1000 * 365,
Expand All @@ -27,7 +27,7 @@ export function formatTime(time: string): string {
const d2 = new Date();
const elapsed = d1.getTime() - d2.getTime();
for (const u in units) {
if (Math.abs(elapsed) > units[u] || u == 'second') {
if (Math.abs(elapsed) > units[u] || u === 'second') {
return rtf.format(Math.round(elapsed / units[u]), u as any);
}
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/environments/EnvironmentList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,17 @@ function _EnvironmentList(props: IEnvironmentListProps) {
}
}}
pageSizeOptions={[props.pageSize ?? 100]}
disableRowSelectionOnClick={!Boolean(props.selectable)}
disableRowSelectionOnClick={!props.selectable}
sx={{
'& .MuiDataGrid-virtualScroller::-webkit-scrollbar': {
overflow: rows.length > 0 ? 'auto' : 'hidden'
}
}}
columnVisibilityModel={{ remove: !Boolean(props.hideRemoveButton) }}
columnVisibilityModel={{ remove: !props.hideRemoveButton }}
checkboxSelection={Boolean(props.selectable)}
rowSelectionModel={props.rowSelectionModel}
onRowSelectionModelChange={props.setRowSelectionModel}
density='compact'
density="compact"
autoHeight
slots={{
noRowsOverlay: () => {
Expand Down
19 changes: 10 additions & 9 deletions frontend/src/environments/LogDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import { Fragment, memo, useRef, useState } from 'react';
import { Fragment, memo, useCallback, useRef, useState } from 'react';
import urlJoin from 'url-join';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import { useJupyterhub } from '../common/JupyterhubContext';

interface IEnvironmentLogButton {
name: string;
Expand All @@ -25,24 +26,24 @@ const terminalFactory = () => {
};

function _EnvironmentLogButton(props: IEnvironmentLogButton) {
const jhData = useJupyterhub();
const [open, setOpen] = useState(false);
const [built, setBuilt] = useState(false);
const divRef = useRef<HTMLDivElement>(null);
const terminalRef = useRef<{ terminal: Terminal; fitAddon: FitAddon }>(
terminalFactory()
);
const handleOpen = () => {
const handleOpen = useCallback(() => {
setOpen(true);
if (divRef.current) {
const {terminal, fitAddon} = terminalFactory()
terminalRef.current.terminal = terminal
terminalRef.current.fitAddon = fitAddon
const { terminal, fitAddon } = terminalFactory();
terminalRef.current.terminal = terminal;
terminalRef.current.fitAddon = fitAddon;

terminal.open(divRef.current);
fitAddon.fit();
const jhData = (window as any).jhdata;
const baseUrl = jhData.base_url;
const xsrfToken = jhData.xsrf_token;
const { baseUrl, xsrfToken } = jhData;

let logsUrl = urlJoin(
baseUrl,
'api',
Expand Down Expand Up @@ -73,7 +74,7 @@ function _EnvironmentLogButton(props: IEnvironmentLogButton) {
fitAddon.fit();
};
}
};
}, [jhData, props.image]);
const handleClose = (
event?: any,
reason?: 'backdropClick' | 'escapeKeyDown'
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/environments/NewEnvironmentDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
DialogTitle,
Divider,
OutlinedTextFieldProps,
Typography,
Typography
} from '@mui/material';
import { Fragment, memo, useCallback, useMemo, useState } from 'react';

Expand Down
1 change: 1 addition & 0 deletions frontend/src/environments/RemoveEnvironmentButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function _RemoveEnvironmentButton(props: IRemoveEnvironmentButton) {
if (response?.status === 'ok') {
window.location.reload();
} else {
/* */
}
}, [props.image, axios]);

Expand Down
25 changes: 11 additions & 14 deletions frontend/src/environments/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { JupyterhubContext } from '../common/JupyterhubContext';
import App, { IAppProps } from './App';
Expand All @@ -23,17 +22,15 @@ const jhData = (window as any).jhdata;
const { base_url, xsrf_token, user, prefix, admin_access } = jhData;

root.render(
<StrictMode>
<JupyterhubContext.Provider
value={{
baseUrl: base_url,
xsrfToken: xsrf_token,
user,
prefix,
adminAccess: admin_access
}}
>
<App {...configData} />
</JupyterhubContext.Provider>
</StrictMode>
<JupyterhubContext.Provider
value={{
baseUrl: base_url,
xsrfToken: xsrf_token,
user,
prefix,
adminAccess: admin_access
}}
>
<App {...configData} />
</JupyterhubContext.Provider>
);
1 change: 0 additions & 1 deletion frontend/src/servers/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export default function App(props: IAppProps) {
const xsrfToken = jhData.xsrfToken;
return new AxiosClient({ baseUrl, xsrfToken });
}, [jhData]);
console.log('props', props);

return (
<ThemeProvider theme={customTheme}>
Expand Down
21 changes: 12 additions & 9 deletions frontend/src/servers/NewServerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,20 @@ function _NewServerDialog(props: INewServerDialogProps) {

const createServer = useCallback(async () => {
const imageName = props.images[rowSelectionModel[0] as number].image_name;
console.log('serverName', serverName, imageName);
const data = new FormData();
data.append('image', imageName);
const res = await axios.request({
method: 'post',
prefix: SPAWN_PREFIX,
path: `${jhData.user}/${serverName}`,
data
});
console.log('AAAAA', res)
}, [serverName, rowSelectionModel, props.images]);
try {
await axios.request({
method: 'post',
prefix: SPAWN_PREFIX,
path: `${jhData.user}/${serverName}`,
data
});
window.location.reload();
} catch (e: any) {
console.error(e);
}
}, [serverName, rowSelectionModel, props.images, axios, jhData]);
return (
<Fragment>
<Box sx={{ display: 'flex', flexDirection: 'row-reverse' }}>
Expand Down
77 changes: 77 additions & 0 deletions frontend/src/servers/OpenServerButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Button, IconButton } from '@mui/material';
import { Fragment, memo, useEffect, useState } from 'react';

// import { useAxios } from '../common/AxiosContext';
import { useJupyterhub } from '../common/JupyterhubContext';
import urlJoin from 'url-join';
import SyncIcon from '@mui/icons-material/Sync';

interface IOpenServerButton {
url: string;
serverName: string;
}

function _OpenServerButton(props: IOpenServerButton) {
// const axios = useAxios();
const jhData = useJupyterhub();
const [progress, setProgress] = useState(0);
useEffect(() => {
const { user, baseUrl, xsrfToken } = jhData;
let progressUrl = urlJoin(
baseUrl,
'api',
'users',
user,
'servers',
props.serverName,
'progress'
);
if (xsrfToken) {
// add xsrf token to url parameter
const sep = progressUrl.indexOf('?') === -1 ? '?' : '&';
progressUrl = progressUrl + sep + '_xsrf=' + xsrfToken;
}

const eventSource = new EventSource(progressUrl);
eventSource.onerror = err => {
setProgress(100);
eventSource.close();
};

eventSource.onmessage = event => {
const data = JSON.parse(event.data);

setProgress(data.progress ?? 0);
};
}, [jhData, setProgress]);

return (
<Fragment>
{progress === 100 && (
<Button href={props.url} target="_blank">
Open Server
</Button>
)}
{progress < 100 && (
<IconButton title="Starting">
<SyncIcon
sx={{
animation: 'spin 2s linear infinite',
'@keyframes spin': {
'0%': {
transform: 'rotate(360deg)'
},
'100%': {
transform: 'rotate(0deg)'
}
}
}}
htmlColor="orange"
/>
</IconButton>
)}
</Fragment>
);
}

export const OpenServerButton = memo(_OpenServerButton);
2 changes: 1 addition & 1 deletion frontend/src/servers/RemoveServerButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function _RemoveServerButton(props: IRemoveServerButton) {
} catch (e: any) {
console.error(e);
}
}, [props.server, axios]);
}, [props.server, axios, jhData]);

return (
<ButtonWithConfirm
Expand Down
10 changes: 4 additions & 6 deletions frontend/src/servers/ServersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Box } from '@mui/system';
import { IServerData } from './types';
import { formatTime } from '../common/utils';
import { RemoveServerButton } from './RemoveServerButton';
import { Button } from '@mui/material';
import { OpenServerButton } from './OpenServerButton';

const columns: GridColDef[] = [
{
Expand All @@ -31,7 +31,7 @@ const columns: GridColDef[] = [
sortable: false,
hideable: false,
renderCell: params => {
return <RemoveServerButton server={params.row.name}/>;
return <RemoveServerButton server={params.row.name} />;
}
},
{
Expand All @@ -43,9 +43,7 @@ const columns: GridColDef[] = [
hideable: false,
renderCell: params => {
return (
<Button href={params.row.url} target="_blank">
Open Server
</Button>
<OpenServerButton url={params.row.url} serverName={params.row.name} />
);
}
}
Expand Down Expand Up @@ -79,7 +77,7 @@ function _ServerList(props: IServerListProps) {
}}
pageSizeOptions={[100]}
disableRowSelectionOnClick
density='compact'
density="compact"
autoHeight
slots={{
noRowsOverlay: () => {
Expand Down
25 changes: 11 additions & 14 deletions frontend/src/servers/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

import { JupyterhubContext } from '../common/JupyterhubContext';
Expand All @@ -25,17 +24,15 @@ if (dataElement) {
const jhData = (window as any).jhdata;
const { base_url, xsrf_token, user, prefix, admin_access } = jhData;
root.render(
<StrictMode>
<JupyterhubContext.Provider
value={{
baseUrl: base_url,
xsrfToken: xsrf_token,
user,
prefix,
adminAccess: admin_access
}}
>
<App {...configData} />
</JupyterhubContext.Provider>
</StrictMode>
<JupyterhubContext.Provider
value={{
baseUrl: base_url,
xsrfToken: xsrf_token,
user,
prefix,
adminAccess: admin_access
}}
>
<App {...configData} />
</JupyterhubContext.Provider>
);

0 comments on commit 11b2ad1

Please sign in to comment.