Skip to content

Commit 6e4a42d

Browse files
rootroot
authored andcommitted
feat(ws): Notebooks 2.0 // Frontend // Workspaces table // Workspace redirect status column #147
Signed-off-by: root <root@C-PF3RRRR6.>
1 parent 055150b commit 6e4a42d

File tree

3 files changed

+131
-15
lines changed

3 files changed

+131
-15
lines changed

workspaces/frontend/src/app/actions/WorkspaceKindsActions.tsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,35 @@ export function buildKindLogoDictionary(workspaceKinds: WorkspaceKind[] | []): K
1919
}
2020
return kindLogoDict;
2121
}
22+
23+
type WorkspaceRedirectStatus = Record<
24+
string,
25+
{ to: string; message: string; level: string } | null
26+
>;
27+
28+
29+
/**
30+
* Builds a dictionary of workspace kinds to redirect statuses.
31+
* @param {WorkspaceKind[]} workspaceKinds - The list of workspace kinds.
32+
* @returns {WorkspaceRedirectStatus} A dictionary with kind names as keys and redirect status objects as values.
33+
*/
34+
export function buildWorkspaceRedirectStatus(
35+
workspaceKinds: WorkspaceKind[] | []
36+
): WorkspaceRedirectStatus {
37+
const workspaceRedirectStatus: WorkspaceRedirectStatus = {};
38+
for (const workspaceKind of workspaceKinds) {
39+
// Loop through the `values` array inside `imageConfig`
40+
const redirect = workspaceKind.podTemplate?.options?.imageConfig?.values?.find(
41+
(value) => value.redirect
42+
)?.redirect;
43+
// If redirect exists, extract the necessary properties
44+
workspaceRedirectStatus[workspaceKind.name] = redirect
45+
? {
46+
to: redirect.to,
47+
message: redirect.message.text,
48+
level: redirect.message.level,
49+
}
50+
: null;
51+
}
52+
return workspaceRedirectStatus;
53+
}

workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx

Lines changed: 94 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,22 @@ import {
2525
ActionsColumn,
2626
IActions,
2727
} from '@patternfly/react-table';
28+
import {
29+
InfoCircleIcon,
30+
ExclamationTriangleIcon,
31+
TimesCircleIcon,
32+
QuestionCircleIcon,
33+
CodeIcon,
34+
} from '@patternfly/react-icons';
2835
import { useState } from 'react';
29-
import { CodeIcon } from '@patternfly/react-icons';
3036
import { Workspace, WorkspacesColumnNames, WorkspaceState } from '~/shared/types';
3137
import { WorkspaceDetails } from '~/app/pages/Workspaces/Details/WorkspaceDetails';
3238
import { ExpandedWorkspaceRow } from '~/app/pages/Workspaces/ExpandedWorkspaceRow';
3339
import DeleteModal from '~/shared/components/DeleteModal';
34-
import { buildKindLogoDictionary } from '~/app/actions/WorkspaceKindsActions';
40+
import {
41+
buildKindLogoDictionary,
42+
buildWorkspaceRedirectStatus,
43+
} from '~/app/actions/WorkspaceKindsActions';
3544
import useWorkspaceKinds from '~/app/hooks/useWorkspaceKinds';
3645
import Filter, { FilteredColumn } from 'shared/components/Filter';
3746
import { formatRam } from 'shared/utilities/WorkspaceResources';
@@ -88,6 +97,10 @@ export const Workspaces: React.FunctionComponent = () => {
8897
state: WorkspaceState.Paused,
8998
stateMessage: 'It is paused.',
9099
},
100+
redirectStatus: {
101+
level: 'Info',
102+
text: 'This is informational', // Tooltip text
103+
},
91104
},
92105
{
93106
name: 'My Other Jupyter Notebook',
@@ -133,15 +146,30 @@ export const Workspaces: React.FunctionComponent = () => {
133146
state: WorkspaceState.Running,
134147
stateMessage: 'It is running.',
135148
},
149+
redirectStatus: {
150+
level: 'Danger',
151+
text: 'This is dangerous',
152+
},
136153
},
137154
];
138155

139156
const [workspaceKinds] = useWorkspaceKinds();
140157
let kindLogoDict: Record<string, string> = {};
141158
kindLogoDict = buildKindLogoDictionary(workspaceKinds);
142159

