feat(ws): added images tab to workspace kind details (#398)
* feat(ws): added images tab to workspace kind details Signed-off-by: paulovmr <832830+paulovmr@users.noreply.github.com> * feat(ws): added images tab to workspace kind details Signed-off-by: paulovmr <832830+paulovmr@users.noreply.github.com> * feat(ws): added images tab to workspace kind details Signed-off-by: paulovmr <832830+paulovmr@users.noreply.github.com> --------- Signed-off-by: paulovmr <832830+paulovmr@users.noreply.github.com>
This commit is contained in:
parent
d668eb83c7
commit
83caeff57c
|
@ -1,8 +1,12 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { useNotebookAPI } from '~/app/hooks/useNotebookAPI';
|
import { useNotebookAPI } from '~/app/hooks/useNotebookAPI';
|
||||||
import { Workspace, WorkspaceKind } from '~/shared/api/backendApiTypes';
|
import { Workspace, WorkspaceKind } from '~/shared/api/backendApiTypes';
|
||||||
|
import { WorkspaceCountPerKindImagePodConfig } from '~/app/types';
|
||||||
|
|
||||||
type WorkspaceCountPerKind = Record<WorkspaceKind['name'], number>;
|
export type WorkspaceCountPerKind = Record<
|
||||||
|
WorkspaceKind['name'],
|
||||||
|
WorkspaceCountPerKindImagePodConfig
|
||||||
|
>;
|
||||||
|
|
||||||
export const useWorkspaceCountPerKind = (): WorkspaceCountPerKind => {
|
export const useWorkspaceCountPerKind = (): WorkspaceCountPerKind => {
|
||||||
const { api } = useNotebookAPI();
|
const { api } = useNotebookAPI();
|
||||||
|
@ -14,7 +18,25 @@ export const useWorkspaceCountPerKind = (): WorkspaceCountPerKind => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
api.listAllWorkspaces({}).then((workspaces) => {
|
api.listAllWorkspaces({}).then((workspaces) => {
|
||||||
const countPerKind = workspaces.reduce((acc: WorkspaceCountPerKind, workspace: Workspace) => {
|
const countPerKind = workspaces.reduce((acc: WorkspaceCountPerKind, workspace: Workspace) => {
|
||||||
acc[workspace.workspaceKind.name] = (acc[workspace.workspaceKind.name] || 0) + 1;
|
acc[workspace.workspaceKind.name] = acc[workspace.workspaceKind.name] ?? {
|
||||||
|
count: 0,
|
||||||
|
countByImage: {},
|
||||||
|
countByPodConfig: {},
|
||||||
|
};
|
||||||
|
acc[workspace.workspaceKind.name].count =
|
||||||
|
(acc[workspace.workspaceKind.name].count || 0) + 1;
|
||||||
|
acc[workspace.workspaceKind.name].countByImage[
|
||||||
|
workspace.podTemplate.options.imageConfig.current.id
|
||||||
|
] =
|
||||||
|
(acc[workspace.workspaceKind.name].countByImage[
|
||||||
|
workspace.podTemplate.options.imageConfig.current.id
|
||||||
|
] || 0) + 1;
|
||||||
|
acc[workspace.workspaceKind.name].countByPodConfig[
|
||||||
|
workspace.podTemplate.options.podConfig.current.id
|
||||||
|
] =
|
||||||
|
(acc[workspace.workspaceKind.name].countByPodConfig[
|
||||||
|
workspace.podTemplate.options.podConfig.current.id
|
||||||
|
] || 0) + 1;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
setWorkspaceCountPerKind(countPerKind);
|
setWorkspaceCountPerKind(countPerKind);
|
||||||
|
|
|
@ -87,7 +87,8 @@ export const WorkspaceKinds: React.FunctionComponent = () => {
|
||||||
name: workspaceKind.name,
|
name: workspaceKind.name,
|
||||||
description: workspaceKind.description,
|
description: workspaceKind.description,
|
||||||
deprecated: workspaceKind.deprecated,
|
deprecated: workspaceKind.deprecated,
|
||||||
numOfWorkspaces: workspaceCountPerKind[workspaceKind.name] ?? 0,
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
numOfWorkspaces: workspaceCountPerKind[workspaceKind.name]?.count ?? 0,
|
||||||
};
|
};
|
||||||
return [icon, name, description, deprecated, numberOfWorkspaces];
|
return [icon, name, description, deprecated, numberOfWorkspaces];
|
||||||
},
|
},
|
||||||
|
@ -433,6 +434,7 @@ export const WorkspaceKinds: React.FunctionComponent = () => {
|
||||||
{selectedWorkspaceKind && (
|
{selectedWorkspaceKind && (
|
||||||
<WorkspaceKindDetails
|
<WorkspaceKindDetails
|
||||||
workspaceKind={selectedWorkspaceKind}
|
workspaceKind={selectedWorkspaceKind}
|
||||||
|
workspaceCountPerKind={workspaceCountPerKind}
|
||||||
onCloseClick={() => setSelectedWorkspaceKind(null)}
|
onCloseClick={() => setSelectedWorkspaceKind(null)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -580,7 +582,10 @@ export const WorkspaceKinds: React.FunctionComponent = () => {
|
||||||
)}
|
)}
|
||||||
</Td>
|
</Td>
|
||||||
<Td dataLabel={columns.numberOfWorkspaces.name}>
|
<Td dataLabel={columns.numberOfWorkspaces.name}>
|
||||||
{workspaceCountPerKind[workspaceKind.name] ?? 0}
|
{
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
workspaceCountPerKind[workspaceKind.name]?.count ?? 0
|
||||||
|
}
|
||||||
</Td>
|
</Td>
|
||||||
|
|
||||||
<Td isActionCell data-testid="action-column">
|
<Td isActionCell data-testid="action-column">
|
||||||
|
|
|
@ -13,15 +13,19 @@ import {
|
||||||
TabContent,
|
TabContent,
|
||||||
} from '@patternfly/react-core';
|
} from '@patternfly/react-core';
|
||||||
import { WorkspaceKind } from '~/shared/api/backendApiTypes';
|
import { WorkspaceKind } from '~/shared/api/backendApiTypes';
|
||||||
import { WorkspaceDetailsOverview } from './WorkspaceDetailsOverview';
|
import { WorkspaceCountPerKind } from '~/app/hooks/useWorkspaceCountPerKind';
|
||||||
|
import { WorkspaceKindDetailsOverview } from './WorkspaceKindDetailsOverview';
|
||||||
|
import { WorkspaceKindDetailsImages } from './WorkspaceKindDetailsImages';
|
||||||
|
|
||||||
type WorkspaceKindDetailsProps = {
|
type WorkspaceKindDetailsProps = {
|
||||||
workspaceKind: WorkspaceKind;
|
workspaceKind: WorkspaceKind;
|
||||||
|
workspaceCountPerKind: WorkspaceCountPerKind;
|
||||||
onCloseClick: React.MouseEventHandler;
|
onCloseClick: React.MouseEventHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WorkspaceKindDetails: React.FunctionComponent<WorkspaceKindDetailsProps> = ({
|
export const WorkspaceKindDetails: React.FunctionComponent<WorkspaceKindDetailsProps> = ({
|
||||||
workspaceKind,
|
workspaceKind,
|
||||||
|
workspaceCountPerKind,
|
||||||
onCloseClick,
|
onCloseClick,
|
||||||
}) => {
|
}) => {
|
||||||
const [activeTabKey, setActiveTabKey] = React.useState<string | number>(0);
|
const [activeTabKey, setActiveTabKey] = React.useState<string | number>(0);
|
||||||
|
@ -50,6 +54,12 @@ export const WorkspaceKindDetails: React.FunctionComponent<WorkspaceKindDetailsP
|
||||||
tabContentId="overviewTabContent"
|
tabContentId="overviewTabContent"
|
||||||
aria-label="Overview"
|
aria-label="Overview"
|
||||||
/>
|
/>
|
||||||
|
<Tab
|
||||||
|
eventKey={1}
|
||||||
|
title={<TabTitleText>Images</TabTitleText>}
|
||||||
|
tabContentId="imagesTabContent"
|
||||||
|
aria-label="Images"
|
||||||
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</DrawerPanelBody>
|
</DrawerPanelBody>
|
||||||
|
|
||||||
|
@ -62,7 +72,21 @@ export const WorkspaceKindDetails: React.FunctionComponent<WorkspaceKindDetailsP
|
||||||
hidden={activeTabKey !== 0}
|
hidden={activeTabKey !== 0}
|
||||||
>
|
>
|
||||||
<TabContentBody hasPadding>
|
<TabContentBody hasPadding>
|
||||||
<WorkspaceDetailsOverview workspaceKind={workspaceKind} />
|
<WorkspaceKindDetailsOverview workspaceKind={workspaceKind} />
|
||||||
|
</TabContentBody>
|
||||||
|
</TabContent>
|
||||||
|
<TabContent
|
||||||
|
key={1}
|
||||||
|
eventKey={1}
|
||||||
|
id="imagesTabContent"
|
||||||
|
activeKey={activeTabKey}
|
||||||
|
hidden={activeTabKey !== 1}
|
||||||
|
>
|
||||||
|
<TabContentBody hasPadding>
|
||||||
|
<WorkspaceKindDetailsImages
|
||||||
|
workspaceKind={workspaceKind}
|
||||||
|
workspaceCountPerKind={workspaceCountPerKind}
|
||||||
|
/>
|
||||||
</TabContentBody>
|
</TabContentBody>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
</DrawerPanelBody>
|
</DrawerPanelBody>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { List, ListItem } from '@patternfly/react-core';
|
||||||
|
import { WorkspaceKind } from '~/shared/api/backendApiTypes';
|
||||||
|
import { WorkspaceCountPerKind } from '~/app/hooks/useWorkspaceCountPerKind';
|
||||||
|
|
||||||
|
type WorkspaceDetailsImagesProps = {
|
||||||
|
workspaceKind: WorkspaceKind;
|
||||||
|
workspaceCountPerKind: WorkspaceCountPerKind;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WorkspaceKindDetailsImages: React.FunctionComponent<WorkspaceDetailsImagesProps> = ({
|
||||||
|
workspaceKind,
|
||||||
|
workspaceCountPerKind,
|
||||||
|
}) => (
|
||||||
|
<List isPlain>
|
||||||
|
{workspaceKind.podTemplate.options.imageConfig.values.map((image, rowIndex) => (
|
||||||
|
<ListItem key={rowIndex}>
|
||||||
|
{image.displayName}:{' '}
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
|
workspaceCountPerKind[workspaceKind.name]
|
||||||
|
? workspaceCountPerKind[workspaceKind.name].countByImage[image.id]
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
{' Workspaces'}
|
||||||
|
</ListItem>
|
||||||
|
))}
|
||||||
|
</List>
|
||||||
|
);
|
|
@ -13,9 +13,9 @@ type WorkspaceDetailsOverviewProps = {
|
||||||
workspaceKind: WorkspaceKind;
|
workspaceKind: WorkspaceKind;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WorkspaceDetailsOverview: React.FunctionComponent<WorkspaceDetailsOverviewProps> = ({
|
export const WorkspaceKindDetailsOverview: React.FunctionComponent<
|
||||||
workspaceKind,
|
WorkspaceDetailsOverviewProps
|
||||||
}) => (
|
> = ({ workspaceKind }) => (
|
||||||
<DescriptionList isHorizontal>
|
<DescriptionList isHorizontal>
|
||||||
<DescriptionListGroup>
|
<DescriptionListGroup>
|
||||||
<DescriptionListTerm>Name</DescriptionListTerm>
|
<DescriptionListTerm>Name</DescriptionListTerm>
|
|
@ -46,3 +46,9 @@ export interface WorkspaceFormData {
|
||||||
podConfig: WorkspacePodConfigValue | undefined;
|
podConfig: WorkspacePodConfigValue | undefined;
|
||||||
properties: WorkspaceFormProperties;
|
properties: WorkspaceFormProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WorkspaceCountPerKindImagePodConfig {
|
||||||
|
count: number;
|
||||||
|
countByImage: Record<WorkspaceImageConfigValue['id'], number>;
|
||||||
|
countByPodConfig: Record<WorkspacePodConfigValue['id'], number>;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue