Skip to content

Commit

Permalink
Add launch server button
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Jan 18, 2024
1 parent 8debc9a commit 27cdb7f
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 19 deletions.
8 changes: 7 additions & 1 deletion frontend/src/servers/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useJupyterhub } from '../common/JupyterhubContext';
export interface IAppProps {
images: IEnvironmentData[];
server_data: IServerData[];
default_server_data: IServerData;
allow_named_servers: boolean;
named_server_limit_per_user: number;
}
Expand All @@ -34,8 +35,13 @@ export default function App(props: IAppProps) {
<NewServerDialog
images={props.images}
allowNamedServers={props.allow_named_servers}
serverLimit={props.named_server_limit_per_user}
defaultRunning={props.default_server_data.active}
/>
<ServerList
servers={props.server_data}
defaultServer={props.default_server_data}
/>
<ServerList servers={props.server_data} />
</Stack>
</ScopedCssBaseline>
</AxiosContext.Provider>
Expand Down
25 changes: 19 additions & 6 deletions frontend/src/servers/NewServerDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
OutlinedTextFieldProps
} from '@mui/material';
import { GridRowSelectionModel } from '@mui/x-data-grid';
import { Fragment, memo, useCallback, useState } from 'react';
import { Fragment, memo, useCallback, useMemo, useState } from 'react';

import { EnvironmentList } from '../environments/EnvironmentList';
import { IEnvironmentData } from '../environments/types';
Expand All @@ -21,6 +21,8 @@ import { useJupyterhub } from '../common/JupyterhubContext';
export interface INewServerDialogProps {
images: IEnvironmentData[];
allowNamedServers: boolean;
defaultRunning: boolean;
serverLimit: number;
}

