Skip to content

Commit

Permalink
refactor: new image parsing on CustomizedImageList
Browse files Browse the repository at this point in the history
  • Loading branch information
agatha197 committed Nov 1, 2024
1 parent e726443 commit 694c97a
Showing 1 changed file with 187 additions and 84 deletions.
271 changes: 187 additions & 84 deletions react/src/components/CustomizedImageList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ import {
useSuspendedBackendaiClient,
useUpdatableState,
} from '../hooks';
import AliasedBaseImageName from './AliasedBaseImageName';
import AliasedImageDoubleTags from './AliasedImageDoubleTags';
import TextHighlighter from './TextHighlighter';
import { CustomizedImageListForgetAndUntagMutation } from './__generated__/CustomizedImageListForgetAndUntagMutation.graphql';
import {
CustomizedImageListQuery,
CustomizedImageListQuery$data,
} from './__generated__/CustomizedImageListQuery.graphql';
import { DeleteOutlined, SettingOutlined } from '@ant-design/icons';
import CopyButton from './lablupTalkativotUI/CopyButton';
import {
DeleteOutlined,
ReloadOutlined,
SearchOutlined,
SettingOutlined,
} from '@ant-design/icons';
import { useLocalStorageState } from 'ahooks';
import { App, Button, Input, Popconfirm, Table, theme, Typography } from 'antd';
import { AnyObject } from 'antd/es/_util/type';
Expand Down Expand Up @@ -45,6 +54,8 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
const [customizedImageListFetchKey, updateCustomizedImageListFetchKey] =
useUpdatableState('initial-fetch');
const [inFlightImageId, setInFlightImageId] = useState<string>();
const [imageSearch, setImageSearch] = useState('');
const [isPendingSearchTransition, startSearchTransition] = useTransition();
const [
,
{
Expand Down Expand Up @@ -73,6 +84,14 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
}
supported_accelerators
namespace @since(version: "24.09.1.")
base_image_name @since(version: "24.09.1.")
tags @since(version: "24.09.1.") {
key
value
}
version @since(version: "24.09.1.")
...AliasedBaseImageNameFragment
...AliasedImageDoubleTagsFragment
}
}
`,
Expand Down Expand Up @@ -101,17 +120,42 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
`);

