From 88bd72f4f8e9b1502b805926538a2fdbaa54e0a6 Mon Sep 17 00:00:00 2001 From: Piyush Kumar Date: Thu, 29 Aug 2024 19:00:12 +0530 Subject: [PATCH] minor ui changes --- gql-queries-generator/doc/queries.graphql | 45 +++ .../console/hooks/use-cluster-status-v2.tsx | 23 +- .../$account+/env+/$environment+/_layout.tsx | 25 +- .../$environment+/apps/apps-resources-v2.tsx | 13 +- .../handle-managed-resource-v2.tsx | 58 ++- .../managed-resources-resource-v2.tsx | 22 +- .../$environment+/managed-resources/route.tsx | 30 +- .../environments/environment-resources-v2.tsx | 39 +- .../infra+/clusters/cluster-resources-v2.tsx | 40 +-- .../backend-services-resources-V2.tsx | 13 +- .../handle-backend-service.tsx | 26 +- .../$account+/managed-services/route.tsx | 26 +- .../_main+/$account+/msvc+/$msv+/_layout.tsx | 24 +- .../msvc+/$msv+/managed-resources/route.tsx | 26 +- .../$msv+/new-managed-resource/_index.tsx | 54 ++- .../$account+/new-managed-service/_index.tsx | 14 +- .../image-pull-secrets-resource-v2.tsx | 22 +- .../ips+/$imagepullsecret+/_layout.tsx | 169 +++++++++ .../images/images-resources.tsx | 340 ++++++++++++++++++ .../ips+/$imagepullsecret+/images/route.tsx | 92 +++++ .../ips+/$imagepullsecret+/images/tools.tsx | 29 ++ .../ips+/$imagepullsecret+/index.tsx | 5 + .../console/routes/_main+/_layout/_layout.tsx | 42 +-- .../gql/queries/byok-cluster-queries.ts | 8 +- .../gql/queries/image-pull-secrets-queries.ts | 66 +++- .../components/atoms/progress-bar.tsx | 2 +- src/generated/gql/server.ts | 41 +++ 27 files changed, 1020 insertions(+), 274 deletions(-) create mode 100644 src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/_layout.tsx create mode 100644 src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/images-resources.tsx create mode 100644 src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/route.tsx create mode 100644 src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/tools.tsx create mode 100644 src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/index.tsx diff --git a/gql-queries-generator/doc/queries.graphql b/gql-queries-generator/doc/queries.graphql index 83340bfd3..566e9f6b6 100644 --- a/gql-queries-generator/doc/queries.graphql +++ b/gql-queries-generator/doc/queries.graphql @@ -3992,6 +3992,51 @@ mutation consoleDeleteImagePullSecrets($name: String!) { core_deleteImagePullSecret(name: $name) } +query consoleGetImagePullSecret($name: String!) { + core_getImagePullSecret(name: $name) { + accountName + createdBy { + userEmail + userId + userName + } + creationTime + displayName + dockerConfigJson + environments + format + id + lastUpdatedBy { + userEmail + userId + userName + } + markedForDeletion + metadata { + annotations + creationTimestamp + deletionTimestamp + generation + labels + name + namespace + } + recordVersion + registryPassword + registryURL + registryUsername + syncStatus { + action + error + lastSyncedAt + recordVersion + state + syncScheduledAt + } + updateTime + } +} + query consoleListImagePullSecrets($search: SearchImagePullSecrets, $pq: CursorPaginationIn) { core_listImagePullSecrets(search: $search, pq: $pq) { edges { diff --git a/src/apps/console/hooks/use-cluster-status-v2.tsx b/src/apps/console/hooks/use-cluster-status-v2.tsx index 598267437..c2e795abc 100644 --- a/src/apps/console/hooks/use-cluster-status-v2.tsx +++ b/src/apps/console/hooks/use-cluster-status-v2.tsx @@ -1,3 +1,4 @@ +import { useParams } from '@remix-run/react'; import { Dispatch, ReactNode, @@ -8,12 +9,11 @@ import { useMemo, useState, } from 'react'; -import { ExtractNodeType, parseNodes } from '../server/r-utils/common'; -import { IByocClusters } from '../server/gql/queries/byok-cluster-queries'; -import { useParams } from '@remix-run/react'; import { useSocketWatch } from '~/root/lib/client/helpers/socket/useWatch'; -import { useConsoleApi } from '../server/gql/api-provider'; import useDebounce from '~/root/lib/client/hooks/use-debounce'; +import { useConsoleApi } from '../server/gql/api-provider'; +import { IByocClusters } from '../server/gql/queries/byok-cluster-queries'; +import { ExtractNodeType, parseNodes } from '../server/r-utils/common'; type IClusterMap = { [key: string]: ExtractNodeType }; @@ -36,13 +36,10 @@ const ClusterStatusProvider = ({ children }: { children: ReactNode }) => { const listCluster = useCallback(async () => { try { const cl = await api.listAllClusters(); - const parsed = parseNodes(cl.data).reduce( - (acc, c) => { - acc[c.metadata.name] = c; - return acc; - }, - {} as { [key: string]: ExtractNodeType }, - ); + const parsed = parseNodes(cl.data).reduce((acc, c) => { + acc[c.metadata.name] = c; + return acc; + }, {} as { [key: string]: ExtractNodeType }); setClusters(parsed); return clusters; } catch (err) { @@ -56,7 +53,7 @@ const ClusterStatusProvider = ({ children }: { children: ReactNode }) => { listCluster(); }, 3000, - [update], + [update] ); useSocketWatch(() => { @@ -67,7 +64,7 @@ const ClusterStatusProvider = ({ children }: { children: ReactNode }) => { ({ clusters, setClusters }), - [clusters, setClusters], + [clusters, setClusters] )} > {children} diff --git a/src/apps/console/routes/_main+/$account+/env+/$environment+/_layout.tsx b/src/apps/console/routes/_main+/$account+/env+/$environment+/_layout.tsx index 7f1ec3995..f1f694714 100644 --- a/src/apps/console/routes/_main+/$account+/env+/$environment+/_layout.tsx +++ b/src/apps/console/routes/_main+/$account+/env+/$environment+/_layout.tsx @@ -1,10 +1,3 @@ -import { - BackingServices, - CirclesFour, - GearSix, - File, - // TreeStructure, -} from '~/console/components/icons'; import { Link, Outlet, @@ -13,20 +6,26 @@ import { useParams, } from '@remix-run/react'; import { useState } from 'react'; +import Breadcrum from '~/console/components/breadcrum'; import { CommonTabs } from '~/console/components/common-navbar-tabs'; +import { + BackingServices, + CirclesFour, + File, + GearSix, +} from '~/console/components/icons'; import HandleScope from '~/console/page-components/handle-environment'; +import { ICluster } from '~/console/server/gql/queries/cluster-queries'; +import { IEnvironment } from '~/console/server/gql/queries/environment-queries'; +import { ILoginUrls, ILogins } from '~/console/server/gql/queries/git-queries'; import { GQLServerHandler } from '~/console/server/gql/saved-queries'; import { parseName } from '~/console/server/r-utils/common'; import { ensureAccountSet } from '~/console/server/utils/auth-utils'; +import { BreadcrumSlash, tabIconSize } from '~/console/utils/commons'; import { SubNavDataProvider } from '~/lib/client/hooks/use-create-subnav-action'; import { IRemixCtx, LoaderResult } from '~/lib/types/common'; -import { BreadcrumSlash, tabIconSize } from '~/console/utils/commons'; -import { IEnvironment } from '~/console/server/gql/queries/environment-queries'; -import { ILoginUrls, ILogins } from '~/console/server/gql/queries/git-queries'; import logger from '~/root/lib/client/helpers/log'; -import Breadcrum from '~/console/components/breadcrum'; import { handleError } from '~/root/lib/utils/common'; -import { ICluster } from '~/console/server/gql/queries/cluster-queries'; import { IAccountContext } from '../../_layout'; const Environment = () => { @@ -65,7 +64,7 @@ const tabs = [ label: ( - Integrated Resources + Imported Managed Resources ), to: '/managed-resources', diff --git a/src/apps/console/routes/_main+/$account+/env+/$environment+/apps/apps-resources-v2.tsx b/src/apps/console/routes/_main+/$account+/env+/$environment+/apps/apps-resources-v2.tsx index e169367d5..e75a9c675 100644 --- a/src/apps/console/routes/_main+/$account+/env+/$environment+/apps/apps-resources-v2.tsx +++ b/src/apps/console/routes/_main+/$account+/env+/$environment+/apps/apps-resources-v2.tsx @@ -25,7 +25,8 @@ import ResourceExtraAction, { IResourceExtraItem, } from '~/console/components/resource-extra-action'; import { SyncStatusV2 } from '~/console/components/sync-status'; -import useClusterStatus from '~/console/hooks/use-cluster-status'; +import { findClusterStatus } from '~/console/hooks/use-cluster-status'; +import { useClusterStatusV2 } from '~/console/hooks/use-cluster-status-v2'; import { useConsoleApi } from '~/console/server/gql/api-provider'; import { IApps } from '~/console/server/gql/queries/app-queries'; import { @@ -240,15 +241,15 @@ const GridView = ({ items = [], onAction: _ }: IResource) => { const ListView = ({ items = [], onAction }: IResource) => { const { environment, account, cluster } = useOutletContext(); - const { findClusterStatus, clusters, loading } = useClusterStatus(); + const { clusters } = useClusterStatusV2(); const [clusterOnlineStatus, setClusterOnlineStatus] = useState< Record >({}); useEffect(() => { const states: Record = {}; - clusters.forEach((c) => { - states[c.metadata.name] = findClusterStatus(c); + Object.entries(clusters).forEach(([key, value]) => { + states[key] = findClusterStatus(value); }); setClusterOnlineStatus(states); }, [clusters]); @@ -329,10 +330,6 @@ const ListView = ({ items = [], onAction }: IResource) => { }, status: { render: () => { - if (loading) { - return null; - } - if (environment.spec?.suspend) { return null; } diff --git a/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/handle-managed-resource-v2.tsx b/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/handle-managed-resource-v2.tsx index 8366869e6..a52e428e2 100644 --- a/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/handle-managed-resource-v2.tsx +++ b/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/handle-managed-resource-v2.tsx @@ -1,30 +1,30 @@ /* eslint-disable react/destructuring-assignment */ +import { useOutletContext, useParams } from '@remix-run/react'; +import { useCallback, useEffect, useState } from 'react'; +import Select from '~/components/atoms/select'; import Popup from '~/components/molecule/popup'; -import { useReload } from '~/root/lib/client/helpers/reloader'; -import useForm, { dummyEvent } from '~/root/lib/client/hooks/use-form'; -import Yup from '~/root/lib/server/helpers/yup'; -import { handleError } from '~/root/lib/utils/common'; +import { toast } from '~/components/molecule/toast'; +import { useMapper } from '~/components/utils'; +import { CopyContentToClipboard } from '~/console/components/common-console-components'; +import { ListItem } from '~/console/components/console-list-components'; +import ListV2 from '~/console/components/listV2'; +import { LoadingPlaceHolder } from '~/console/components/loading'; +import MultiStep, { useMultiStep } from '~/console/components/multi-step'; +import { NameIdView } from '~/console/components/name-id-view'; import { IDialogBase } from '~/console/components/types.d'; +import { useConsoleApi } from '~/console/server/gql/api-provider'; +import { IImportedManagedResources } from '~/console/server/gql/queries/imported-managed-resource-queries'; import { ExtractNodeType, parseName, parseNodes, } from '~/console/server/r-utils/common'; -import Select from '~/components/atoms/select'; -import { useConsoleApi } from '~/console/server/gql/api-provider'; -import { useOutletContext, useParams } from '@remix-run/react'; -import useCustomSwr from '~/root/lib/client/hooks/use-custom-swr'; -import { useMapper } from '~/components/utils'; -import MultiStep, { useMultiStep } from '~/console/components/multi-step'; -import { LoadingPlaceHolder } from '~/console/components/loading'; -import ListV2 from '~/console/components/listV2'; -import { ListItem } from '~/console/components/console-list-components'; -import { CopyContentToClipboard } from '~/console/components/common-console-components'; -import { useCallback, useEffect, useState } from 'react'; -import { toast } from '~/components/molecule/toast'; import { ensureAccountClientSide } from '~/console/server/utils/auth-utils'; -import { NameIdView } from '~/console/components/name-id-view'; -import { IImportedManagedResources } from '~/console/server/gql/queries/imported-managed-resource-queries'; +import { useReload } from '~/root/lib/client/helpers/reloader'; +import useCustomSwr from '~/root/lib/client/hooks/use-custom-swr'; +import useForm, { dummyEvent } from '~/root/lib/client/hooks/use-form'; +import Yup from '~/root/lib/server/helpers/yup'; +import { handleError } from '~/root/lib/utils/common'; import { IEnvironmentContext } from '../_layout'; type BaseType = ExtractNodeType; @@ -90,11 +90,9 @@ const Root = (props: IDialog) => { managedResourceName: '', }, validationSchema: Yup.object({ - managedServiceName: Yup.string().required( - 'integrated service is required' - ), + managedServiceName: Yup.string().required('Managed service is required'), managedResourceName: Yup.string().required( - 'integrated resource name is required' + 'Managed resource name is required' ), }), onSubmit: async (val) => { @@ -113,9 +111,7 @@ const Root = (props: IDialog) => { reloadPage(); resetValues(); toast.success( - `integrated resource ${ - isUpdate ? 'updated' : 'imported' - } successfully` + `Managed resource ${isUpdate ? 'updated' : 'imported'} successfully` ); setVisible(false); } catch (err) { @@ -171,7 +167,7 @@ const Root = (props: IDialog) => {
{ /> [ ...((mresList && mresList.filter((mres) => { @@ -243,7 +239,7 @@ const HandleManagedResourceV2 = (props: IDialog) => { return ( setVisible(v)}> - {isUpdate ? 'Edit External Name' : 'Import Integrated Resource'} + {isUpdate ? 'Edit External Name' : 'Import Managed Resource'} {(!isUpdate || (isUpdate && props.data)) && } diff --git a/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/managed-resources-resource-v2.tsx b/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/managed-resources-resource-v2.tsx index 54a3f506e..4c2bc2ed9 100644 --- a/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/managed-resources-resource-v2.tsx +++ b/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/managed-resources-resource-v2.tsx @@ -16,7 +16,8 @@ import { LockSimple, Trash } from '~/console/components/icons'; import ListGridView from '~/console/components/list-grid-view'; import ListV2 from '~/console/components/listV2'; import ResourceExtraAction from '~/console/components/resource-extra-action'; -import useClusterStatus from '~/console/hooks/use-cluster-status'; +import { findClusterStatus } from '~/console/hooks/use-cluster-status'; +import { useClusterStatusV2 } from '~/console/hooks/use-cluster-status-v2'; import { useConsoleApi } from '~/console/server/gql/api-provider'; import { IImportedManagedResources } from '~/console/server/gql/queries/imported-managed-resource-queries'; import { IMSvTemplates } from '~/console/server/gql/queries/managed-templates-queries'; @@ -33,7 +34,7 @@ import { handleError } from '~/lib/utils/common'; import { IEnvironmentContext } from '../_layout'; import { ViewSecret } from './handle-managed-resource-v2'; -const RESOURCE_NAME = 'integrated resource'; +const RESOURCE_NAME = 'managed resource'; type BaseType = ExtractNodeType; const parseItem = (item: BaseType, templates: IMSvTemplates) => { @@ -69,13 +70,6 @@ const ExtraButton = ({ onAction, item }: IExtraButton) => { return ( , - // type: 'item', - // onClick: () => onAction({ action: 'edit', item }), - // key: 'edit', - // }, { label: 'View Secret', icon: , @@ -141,15 +135,15 @@ const GridView = ({ items = [], onAction, templates }: IResource) => { const ListView = ({ items = [], onAction, templates }: IResource) => { const { cluster } = useOutletContext(); - const { findClusterStatus, clusters, loading } = useClusterStatus(); + const { clusters } = useClusterStatusV2(); const [clusterOnlineStatus, setClusterOnlineStatus] = useState< Record >({}); useEffect(() => { const states: Record = {}; - clusters.forEach((c) => { - states[c.metadata.name] = findClusterStatus(c); + Object.entries(clusters).forEach(([key, value]) => { + states[key] = findClusterStatus(value); }); setClusterOnlineStatus(states); }, [clusters]); @@ -236,10 +230,6 @@ const ListView = ({ items = [], onAction, templates }: IResource) => { }, status: { render: () => { - if (loading) { - return null; - } - if (!isClusterOnline) { return Cluster Offline; } diff --git a/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/route.tsx b/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/route.tsx index 5b2c9115f..2a92143c4 100644 --- a/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/route.tsx +++ b/src/apps/console/routes/_main+/$account+/env+/$environment+/managed-resources/route.tsx @@ -1,21 +1,21 @@ -import { Plus } from '~/console/components/icons'; import { defer } from '@remix-run/node'; import { Link, useLoaderData, useOutletContext } from '@remix-run/react'; +import { useState } from 'react'; +import { Button } from '~/components/atoms/button'; +import { EmptyManagedResourceImage } from '~/console/components/empty-resource-images'; +import { Plus } from '~/console/components/icons'; import { LoadingComp, pWrapper } from '~/console/components/loading-component'; import Wrapper from '~/console/components/wrapper'; +import { IAccountContext } from '~/console/routes/_main+/$account+/_layout'; import { GQLServerHandler } from '~/console/server/gql/saved-queries'; import { parseNodes } from '~/console/server/r-utils/common'; +import { ensureAccountSet } from '~/console/server/utils/auth-utils'; +import { getPagination, getSearch } from '~/console/server/utils/common'; import { IRemixCtx } from '~/lib/types/common'; import fake from '~/root/fake-data-generator/fake'; -import { Button } from '~/components/atoms/button'; -import { useState } from 'react'; -import { IAccountContext } from '~/console/routes/_main+/$account+/_layout'; -import { EmptyManagedResourceImage } from '~/console/components/empty-resource-images'; -import { getPagination, getSearch } from '~/console/server/utils/common'; -import { ensureAccountSet } from '~/console/server/utils/auth-utils'; -import Tools from './tools'; -import ManagedResourceResourcesV2 from './managed-resources-resource-v2'; import HandleManagedResourceV2 from './handle-managed-resource-v2'; +import ManagedResourceResourcesV2 from './managed-resources-resource-v2'; +import Tools from './tools'; export const loader = (ctx: IRemixCtx) => { const { environment } = ctx.params; @@ -59,11 +59,11 @@ const KlOperatorServices = () => { return ( 0 && (
+ ); +}; + +export const handle = ({ + promise: { imagePullSecret, error }, +}: { + promise: any; +}) => { + if (error) { + return {}; + } + + return { + navbar: , + breadcrum: () => , + }; +}; + +export interface IImagePullSecretContext extends IAccountContext { + imagepullsecret: IImagePullSecret; +} + +const IPSOutlet = ({ + imagePullSecret: OImagePullSecret, +}: { + imagePullSecret: IImagePullSecret; +}) => { + const rootContext = useOutletContext(); + + return ( + + ); +}; + +export const loader = async (ctx: IRemixCtx) => { + const promise = pWrapper(async () => { + ensureAccountSet(ctx); + const { imagepullsecret } = ctx.params; + try { + const { data, errors } = await GQLServerHandler( + ctx.request + ).getImagePullSecret({ + name: imagepullsecret, + }); + if (errors) { + throw errors[0]; + } + + return { + imagePullSecret: data, + }; + } catch (err) { + logger.log(err); + + return { + imagePullSecret: {} as IImagePullSecret, + redirect: `../image-pull-secrets`, + }; + } + }); + return defer({ promise: await promise }); +}; + +const ImagePullSecret = () => { + const { promise } = useLoaderData(); + return ( + + {({ imagePullSecret }) => { + return ; + }} + + ); +}; + +export default ImagePullSecret; diff --git a/src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/images-resources.tsx b/src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/images-resources.tsx new file mode 100644 index 000000000..c84643f12 --- /dev/null +++ b/src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/images-resources.tsx @@ -0,0 +1,340 @@ +import { Link, useOutletContext, useParams } from '@remix-run/react'; +import { useState } from 'react'; +import { toast } from '~/components/molecule/toast'; +import { generateKey, titleCase } from '~/components/utils'; +import ConsoleAvatar from '~/console/components/console-avatar'; +import { + ListItem, + ListItemV2, + ListTitle, + ListTitleV2, + listClass, +} from '~/console/components/console-list-components'; +import DeleteDialog from '~/console/components/delete-dialog'; +import Grid from '~/console/components/grid'; +import { Copy, Trash } from '~/console/components/icons'; +import ListGridView from '~/console/components/list-grid-view'; +import ListV2 from '~/console/components/listV2'; +import ResourceExtraAction, { + IResourceExtraItem, +} from '~/console/components/resource-extra-action'; +import { IAccountContext } from '~/console/routes/_main+/$account+/_layout'; +import { useConsoleApi } from '~/console/server/gql/api-provider'; +import { IEnvironments } from '~/console/server/gql/queries/environment-queries'; +import { + ExtractNodeType, + parseName, + parseUpdateOrCreatedBy, + parseUpdateOrCreatedOn, +} from '~/console/server/r-utils/common'; +import { useWatchReload } from '~/lib/client/helpers/socket/useWatch'; +import { useReload } from '~/root/lib/client/helpers/reloader'; +import { handleError } from '~/root/lib/utils/common'; + +const RESOURCE_NAME = 'environment'; +type BaseType = ExtractNodeType; + +const parseItem = (item: BaseType) => { + return { + name: item.displayName, + id: parseName(item), + updateInfo: { + author: `Updated by ${titleCase(parseUpdateOrCreatedBy(item))}`, + time: parseUpdateOrCreatedOn(item), + }, + }; +}; + +type OnAction = ({ + action, + item, +}: { + action: 'clone' | 'delete' | 'suspend' | 'resumed'; + item: BaseType; +}) => void; + +type IExtraButton = { + onAction: OnAction; + item: BaseType; +}; + +const ExtraButton = ({ item, onAction }: IExtraButton) => { + const iconSize = 16; + const options: IResourceExtraItem[] = [ + { + label: 'Clone', + icon: , + type: 'item', + key: 'clone', + onClick: () => onAction({ action: 'clone', item }), + }, + { + label: 'Delete', + icon: , + type: 'item', + onClick: () => onAction({ action: 'delete', item }), + key: 'delete', + className: '!text-text-critical', + }, + ]; + + return ; +}; + +interface IResource { + items: (BaseType & { isClusterOnline: boolean })[]; + onAction: OnAction; +} + +const GridView = ({ items = [], onAction }: IResource) => { + const { account } = useParams(); + return ( + + {items.map((item, index) => { + const { name, id, updateInfo } = parseItem(item); + const keyPrefix = `${RESOURCE_NAME}-${id}-${index}`; + return ( + ( + } + avatar={} + /> + ), + }, + { + key: generateKey(keyPrefix, updateInfo.author), + className: listClass.author, + render: () => ( + + ), + }, + ]} + /> + ); + })} + + ); +}; + +const ListView = ({ items, onAction }: IResource) => { + const { account } = useParams(); + // const { clusters } = useClusterStatusV2(); + + // const [clusterOnlineStatus, setClusterOnlineStatus] = useState< + // Record + // >({}); + // useEffect(() => { + // const states: Record = {}; + // Object.entries(clusters).forEach(([key, value]) => { + // states[key] = findClusterStatus(value); + // }); + // setClusterOnlineStatus(states); + // }, [clusters]); + + return ( + 'Resource Name', + name: 'name', + className: listClass.title, + }, + { + render: () => 'Cluster', + name: 'cluster', + className: listClass.item, + }, + { + render: () => '', + name: 'flex-post', + className: listClass.flex, + }, + // { + // render: () => 'Status', + // name: 'status', + // className: listClass.status, + // }, + { + render: () => 'Updated', + name: 'updated', + className: listClass.updated, + }, + { + render: () => '', + name: 'action', + className: listClass.action, + }, + ], + rows: items.map((i) => { + const { name, id, updateInfo } = parseItem(i); + // const isClusterOnline = clusterOnlineStatus[i.clusterName]; + + return { + columns: { + name: { + render: () => ( + } + /> + ), + }, + cluster: { + render: () => ( + + ), + }, + // status: { + // render: () => { + // if (i.isArchived) { + // return Archived; + // } + + // if (!isClusterOnline) { + // return Cluster Offline; + // } + + // if (i.spec?.suspend) { + // return Suspended; + // } + + // return ; + // }, + // }, + updated: { + render: () => ( + + ), + }, + action: { + render: () => , + }, + }, + ...(i.isArchived ? {} : { to: `/${account}/env/${id}` }), + }; + }), + }} + /> + ); +}; + +const ImagesResource = ({ items = [] }: { items: BaseType[] }) => { + const { account } = useOutletContext(); + const api = useConsoleApi(); + const reloadPage = useReload(); + useWatchReload( + items.map((i) => { + return `account:${parseName(account)}.environment:${parseName(i)}`; + }) + ); + + const suspendEnvironment = async (item: BaseType, suspend: boolean) => { + try { + const { errors } = await api.updateEnvironment({ + env: { + displayName: item.displayName, + clusterName: item.clusterName, + metadata: { + name: parseName(item), + }, + spec: { + suspend, + }, + }, + }); + + if (errors) { + throw errors[0]; + } + toast.success( + `${ + suspend + ? 'Environment suspended successfully' + : 'Environment resumed successfully' + }` + ); + reloadPage(); + } catch (err) { + handleError(err); + } + }; + + const [showDeleteDialog, setShowDeleteDialog] = useState( + null + ); + const [visible, setVisible] = useState(null); + + const props: IResource = { + // @ts-ignore + items, + onAction: ({ action, item }) => { + switch (action) { + case 'clone': + setVisible(item); + break; + case 'suspend': + suspendEnvironment(item, true); + break; + case 'resumed': + suspendEnvironment(item, false); + break; + case 'delete': + setShowDeleteDialog(item); + break; + default: + break; + } + }, + }; + + return ( + <> + } + gridView={} + /> + { + try { + const { errors } = await api.deleteEnvironment({ + envName: parseName(showDeleteDialog), + }); + + if (errors) { + throw errors[0]; + } + reloadPage(); + toast.success(`Environment deleted successfully`); + setShowDeleteDialog(null); + } catch (err) { + handleError(err); + } + }} + /> + + ); +}; + +export default ImagesResource; diff --git a/src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/route.tsx b/src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/route.tsx new file mode 100644 index 000000000..48c8803ee --- /dev/null +++ b/src/apps/console/routes/_main+/$account+/settings+/ips+/$imagepullsecret+/images/route.tsx @@ -0,0 +1,92 @@ +import { defer } from '@remix-run/node'; +import { Link, useLoaderData } from '@remix-run/react'; +import { Button } from '~/components/atoms/button'; +import { EmptyManagedResourceImage } from '~/console/components/empty-resource-images'; +import { Plus } from '~/console/components/icons'; +import { LoadingComp, pWrapper } from '~/console/components/loading-component'; +import Wrapper from '~/console/components/wrapper'; +import { GQLServerHandler } from '~/console/server/gql/saved-queries'; +import { parseNodes } from '~/console/server/r-utils/common'; +import { ensureAccountSet } from '~/console/server/utils/auth-utils'; +import { getPagination, getSearch } from '~/console/server/utils/common'; +import { IRemixCtx } from '~/lib/types/common'; +import ImagesResource from './images-resources'; +import Tools from './tools'; + +export const loader = (ctx: IRemixCtx) => { + const { imagepullsecret } = ctx.params; + console.log('====>>>>', imagepullsecret); + const promise = pWrapper(async () => { + ensureAccountSet(ctx); + + const { data, errors } = await GQLServerHandler( + ctx.request + ).listEnvironments({ + pq: getPagination(ctx), + search: getSearch(ctx), + }); + + if (errors) { + throw errors[0]; + } + return { imagesData: data }; + }); + return defer({ promise }); +}; + +const Images = () => { + const { promise } = useLoaderData(); + return ( + + {({ imagesData }) => { + const images = parseNodes(imagesData); + + return ( + 0 && ( +