const commonInputProps: OutlinedTextFieldProps = {
Expand Down Expand Up @@ -77,6 +79,18 @@ function _NewServerDialog(props: INewServerDialogProps) {
console.error(e);
}
}, [serverName, rowSelectionModel, props.images, axios, jhData]);
const disabled = useMemo(() => {
if (rowSelectionModel.length === 0) {
return true;
}
if (serverName.length === 0) {
if (props.defaultRunning) {
return true;
} else {
return false;
}
}
}, [rowSelectionModel, serverName, props.defaultRunning]);
return (
<Fragment>
<Box sx={{ display: 'flex', flexDirection: 'row-reverse' }}>
Expand All @@ -95,9 +109,11 @@ function _NewServerDialog(props: INewServerDialogProps) {
name="server_name"
label="Server name"
type="string"
required={true}
required={false}
helperText="If empty, a default server will be created"
onChange={e => setServerName(e.target.value)}
value={serverName}
disabled={!props.allowNamedServers}
/>
</Box>
)}
Expand All @@ -118,10 +134,7 @@ function _NewServerDialog(props: INewServerDialogProps) {
<Button
variant="contained"
color="primary"
disabled={
rowSelectionModel.length === 0 ||
(serverName.length === 0 && props.allowNamedServers)
}
disabled={disabled}
onClick={createServer}
>
Create Server
Expand Down
42 changes: 36 additions & 6 deletions frontend/src/servers/OpenServerButton.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import { Button, IconButton } from '@mui/material';
import { Fragment, memo, useEffect, useState } from 'react';
import { Fragment, memo, useCallback, useEffect, useState } from 'react';

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

interface IOpenServerButton {
url: string;
serverName: string;
imageName: string;
active: boolean;
}

function _OpenServerButton(props: IOpenServerButton) {
// const axios = useAxios();
const axios = useAxios();
const jhData = useJupyterhub();

const [progress, setProgress] = useState(0);
useEffect(() => {
const { user, baseUrl, xsrfToken } = jhData;
Expand Down Expand Up @@ -45,12 +49,38 @@ function _OpenServerButton(props: IOpenServerButton) {
};
}, [jhData, setProgress, props.serverName]);

const createServer = useCallback(async () => {
const imageName = props.imageName;
const data = new FormData();
data.append('image', imageName);
try {
await axios.request({
method: 'post',
prefix: SPAWN_PREFIX,
path: `${jhData.user}/${props.serverName}`,
data
});
window.open(props.url, '_blank')?.focus();
window.location.reload();
} catch (e: any) {
console.error(e);
}
}, [props, axios, jhData]);

return (
<Fragment>
{progress === 100 && (
<Button href={props.url} target="_blank">
Open Server
</Button>
<Fragment>
{props.active && (
<Button href={props.url} target="_blank">
Open Server
</Button>
)}

{!props.active && (
<Button onClick={createServer}>Launch server</Button>
)}
</Fragment>
)}
{progress < 100 && (
<IconButton title="Starting">
Expand Down
29 changes: 27 additions & 2 deletions frontend/src/servers/ServersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { IServerData } from './types';
import { formatTime } from '../common/utils';
import { RemoveServerButton } from './RemoveServerButton';
import { OpenServerButton } from './OpenServerButton';

import { IconButton } from '@mui/material';
import CheckIcon from '@mui/icons-material/Check';
import ClearIcon from '@mui/icons-material/Clear';
const columns: GridColDef[] = [
{
field: 'name',
Expand All @@ -23,6 +25,23 @@ const columns: GridColDef[] = [
headerName: 'Last activity',
width: 150
},
{
field: 'active',
headerName: 'Status',
width: 100,
hideSortIcons: true,
renderCell: params => {
return params.value ? (
<IconButton>
<CheckIcon color="success" />
</IconButton>
) : (
<IconButton>
<ClearIcon color="error" />
</IconButton>
);
}
},
{
field: 'status',
headerName: '',
Expand All @@ -43,14 +62,20 @@ const columns: GridColDef[] = [
hideable: false,
renderCell: params => {
return (
<OpenServerButton url={params.row.url} serverName={params.row.name} />
<OpenServerButton
url={params.row.url}
serverName={params.row.name}
imageName={params.row.image}
active={params.row.active}
/>
);
}
}
];

export interface IServerListProps {
servers: IServerData[];
defaultServer: IServerData;
}

function _ServerList(props: IServerListProps) {
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/servers/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ if (rootElement) {
let configData: IAppProps = {
images: [],
server_data: [],
default_server_data: {
name: '',
url: '',
last_activity: '',
user_options: {},
active: false
},
allow_named_servers: false,
named_server_limit_per_user: 0
};
Expand Down
1 change: 1 addition & 0 deletions frontend/src/servers/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export interface IServerData {
url: string;
last_activity: string;
user_options: { image?: string };
active: boolean;
}
1 change: 0 additions & 1 deletion tljh_repo2docker/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ async def post(self):
"Invalid build argument format"
)
extra_buildargs.append(barg)
print('@@@@@@@', repo, ref, name, memory, cpu, username, password, extra_buildargs)
await build_image(repo, ref, name, memory, cpu, username, password, extra_buildargs)

self.set_status(200)
Expand Down
14 changes: 12 additions & 2 deletions tljh_repo2docker/servers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ async def get(self):
server_data.append(
self._spawner_to_server_data(sp, user)
)
try:
named_server_limit = await self.get_current_user_named_server_limit()
except Exception:
named_server_limit = 0
result = self.render_template(
"servers.html",
images=images,
allow_named_servers=self.allow_named_servers,
named_server_limit_per_user=await self.get_current_user_named_server_limit(),
named_server_limit_per_user=named_server_limit,
server_data=server_data,
default_server_data=self._spawner_to_server_data(user.spawner, user),
auth_state=auth_state,
)

Expand All @@ -53,11 +58,16 @@ def _spawner_to_server_data(self, sp: Spawner, user: Any) -> Dict:
except Exception:
data["last_activity"] = ""

try:
data["active"] = sp.active
except Exception:
data["active"] = False

try:
if sp.user_options:
data["user_options"] = sp.user_options
else:
data["user_options"] = {}
except:
except Exception:
data["user_options"] = {}
return data
2 changes: 1 addition & 1 deletion tljh_repo2docker/templates/servers.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div id="servers-root">
<script id="tljh-page-data" type="application/json">
{
"images": {{ images | tojson }}, "allow_named_servers": {{allow_named_servers | tojson}}, "named_server_limit_per_user": {{named_server_limit_per_user}}, "server_data": {{ server_data| tojson }}
"images": {{ images | tojson }}, "allow_named_servers": {{allow_named_servers | tojson}}, "named_server_limit_per_user": {{named_server_limit_per_user}}, "server_data": {{ server_data| tojson }}, "default_server_data": {{ default_server_data| tojson }}
}
</script>
<script src="{{ base_url }}environments-static/js/react/servers.js"></script>
Expand Down

0 comments on commit 27cdb7f

Please sign in to comment.