diff --git a/gql-queries-generator/doc/queries.graphql b/gql-queries-generator/doc/queries.graphql index 80f53a71e..58c1cb9b1 100644 --- a/gql-queries-generator/doc/queries.graphql +++ b/gql-queries-generator/doc/queries.graphql @@ -135,6 +135,7 @@ query consoleListAllClusters($search: SearchCluster, $pagination: CursorPaginati cursor node { accountName + ownedBy clusterSvcCIDR lastOnlineAt createdBy { @@ -2438,9 +2439,6 @@ query consoleGetPvc($clusterName: String!, $name: String!) { namespace } resources { - claims { - name - } limits requests } @@ -2505,9 +2503,6 @@ query consoleListPvcs($clusterName: String!, $search: SearchPersistentVolumeClai namespace } resources { - claims { - name - } limits requests } @@ -3386,6 +3381,7 @@ query consoleGetBYOKClusterInstructions($name: String!, $onlyHelmValues: Boolean query consoleGetByokCluster($name: String!) { infra_getBYOKCluster(name: $name) { accountName + ownedBy createdBy { userEmail userId @@ -3430,6 +3426,7 @@ query consoleListByokClusters($search: SearchCluster, $pagination: CursorPaginat cursor node { accountName + ownedBy clusterSvcCIDR lastOnlineAt createdBy { @@ -4489,6 +4486,20 @@ query consoleGetRegistryImageUrl { } } +query consoleSearchRegistryImages($query: String!) { + core_searchRegistryImages(query: $query) { + accountName + creationTime + id + imageName + imageTag + markedForDeletion + meta + recordVersion + updateTime + } +} + query consoleListRegistryImages($pq: CursorPaginationIn) { core_listRegistryImages(pq: $pq) { edges { diff --git a/src/apps/console/page-components/app/general.tsx b/src/apps/console/page-components/app/general.tsx index 0957b335c..0c2a58e7d 100644 --- a/src/apps/console/page-components/app/general.tsx +++ b/src/apps/console/page-components/app/general.tsx @@ -2,16 +2,19 @@ import { useParams } from '@remix-run/react'; import { useCallback, useEffect, useState } from 'react'; import { Checkbox } from '~/components/atoms/checkbox'; import { TextInput } from '~/components/atoms/input'; +import Select from '~/components/atoms/select'; import { BottomNavigation } from '~/console/components/commons'; import { NameIdView } from '~/console/components/name-id-view'; import { useAppState } from '~/console/page-components/app-states'; import { FadeIn } from '~/console/page-components/util'; +import { AppSelectItem } from '~/console/routes/_main+/$account+/env+/$environment+/new-app/app-detail'; import HandleBuild from '~/console/routes/_main+/$account+/repo+/$repo+/builds/handle-builds'; import { useConsoleApi } from '~/console/server/gql/api-provider'; -import { parseName, parseNodes } from '~/console/server/r-utils/common'; +import { parseName } from '~/console/server/r-utils/common'; import { keyconstants } from '~/console/server/r-utils/key-constants'; import { ensureAccountClientSide } from '~/console/server/utils/auth-utils'; import { constants } from '~/console/server/utils/constants'; +import useDebounce from '~/root/lib/client/hooks/use-debounce'; import useForm, { dummyEvent } from '~/root/lib/client/hooks/use-form'; import { useUnsavedChanges } from '~/root/lib/client/hooks/use-unsaved-changes'; import Yup from '~/root/lib/server/helpers/yup'; @@ -63,28 +66,8 @@ import { handleError } from '~/root/lib/utils/common'; // return ; // }; -const AppSelectItem = ({ - label, - value, - registry, - repository, -}: { - label: string; - value: string; - registry: string; - repository: string; -}) => { - return ( -
-
-
{label}
- {registry !== '' && repository !== '' && ( -
{`${registry}/${repository}`}
- )} - {/*
{value}
*/} -
-
- ); +const valueRenderer = ({ value }: { value: string }) => { + return
{value}
; }; const AppGeneral = ({ mode = 'new' }: { mode: 'edit' | 'new' }) => { @@ -109,38 +92,49 @@ const AppGeneral = ({ mode = 'new' }: { mode: 'edit' | 'new' }) => { const [imageList, setImageList] = useState([]); const [imageLoaded, setImageLoaded] = useState(false); + const [imageSearchText, setImageSearchText] = useState(''); - const getRegistryImages = useCallback(async () => { - ensureAccountClientSide(params); - setImageLoaded(true); - try { - const registrayImages = await api.listRegistryImages({}); - const data = parseNodes(registrayImages.data).map((i) => ({ - label: `${i.imageName}:${i.imageTag}`, - value: `${i.imageName}:${i.imageTag}`, - ready: true, - render: () => ( - - ), - })); - setImageList(data); - } catch (err) { - handleError(err); - } finally { - setImageLoaded(false); - } - }, []); + const getRegistryImages = useCallback( + async ({ query }: { query: string }) => { + ensureAccountClientSide(params); + setImageLoaded(true); + try { + const registrayImages = await api.searchRegistryImages({ query }); + const data = registrayImages.data.map((i) => ({ + label: `${i.imageName}:${i.imageTag}/${i.meta.author}/${i.meta.registry}:${i.meta.repository}`, + value: `${i.imageName}:${i.imageTag}`, + ready: true, + render: () => ( + + ), + })); + setImageList(data); + } catch (err) { + handleError(err); + } finally { + setImageLoaded(false); + } + }, + [] + ); useEffect(() => { - getRegistryImages(); + getRegistryImages({ query: '' }); }, []); - // const api = useConsoleApi(); + useDebounce( + () => { + if (imageSearchText) { + getRegistryImages({ query: imageSearchText }); + } + }, + 300, + [imageSearchText] + ); const { values, @@ -317,7 +311,7 @@ const AppGeneral = ({ mode = 'new' }: { mode: 'edit' | 'new' }) => { /> )}
- { onChange={handleChange('imageUrl')} error={!!errors.imageUrl} message={errors.imageUrl} - /> - {/* imageList} onChange={({ value }) => { handleChange('imageUrl')(dummyEvent(value)); }} + onSearch={(text) => { + setImageSearchText(text); + }} showclear noOptionMessage={
@@ -346,7 +345,8 @@ const AppGeneral = ({ mode = 'new' }: { mode: 'edit' | 'new' }) => { message={errors.imageUrl} loading={imageLoaded} createLabel="Select" - /> */} + valueRender={valueRenderer} + />
{ + return
{value}
; +}; + +export const AppSelectItem = ({ label, - value, - registry, - repository, + meta, + imageSearchText, }: { label: string; - value: string; - registry: string; - repository: string; + meta: any; + imageSearchText: string; }) => { + const getHighlightedText = (text: string, highlight: string) => { + if (!highlight) return text; + + const regex = new RegExp(`(${highlight})`, 'gi'); + const parts = text.split(regex); + + return parts.map((part, index) => + part.toLowerCase() === highlight.toLowerCase() ? ( + // eslint-disable-next-line react/no-array-index-key + + {part} + + ) : ( + part + ) + ); + }; + return (
-
-
{label}
- {registry !== '' && repository !== '' && ( -
{`${registry}/${repository}`}
- )} +
+
{label}
+
+ {meta && + Object.keys(meta).length > 0 && + Object.keys(meta).map((key) => ( +
+ {`${key}: `} + {getHighlightedText(meta[key], imageSearchText)} + {' |'} +
+ ))} +
); @@ -104,47 +133,51 @@ const AppDetail = () => { const [imageList, setImageList] = useState([]); const [imageLoaded, setImageLoaded] = useState(false); - // const [imageSearchText, setImageSearchText] = useState(''); + const [imageSearchText, setImageSearchText] = useState(''); - const getRegistryImages = useCallback(async () => { - ensureAccountClientSide(params); - setImageLoaded(true); - try { - const registrayImages = await api.listRegistryImages({}); - const data = parseNodes(registrayImages.data).map((i) => ({ - label: `${i.imageName}:${i.imageTag}`, - value: `${i.imageName}:${i.imageTag}`, - ready: true, - render: () => ( - - ), - })); - setImageList(data); - } catch (err) { - handleError(err); - } finally { - setImageLoaded(false); - } - }, []); + const getRegistryImages = useCallback( + async ({ query }: { query: string }) => { + ensureAccountClientSide(params); + setImageLoaded(true); + try { + const registrayImages = await api.searchRegistryImages({ + query, + }); + const data = registrayImages.data.map((i) => ({ + label: `${i.imageName}:${i.imageTag}/${i.meta.author}/${i.meta.registry}:${i.meta.repository}`, + value: `${i.imageName}:${i.imageTag}`, + ready: true, + render: () => ( + + ), + })); + setImageList(data); + } catch (err) { + handleError(err); + } finally { + setImageLoaded(false); + } + }, + [] + ); useEffect(() => { - getRegistryImages(); + getRegistryImages({ query: '' }); }, []); - // useDebounce( - // () => { - // if (imageSearchText) { - // getRegistryImages(); - // } - // }, - // 300, - // [imageSearchText] - // ); + useDebounce( + () => { + if (imageSearchText) { + getRegistryImages({ query: imageSearchText }); + } + }, + 300, + [imageSearchText] + ); const { values, errors, handleChange, handleSubmit, isLoading, setValues } = useForm({ @@ -332,7 +365,7 @@ const AppDetail = () => { size="sm" /> */} - { onChange={handleChange('imageUrl')} error={!!errors.imageUrl} message={errors.imageUrl} - /> + /> */} - {/*