160+
let workspaceRedirectStatus: Record<
161+
string,
162+
{ to: string; message: string; level: string } | null
163+
> = {}; // Initialize the redirect status dictionary
164+
workspaceRedirectStatus = buildWorkspaceRedirectStatus(workspaceKinds); // Populate the dictionary
165+
166+
console.log('Work Space Kinds:', workspaceKinds);
167+
console.log('Kind Logo Dictionary:', kindLogoDict);
168+
console.log('Workspace Redirect Status:', workspaceRedirectStatus);
169+
143170
// Table columns
144171
const columnNames: WorkspacesColumnNames = {
172+
redirectStatus: 'Redirect Status',
145173
name: 'Name',
146174
kind: 'Kind',
147175
image: 'Image',
@@ -234,18 +262,20 @@ export const Workspaces: React.FunctionComponent = () => {
234262
const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc' | null>(null);
235263

236264
const getSortableRowValues = (workspace: Workspace): (string | number)[] => {
237-
const { name, kind, image, podConfig, state, homeVol, cpu, ram, lastActivity } = {
238-
name: workspace.name,
239-
kind: workspace.kind,
240-
image: workspace.options.imageConfig,
241-
podConfig: workspace.options.podConfig,
242-
state: WorkspaceState[workspace.status.state],
243-
homeVol: workspace.podTemplate.volumes.home,
244-
cpu: workspace.cpu,
245-
ram: workspace.ram,
246-
lastActivity: workspace.status.activity.lastActivity,
247-
};
248-
return [name, kind, image, podConfig, state, homeVol, cpu, ram, lastActivity];
265+
const { redirectStatus, name, kind, image, podConfig, state, homeVol, cpu, ram, lastActivity } =
266+
{
267+
redirectStatus: '',
268+
name: workspace.name,
269+
kind: workspace.kind,
270+
image: workspace.options.imageConfig,
271+
podConfig: workspace.options.podConfig,
272+
state: WorkspaceState[workspace.status.state],
273+
homeVol: workspace.podTemplate.volumes.home,
274+
cpu: workspace.cpu,
275+
ram: workspace.ram,
276+
lastActivity: workspace.status.activity.lastActivity,
277+
};
278+
return [redirectStatus, name, kind, image, podConfig, state, homeVol, cpu, ram, lastActivity];
249279
};
250280

251281
let sortedWorkspaces = workspaces;
@@ -349,6 +379,43 @@ export const Workspaces: React.FunctionComponent = () => {
349379
| 'yellow'
350380
)[] = ['green', 'orange', 'yellow', 'blue', 'red', 'purple'];
351381

382+
// Redirect Status Icons
383+
384+
const getRedirectStatusIcon = (level: string | undefined, message: string) => {
385+
switch (level) {
386+
case 'Info':
387+
return (
388+
<Tooltip content={message}>
389+
<InfoCircleIcon color="blue" aria-hidden="true" />
390+
</Tooltip>
391+
);
392+
case 'Warning':
393+
return (
394+
<Tooltip content={message}>
395+
<ExclamationTriangleIcon color="orange" aria-hidden="true" />
396+
</Tooltip>
397+
);
398+
case 'Danger':
399+
return (
400+
<Tooltip content={message}>
401+
<TimesCircleIcon color="red" aria-hidden="true" />
402+
</Tooltip>
403+
);
404+
case undefined:
405+
return (
406+
<Tooltip content={message}>
407+
<QuestionCircleIcon color="gray" aria-hidden="true" />
408+
</Tooltip>
409+
);
410+
default:
411+
return (
412+
<Tooltip content={`Invalid level: ${level}`}>
413+
<QuestionCircleIcon color="gray" aria-hidden="true" />
414+
</Tooltip>
415+
);
416+
}
417+
};
418+
352419
// Pagination
353420

354421
const [page, setPage] = React.useState(1);
@@ -404,7 +471,10 @@ export const Workspaces: React.FunctionComponent = () => {
404471
<Tr>
405472
<Th />
406473
{Object.values(columnNames).map((columnName, index) => (
407-
<Th key={`${columnName}-col-name`} sort={getSortParams(index)}>
474+
<Th
475+
key={`${columnName}-col-name`}
476+
sort={columnName !== 'Redirect Status' ? getSortParams(index) : undefined}
477+
>
408478
{columnName}
409479
</Th>
410480
))}
@@ -427,6 +497,15 @@ export const Workspaces: React.FunctionComponent = () => {
427497
setWorkspaceExpanded(workspace, !isWorkspaceExpanded(workspace)),
428498
}}
429499
/>
500+
<Td dataLabel={columnNames.redirectStatus}>
501+
{workspaceRedirectStatus[workspace.kind]
502+
? getRedirectStatusIcon(
503+
workspaceRedirectStatus[workspace.kind]?.level,
504+
workspaceRedirectStatus[workspace.kind]?.message ||
505+
'No API response available',
506+
)
507+
: getRedirectStatusIcon(undefined, 'No API response available')}
508+
</Td>
430509
<Td dataLabel={columnNames.name}>{workspace.name}</Td>
431510
<Td dataLabel={columnNames.kind}>
432511
{kindLogoDict[workspace.kind] ? (

workspaces/frontend/src/shared/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export interface Workspace {
122122
podConfig: string;
123123
};
124124
status: WorkspaceStatus;
125+
redirectStatus: {
126+
level: "Info" | "Warning" | "Danger";
127+
text: string;
128+
};
125129
}
126130

127131
export type WorkspacesColumnNames = {
@@ -134,4 +138,5 @@ export type WorkspacesColumnNames = {
134138
cpu: string;
135139
ram: string;
136140
lastActivity: string;
141+
redirectStatus: string;
137142
};

0 commit comments

Comments
 (0)