const columns: ColumnsType<CommittedImage> = [
{
title: t('environment.FullImagePath'),
key: 'fullImagePath',
render: (row) => (
<Flex gap={'xxs'}>
<TextHighlighter keyword={imageSearch}>
{getImageFullName(row) || ''}
</TextHighlighter>
<CopyButton
type="text"
style={{ color: token.colorPrimary }}
copyable={{
text: getImageFullName(row) || '',
}}
/>
</Flex>
),
sorter: (a, b) => localeCompare(getImageFullName(a), getImageFullName(b)),
},
{
title: t('environment.Registry'),
dataIndex: 'registry',
key: 'registry',
sorter: (a, b) => localeCompare(a?.registry, b?.registry),
render: (text) => (
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
),
},
{
title: t('environment.Architecture'),
dataIndex: 'architecture',
key: 'architecture',
sorter: (a, b) => localeCompare(a?.architecture, b?.architecture),
render: (text) => (
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
),
},
...(supportExtendedImageInfo
? [
Expand All @@ -121,6 +165,47 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
dataIndex: 'namespace',
sorter: (a: CommittedImage, b: CommittedImage) =>
localeCompare(a?.namespace, b?.namespace),
render: (text: string) => (
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
),
},
{
title: t('environment.BaseImageName'),
key: 'base_image_name',
dataIndex: 'base_image_name',
sorter: (a: CommittedImage, b: CommittedImage) =>
localeCompare(a?.base_image_name, b?.base_image_name),
render: (text: string, row: CommittedImage) => (
<AliasedBaseImageName
imageFrgmt={row}
highlightKeyword={imageSearch}
/>
),
},
{
title: t('environment.Version'),
key: 'version',
dataIndex: 'version',
sorter: (a: CommittedImage, b: CommittedImage) =>
localeCompare(a?.version, b?.version),
render: (text: string) => (
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
),
},
{
title: t('environment.Tags'),
key: 'tags',
dataIndex: 'tags',
render: (
text: Array<{ key: string; value: string }>,
row: CommittedImage,
) => (
<AliasedImageDoubleTags
imageFrgmt={row}
label={undefined}
highlightKeyword={imageSearch}
/>
),
},
]
: [
Expand All @@ -139,100 +224,96 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
<span>{getNamespace(getImageFullName(row) || '')}</span>
),
},
{
title: t('environment.Language'),
key: 'lang',
sorter: (a: CommittedImage, b: CommittedImage) => {
const langA = getImageLang(getImageFullName(a) || '');
const langB = getImageLang(getImageFullName(b) || '');
return langA && langB ? langA.localeCompare(langB) : 0;
},
render: (text: string, row: CommittedImage) => (
<LangTags image={getImageFullName(row) || ''} color="green" />
),
},
{
title: t('environment.Version'),
key: 'baseversion',
dataIndex: 'baseversion',
sorter: (a: CommittedImage, b: CommittedImage) =>
localeCompare(
getBaseVersion(getImageFullName(a) || ''),
getBaseVersion(getImageFullName(b) || ''),
),
render: (text: string, row: CommittedImage) => (
<TextHighlighter keyword={imageSearch}>
{getBaseVersion(getImageFullName(row) || '')}
</TextHighlighter>
),
},
{
title: t('environment.Base'),
key: 'baseimage',
dataIndex: 'baseimage',
sorter: (a: CommittedImage, b: CommittedImage) =>
localeCompare(
getBaseImage(getBaseImage(getImageFullName(a) || '')),
getBaseImage(getBaseImage(getImageFullName(b) || '')),
),
render: (text: string, row: CommittedImage) => (
<BaseImageTags image={getImageFullName(row) || ''} />
),
},
{
title: t('environment.Constraint'),
key: 'constraint',
dataIndex: 'constraint',
sorter: (a: CommittedImage, b: CommittedImage) => {
const requirementA =
a?.tag && b?.labels
? getConstraints(
a?.tag,
a?.labels as { key: string; value: string }[],
)[0] || ''
: '';
const requirementB =
b?.tag && b?.labels
? getConstraints(
b?.tag,
b?.labels as { key: string; value: string }[],
)[0] || ''
: '';
if (requirementA === '' && requirementB === '') return 0;
if (requirementA === '') return -1;
if (requirementB === '') return 1;
return requirementA.localeCompare(requirementB);
},
render: (text: string, row: CommittedImage) =>
row?.tag ? (
<ConstraintTags
tag={row.tag}
labels={row?.labels as { key: string; value: string }[]}
/>
) : null,
},
]),
{
title: t('environment.Language'),
key: 'lang',
sorter: (a, b) => {
const langA = getImageLang(getImageFullName(a) || '');
const langB = getImageLang(getImageFullName(b) || '');
return langA && langB ? langA.localeCompare(langB) : 0;
},
render: (text, row) => (
<LangTags image={getImageFullName(row) || ''} color="green" />
),
},
{
title: t('environment.Version'),
key: 'baseversion',
sorter: (a, b) => {
const baseversionA = getBaseVersion(getImageFullName(a) || '');
const baseversionB = getBaseVersion(getImageFullName(b) || '');
return baseversionA && baseversionB
? baseversionA.localeCompare(baseversionB)
: 0;
},
render: (text, row) => (
<BaseVersionTags image={getImageFullName(row) || ''} color="green" />
),
},
{
title: t('environment.Base'),
key: 'baseimage',
sorter: (a, b) => {
const baseimageA = getBaseImage(getImageFullName(a) || '');
const baseimageB = getBaseImage(getImageFullName(b) || '');
return baseimageA && baseimageB
? baseimageA.localeCompare(baseimageB)
: 0;
},
render: (text, row) => (
<BaseImageTags image={getImageFullName(row) || ''} />
),
},
{
title: t('environment.Constraint'),
key: 'constraint',
sorter: (a, b) => {
const requirementA =
a?.tag && b?.labels
? getConstraints(
a?.tag,
a?.labels as { key: string; value: string }[],
)[0] || ''
: '';
const requirementB =
b?.tag && b?.labels
? getConstraints(
b?.tag,
b?.labels as { key: string; value: string }[],
)[0] || ''
: '';
if (requirementA === '' && requirementB === '') return 0;
if (requirementA === '') return -1;
if (requirementB === '') return 1;
return requirementA.localeCompare(requirementB);
},
render: (text, row) =>
row?.tag ? (
<ConstraintTags
tag={row.tag}
labels={row?.labels as { key: string; value: string }[]}
/>
) : null,
},
{
title: t('environment.Digest'),
dataIndex: 'digest',
key: 'digest',
sorter: (a, b) =>
a?.digest && b?.digest ? a.digest.localeCompare(b.digest) : 0,
sorter: (a, b) => localeCompare(a?.digest, b?.digest),
render: (text) => (
<Typography.Text ellipsis={{ tooltip: true }} style={{ maxWidth: 200 }}>
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
</Typography.Text>
),
},
{
title: t('general.Control'),
key: 'control',
fixed: 'right',
render: (text, row) => (
<Flex direction="row" align="stretch" justify="center" gap="xxs">
<Typography.Text
copyable={{
text: getImageFullName(row) || '',
}}
style={{
paddingTop: token.paddingXXS,
paddingBottom: token.paddingXXS,
}}
/>
<Popconfirm
title={t('dialog.ask.DoYouWantToProceed')}
description={t('dialog.warning.CannotBeUndone')}
Expand Down Expand Up @@ -293,8 +374,30 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
return (
<Flex direction="column" align="stretch" gap={'xs'}>
<Flex direction="column" align="stretch">
<Flex justify="end" style={{ padding: token.paddingSM }} gap="xs">
<Input
allowClear
prefix={<SearchOutlined />}
placeholder={t('environment.SearchImages')}
onChange={(e) => {
startSearchTransition(() => setImageSearch(e.target.value));
}}
style={{
width: 200,
}}
/>
<Button
icon={<ReloadOutlined />}
loading={isRefetchPending}
onClick={() => {
startRefetchTransition(() => updateCustomizedImageListFetchKey());
}}
>
{t('button.Refresh')}
</Button>
</Flex>
<Table
loading={isRefetchPending}
loading={isPendingSearchTransition}
columns={
columns.filter((column) =>
displayedColumnKeys?.includes(_.toString(column.key)),
Expand Down

0 comments on commit 694c97a

Please sign in to comment.