Skip to content

Commit

Permalink
refactor: parsing image data for versions before 24.12 (#2817)
Browse files Browse the repository at this point in the history
**Changes:**
Refactored image handling similar to #2785 and #2795 for versions before 24.12. Before 24.12, most data parsing is handled on the frontend.

Key changes:
- Consolidated separate tag components (BaseImageTags, ConstraintTags, LangTags) into a single ImageTags component
- Simplified image metadata extraction by using string operations instead of complex parsing
- Removed redundant language column and consolidated information into Tags column
- Added new getTags utility function to consistently parse and format image tag information
- Updated image search functionality to search through tag keys and values

**Impact:**
- Cleaner, more consistent display of image metadata in the UI
- More maintainable code structure for handling image tags
- Improved search capabilities across image metadata

**Screenshots:**

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/2HueYSdFvL8pOB5mgrUQ/483e263b-88bc-4d5e-8a22-d3e219695f76.png)

**What to check:**
Data parsing is the same as 24.12.

**Checklist:**
- [ ] Mention to the original issue
- [ ] Documentation
- [x] Minium required manager version: manager < 24.12
- [x] Specific setting for review: 10.100.64.15
- [x] Minimum requirements to check during review
- [ ] Test case(s) to demonstrate the difference of before/after: will be handled in another stack
  • Loading branch information
