From 6547cf8666277ecc3444d3d97617c1b5d8aa3eee Mon Sep 17 00:00:00 2001 From: agatha197 Date: Thu, 31 Oct 2024 12:32:22 +0900 Subject: [PATCH] refactor: new image parsing on `CustomizedImageList` --- react/src/components/CustomizedImageList.tsx | 271 +++++++++++++------ 1 file changed, 187 insertions(+), 84 deletions(-) diff --git a/react/src/components/CustomizedImageList.tsx b/react/src/components/CustomizedImageList.tsx index f8c287d194..029326b361 100644 --- a/react/src/components/CustomizedImageList.tsx +++ b/react/src/components/CustomizedImageList.tsx @@ -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'; @@ -45,6 +54,8 @@ const CustomizedImageList: React.FC = ({ children }) => { const [customizedImageListFetchKey, updateCustomizedImageListFetchKey] = useUpdatableState('initial-fetch'); const [inFlightImageId, setInFlightImageId] = useState(); + const [imageSearch, setImageSearch] = useState(''); + const [isPendingSearchTransition, startSearchTransition] = useTransition(); const [ , { @@ -73,6 +84,14 @@ const CustomizedImageList: React.FC = ({ 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 } } `, @@ -101,17 +120,42 @@ const CustomizedImageList: React.FC = ({ children }) => { `); const columns: ColumnsType = [ + { + title: t('environment.FullImagePath'), + key: 'fullImagePath', + render: (row) => ( + + + {getImageFullName(row) || ''} + + + + ), + 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) => ( + {text} + ), }, { title: t('environment.Architecture'), dataIndex: 'architecture', key: 'architecture', sorter: (a, b) => localeCompare(a?.architecture, b?.architecture), + render: (text) => ( + {text} + ), }, ...(supportExtendedImageInfo ? [ @@ -121,6 +165,47 @@ const CustomizedImageList: React.FC = ({ children }) => { dataIndex: 'namespace', sorter: (a: CommittedImage, b: CommittedImage) => localeCompare(a?.namespace, b?.namespace), + render: (text: string) => ( + {text} + ), + }, + { + 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) => ( + + ), + }, + { + title: t('environment.Version'), + key: 'version', + dataIndex: 'version', + sorter: (a: CommittedImage, b: CommittedImage) => + localeCompare(a?.version, b?.version), + render: (text: string) => ( + {text} + ), + }, + { + title: t('environment.Tags'), + key: 'tags', + dataIndex: 'tags', + render: ( + text: Array<{ key: string; value: string }>, + row: CommittedImage, + ) => ( + + ), }, ] : [ @@ -139,84 +224,89 @@ const CustomizedImageList: React.FC = ({ children }) => { {getNamespace(getImageFullName(row) || '')} ), }, + { + 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) => ( + + ), + }, + { + 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) => ( + + {getBaseVersion(getImageFullName(row) || '')} + + ), + }, + { + 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) => ( + + ), + }, + { + 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 ? ( + + ) : 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) => ( - - ), - }, - { - 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) => ( - - ), - }, - { - 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) => ( - - ), - }, - { - 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 ? ( - - ) : 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) => ( + + {text} + + ), }, { title: t('general.Control'), @@ -224,15 +314,6 @@ const CustomizedImageList: React.FC = ({ children }) => { fixed: 'right', render: (text, row) => ( - = ({ children }) => { return ( + + } + placeholder={t('environment.SearchImages')} + onChange={(e) => { + startSearchTransition(() => setImageSearch(e.target.value)); + }} + style={{ + width: 200, + }} + /> + + displayedColumnKeys?.includes(_.toString(column.key)),