Skip to content

Commit

Permalink
feat: add AliasedImageDoubleTags
Browse files Browse the repository at this point in the history
  • Loading branch information
agatha197 committed Nov 1, 2024
1 parent 078321b commit eae7706
Showing 1 changed file with 187 additions and 112 deletions.
299 changes: 187 additions & 112 deletions react/src/components/ImageList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import Flex from '../components/Flex';
import { filterNonNullItems, getImageFullName, localeCompare } from '../helper';
import { useBackendAIImageMetaData, useUpdatableState } from '../hooks';
import {
useBackendAIImageMetaData,
useSuspendedBackendaiClient,
useUpdatableState,
} from '../hooks';
import DoubleTag from './DoubleTag';
import ImageInstallModal from './ImageInstallModal';
import { ConstraintTags } from './ImageTags';
import { BaseImageTags, ConstraintTags, LangTags } from './ImageTags';
import ManageAppsModal from './ManageAppsModal';
import ManageImageResourceLimitModal from './ManageImageResourceLimitModal';
import ResourceNumber from './ResourceNumber';
Expand Down Expand Up @@ -61,6 +66,9 @@ const ImageList: React.FC<{ style?: React.CSSProperties }> = ({ style }) => {
const [isOpenColumnsSetting, setIsOpenColumnsSetting] = useState(false);
const [isPendingRefreshTransition, startRefreshTransition] = useTransition();
const [isPendingSearchTransition, startSearchTransition] = useTransition();
const [, { tagAlias }] = useBackendAIImageMetaData();
const baiClient = useSuspendedBackendaiClient();
const supportExtendedImageInfo = baiClient?.supports('extended-image-info');

const { images } = useLazyLoadQuery<ImageListQuery>(
graphql`
Expand Down Expand Up @@ -171,116 +179,183 @@ const ImageList: React.FC<{ style?: React.CSSProperties }> = ({ style }) => {
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
),
},
{
title: t('environment.Namespace'),
key: 'namespace',
dataIndex: 'namespace',
sorter: (a, b) => {
const namespaceA = getNamespace(getImageFullName(a) || '');
const namespaceB = getNamespace(getImageFullName(b) || '');
return namespaceA && namespaceB
? namespaceA.localeCompare(namespaceB)
: 0;
},
render: (text, row) => (
<TextHighlighter keyword={imageSearch}>
{getNamespace(getImageFullName(row) || '')}
</TextHighlighter>
),
},
{
title: t('environment.Language'),
key: 'lang',
dataIndex: 'lang',
sorter: (a, b) => {
const langA = a?.name ? getLang(a?.name) : '';
const langB = b?.name ? getLang(b?.name) : '';
return langA && langB ? langA.localeCompare(langB) : 0;
},
render: (text, row) => (
<TextHighlighter keyword={imageSearch}>
{row.name ? getLang(row.name) : null}
</TextHighlighter>
),
},
{
title: t('environment.Version'),
key: 'baseversion',
dataIndex: 'baseversion',
sorter: (a, b) => {
const baseversionA = getBaseVersion(getImageFullName(a) || '');
const baseversionB = getBaseVersion(getImageFullName(b) || '');
return baseversionA && baseversionB
? baseversionA.localeCompare(baseversionB)
: 0;
},
render: (text, row) => (
<TextHighlighter keyword={imageSearch}>
{getBaseVersion(getImageFullName(row) || '')}
</TextHighlighter>
),
},
{
title: t('environment.Base'),
key: 'baseimage',
dataIndex: 'baseimage',
sorter: (a, b) => {
const baseimageA =
!a?.tag || !a?.name ? '' : getBaseImages(a?.tag, a?.name)[0] || '';
const baseimageB =
!b?.tag || !b?.name ? '' : getBaseImages(b?.tag, b?.name)[0] || '';
if (baseimageA === '' && baseimageB === '') return 0;
if (baseimageA === '') return -1;
if (baseimageB === '') return 1;
return baseimageA.localeCompare(baseimageB);
},
render: (text, row) => (
<Flex direction="row" align="start">
{row?.tag && row?.name
? getBaseImages(row.tag, row.name).map((baseImage) => (
<Tag color="green">
<TextHighlighter keyword={imageSearch}>
{baseImage}
</TextHighlighter>
</Tag>
))
: null}
</Flex>
),
},
{
title: t('environment.Constraint'),
key: 'constraint',
dataIndex: '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 }[]}
highlightKeyword={imageSearch}
/>
) : null,
},
...(supportExtendedImageInfo
? [
{
title: t('environment.Namespace'),
key: 'namespace',
dataIndex: 'namespace',
sorter: (a: EnvironmentImage, b: EnvironmentImage) =>
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: EnvironmentImage, b: EnvironmentImage) =>
localeCompare(a?.base_image_name, b?.base_image_name),
render: (text: string, row: EnvironmentImage) => (
// Replace with this code after using ImageNode instead of Image
// <AliasedBaseImageName
// imageFrgmt={row}
// highlightKeyword={imageSearch}
// />
<TextHighlighter keyword={imageSearch}>
{tagAlias(text)}
</TextHighlighter>
),
},
{
title: t('environment.Version'),
key: 'version',
dataIndex: 'version',
sorter: (a: EnvironmentImage, b: EnvironmentImage) =>
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: EnvironmentImage,
) => {
return (
// <AliasedImageDoubleTags
// imageFrgmt={row}
// label={undefined}
// highlightKeyword={imageSearch}
// />
<Flex direction="row" align="start">
{_.map(text, (tag: { key: string; value: string }) => {
const isCustomized = _.includes(tag.key, 'customized_');
const tagValue = isCustomized
? _.find(row?.labels, {
key: 'ai.backend.customized-image.name',
})?.value
: tag.value;
return (
<DoubleTag
key={tag.key}
values={[
{
label: (
<TextHighlighter
keyword={imageSearch}
key={tag.key}
>
{tagAlias(tag.key)}
</TextHighlighter>
),
color: isCustomized ? 'cyan' : 'blue',
},
{
label: (
<TextHighlighter
keyword={imageSearch}
key={tagValue}
>
{tagValue}
</TextHighlighter>
),
color: isCustomized ? 'cyan' : 'blue',
},
]}
/>
);
})}
</Flex>
);
},
},
]
: [
{
title: t('environment.Namespace'),
key: 'name',
dataIndex: 'name',
sorter: (a: EnvironmentImage, b: EnvironmentImage) =>
localeCompare(getImageFullName(a), getImageFullName(b)),
render: (text: string, row: EnvironmentImage) => (
<TextHighlighter keyword={imageSearch}>
{getNamespace(getImageFullName(row) || '')}
</TextHighlighter>
),
},
{
title: t('environment.Language'),
key: 'lang',
dataIndex: 'lang',
sorter: (a: EnvironmentImage, b: EnvironmentImage) =>
localeCompare(getLang(a.name ?? ''), getLang(b.name ?? '')),
render: (text: string, row: EnvironmentImage) => (
<LangTags image={getImageFullName(row) || ''} color="green" />
),
},
{
title: t('environment.Version'),
key: 'baseversion',
dataIndex: 'baseversion',
sorter: (a: EnvironmentImage, b: EnvironmentImage) =>
localeCompare(
getBaseVersion(getImageFullName(a) || ''),
getBaseVersion(getImageFullName(b) || ''),
),
render: (text: string, row: EnvironmentImage) => (
<TextHighlighter keyword={imageSearch}>
{getBaseVersion(getImageFullName(row) || '')}
</TextHighlighter>
),
},
{
title: t('environment.Base'),
key: 'baseimage',
dataIndex: 'baseimage',
sorter: (a: EnvironmentImage, b: EnvironmentImage) =>
localeCompare(
getBaseImage(getBaseImage(getImageFullName(a) || '')),
getBaseImage(getBaseImage(getImageFullName(b) || '')),
),
render: (text: string, row: EnvironmentImage) => (
<BaseImageTags image={getImageFullName(row) || ''} />
),
},
{
title: t('environment.Constraint'),
key: 'constraint',
dataIndex: 'constraint',
sorter: (a: EnvironmentImage, b: EnvironmentImage) => {
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] || ''
: '';
return localeCompare(requirementA, requirementB);
},
render: (text: string, row: EnvironmentImage) =>
row?.tag ? (
<ConstraintTags
tag={row.tag}
labels={row?.labels as { key: string; value: string }[]}
/>
) : null,
},
]),
{
title: t('environment.Digest'),
dataIndex: 'digest',
Expand Down

0 comments on commit eae7706

Please sign in to comment.