agatha197 committed Nov 12, 2024
1 parent 90496bc commit 4543a32
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 170 deletions.
15 changes: 14 additions & 1 deletion react/src/components/AliasedImageDoubleTags.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { preserveDotStartCase } from '../helper';
import { useBackendAIImageMetaData } from '../hooks';
import DoubleTag, { DoubleTagObjectValue } from './DoubleTag';
import Flex from './Flex';
import TextHighlighter from './TextHighlighter';
import { AliasedImageDoubleTagsFragment$key } from './__generated__/AliasedImageDoubleTagsFragment.graphql';
import { Tag } from 'antd';
import graphql from 'babel-plugin-relay/macro';
import _ from 'lodash';
import React from 'react';
Expand Down Expand Up @@ -45,7 +47,11 @@ const AliasedImageDoubleTags: React.FC<AliasedImageDoubleTagsProps> = ({
key: 'ai.backend.customized-image.name',
})?.value
: tag.value;
return (
const aliasedTag = tagAlias(tag.key + tagValue);
return _.isEqual(
aliasedTag,
preserveDotStartCase(tag.key + tagValue),
) ? (
<DoubleTag
key={tag.key}
values={[
Expand All @@ -68,6 +74,13 @@ const AliasedImageDoubleTags: React.FC<AliasedImageDoubleTagsProps> = ({
]}
{...doubleTagProps}
/>
) : (
<Tag
key={tag.key}
color={isCustomized ? 'cyan' : doubleTagProps.color}
>
{aliasedTag}
</Tag>
);
})}
</Flex>
Expand Down
111 changes: 30 additions & 81 deletions react/src/components/CustomizedImageList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import Flex from '../components/Flex';
import {
BaseImageTags,
ConstraintTags,
LangTags,
} from '../components/ImageTags';
import TableColumnsSettingModal from '../components/TableColumnsSettingModal';
import {
filterEmptyItem,
Expand All @@ -17,6 +12,7 @@ import {
useUpdatableState,
} from '../hooks';
import AliasedImageDoubleTags from './AliasedImageDoubleTags';
import { ImageTags } from './ImageTags';
import TextHighlighter from './TextHighlighter';
import { CustomizedImageListForgetAndUntagMutation } from './__generated__/CustomizedImageListForgetAndUntagMutation.graphql';
import {
Expand Down Expand Up @@ -63,19 +59,8 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
const [inFlightImageId, setInFlightImageId] = useState<string>();
const [imageSearch, setImageSearch] = useState('');
const [isPendingSearchTransition, startSearchTransition] = useTransition();
const [
,
{
getNamespace,
getImageLang,
getBaseVersion,
getBaseImage,
getConstraints,
tagAlias,
getLang,
getBaseImages,
},
] = useBackendAIImageMetaData();
const [, { getBaseVersion, getBaseImages, getBaseImage, tagAlias, getTags }] =
useBackendAIImageMetaData();

const { customized_images } = useLazyLoadQuery<CustomizedImageListQuery>(
graphql`
Expand Down Expand Up @@ -142,17 +127,14 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
fullName: getImageFullName(image) || '',
digest: image?.digest || '',
// ------------ need only before 24.12.0 ------------
lang: image?.name ? getLang(image.name) : '',
baseversion: getBaseVersion(getImageFullName(image) || ''),
baseimage:
image?.tag && image?.name ? getBaseImages(image.tag, image.name) : [],
constraints:
image?.tag && image?.labels
? getConstraints(
image.tag,
image.labels as { key: string; value: string }[],
)
: [],
tag:
getTags(
image?.tag || '',
image?.labels as Array<{ key: string; value: string }>,
) || [],
isCustomized: image?.tag
? image.tag.indexOf('customized') !== -1
: false,
Expand Down Expand Up @@ -180,14 +162,13 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
const baseImagesMatch = _.some(curFilterValues.baseimage, (value) =>
regExp.test(value),
);
const constraintsMatch = _.some(
curFilterValues.constraints,
(constraint) => regExp.test(constraint),
const tagMatch = _.some(
curFilterValues.tag,
(tag) => regExp.test(tag.key) || regExp.test(tag.value),
);
const customizedMatch = curFilterValues.isCustomized
? regExp.test('customized')
: false;
const langMatch = regExp.test(curFilterValues.lang);
const namespaceMatch = regExp.test(curFilterValues.namespace || '');
const fullNameMatch = regExp.test(curFilterValues.fullName);
const tagsMatch = _.some(
Expand All @@ -200,8 +181,7 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
return (
baseVersionMatch ||
baseImagesMatch ||
constraintsMatch ||
langMatch ||
tagMatch ||
namespaceMatch ||
customizedMatch ||
fullNameMatch ||
Expand Down Expand Up @@ -281,7 +261,7 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
title: t('environment.Tags'),
key: 'tags',
dataIndex: 'tags',
render: (text, row) => (
render: (text: Array<{ key: string; value: string }>, row) => (
<AliasedImageDoubleTags
imageFrgmt={row}
label={undefined}
Expand All @@ -294,25 +274,9 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
title: t('environment.Namespace'),
key: 'name',
dataIndex: 'name',
sorter: (a, b) => {
const namespaceA = getNamespace(getImageFullName(a) || '');
const namespaceB = getNamespace(getImageFullName(b) || '');
return localeCompare(namespaceA, namespaceB);
},
render: (text, row) => (
<span>{getNamespace(getImageFullName(row) || '')}</span>
),
},
!supportExtendedImageInfo && {
title: t('environment.Language'),
key: 'lang',
sorter: (a, b) =>
localeCompare(
getImageLang(getImageFullName(a) || ''),
getImageLang(getImageFullName(b) || ''),
),
render: (text, row) => (
<LangTags image={getImageFullName(row) || ''} color="green" />
sorter: (a, b) => localeCompare(getImageFullName(a), getImageFullName(b)),
render: (text) => (
<TextHighlighter keyword={imageSearch}>{text}</TextHighlighter>
),
},
!supportExtendedImageInfo && {
Expand Down Expand Up @@ -340,38 +304,23 @@ const CustomizedImageList: React.FC<PropsWithChildren> = ({ children }) => {
getBaseImage(getImageFullName(b) || ''),
),
render: (text, row) => (
<BaseImageTags image={getImageFullName(row) || ''} />
<TextHighlighter keyword={imageSearch}>
{tagAlias(getBaseImage(getImageFullName(row) || ''))}
</TextHighlighter>
),
},
!supportExtendedImageInfo && {
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] || ''
: '';
return localeCompare(requirementA, requirementB);
},
render: (text, row) =>
row?.tag ? (
<ConstraintTags
tag={row?.tag}
labels={row?.labels as Array<{ key: string; value: string }>}
highlightKeyword={imageSearch}
/>
) : null,
title: t('environment.Tags'),
key: 'tag',
dataIndex: 'tag',
sorter: (a, b) => localeCompare(a?.tag, b?.tag),
render: (text, row) => (
<ImageTags
tag={text}
labels={row?.labels as Array<{ key: string; value: string }>}
highlightKeyword={imageSearch}
/>
),
},
{
title: t('environment.Digest'),
Expand Down
18 changes: 17 additions & 1 deletion react/src/components/ImageEnvironmentSelectFormItems.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getImageFullName, localeCompare } from '../helper';
import { preserveDotStartCase } from '../helper';
import {
useBackendAIImageMetaData,
useSuspendedBackendaiClient,
Expand Down Expand Up @@ -745,7 +746,13 @@ const ImageEnvironmentSelectFormItems: React.FC<
key: 'ai.backend.customized-image.name',
})?.value
: tag.value;
return (
const aliasedTag = tagAlias(
tag.key + tagValue,
);
return _.isEqual(
aliasedTag,
preserveDotStartCase(tag.key + tagValue),
) ? (
<DoubleTag
key={tag.key}
values={[
Expand Down Expand Up @@ -773,6 +780,15 @@ const ImageEnvironmentSelectFormItems: React.FC<
},
]}
/>
) : (
<Tag
key={tag.key}
color={isCustomized ? 'cyan' : 'blue'}
>
<TextHighlighter keyword={versionSearch}>
{aliasedTag}
</TextHighlighter>
</Tag>
);
},
)}
Expand Down
Loading

0 comments on commit 4543a32

Please sign in to comment.