From 7a77ac9dcec9e7b428cb29ef5b52bec0f62bf0da Mon Sep 17 00:00:00 2001 From: warjiang <1096409085@qq.com> Date: Wed, 16 Oct 2024 14:11:32 +0800 Subject: [PATCH 1/3] feat: add api invoke for service in frontend Signed-off-by: warjiang <1096409085@qq.com> --- ui/apps/dashboard/src/services/service.ts | 105 ++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 ui/apps/dashboard/src/services/service.ts diff --git a/ui/apps/dashboard/src/services/service.ts b/ui/apps/dashboard/src/services/service.ts new file mode 100644 index 0000000..eb8db94 --- /dev/null +++ b/ui/apps/dashboard/src/services/service.ts @@ -0,0 +1,105 @@ +import { + convertDataSelectQuery, + DataSelectQuery, + IResponse, + karmadaClient, + ObjectMeta, + Selector, + TypeMeta, +} from '@/services/base.ts'; + +export enum Protocol { + TCP = 'TCP', + UDP = 'UDP', + SCTP = 'SCTP', +} + +export enum ServiceType { + ClusterIP = 'ClusterIP', + NodePort = 'NodePort', + LoadBalancer = 'LoadBalancer', + ExternalName = 'ExternalName', +} + +export interface ServicePort { + port: number; + protocol: Protocol; + nodePort: number; +} + +export interface Endpoint { + host: string; + ports: ServicePort[]; +} + +export interface Service { + objectMeta: ObjectMeta; + typeMeta: TypeMeta; + internalEndpoint: Endpoint; + externalEndpoints: Endpoint[]; + selector: Selector; + type: ServiceType; + clusterIP: string; +} + +export async function GetServices(params: { + namespace?: string; + keyword?: string; +}) { + const { namespace, keyword } = params; + const url = namespace ? `/service/${namespace}` : `/service`; + const requestData = {} as DataSelectQuery; + if (keyword) { + requestData.filterBy = ['name', keyword]; + } + const resp = await karmadaClient.get< + IResponse<{ + errors: string[]; + listMeta: { + totalItems: number; + }; + services: Service[]; + }> + >(url, { + params: convertDataSelectQuery(requestData), + }); + return resp.data; +} + +export interface Ingress { + objectMeta: ObjectMeta; + typeMeta: TypeMeta; + selector: Selector; +} +export async function GetIngress(params: { + namespace?: string; + keyword?: string; +}) { + const { namespace, keyword } = params; + const url = namespace ? `/ingress/${namespace}` : `/ingress`; + const requestData = {} as DataSelectQuery; + if (keyword) { + requestData.filterBy = ['name', keyword]; + } + const resp = await karmadaClient.get< + IResponse<{ + errors: string[]; + listMeta: { + totalItems: number; + }; + services: Ingress[]; + }> + >(url, { + params: convertDataSelectQuery(requestData), + }); + return resp.data; +} + +export const propagationpolicyKey = 'propagationpolicy.karmada.io/name'; +// safely extract propagationpolicy +export const extractPropagationPolicy = (r: { objectMeta: ObjectMeta }) => { + if (!r?.objectMeta?.annotations?.[propagationpolicyKey]) { + return ''; + } + return r?.objectMeta?.annotations?.[propagationpolicyKey]; +}; From 213e49c5b3fd3bf45f723abcffbbbc9961312353 Mon Sep 17 00:00:00 2001 From: warjiang <1096409085@qq.com> Date: Wed, 16 Oct 2024 14:12:16 +0800 Subject: [PATCH 2/3] feat: implement ui for service Signed-off-by: warjiang <1096409085@qq.com> --- .../service/components/ingress-table.tsx | 146 ++++++++++++++ .../components/service-editor-modal.tsx | 97 +++++++++ .../service/components/service-table.tsx | 146 ++++++++++++++ .../service/index.tsx | 186 +++++++++++++++++- ui/apps/dashboard/src/services/base.ts | 6 + 5 files changed, 576 insertions(+), 5 deletions(-) create mode 100644 ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/ingress-table.tsx create mode 100644 ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx create mode 100644 ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-table.tsx diff --git a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/ingress-table.tsx b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/ingress-table.tsx new file mode 100644 index 0000000..4cb15df --- /dev/null +++ b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/ingress-table.tsx @@ -0,0 +1,146 @@ +import {Button, Popconfirm, Space, Table, TableColumnProps, Tag} from "antd"; +import {extractPropagationPolicy, GetIngress, Ingress} from "@/services/service.ts"; +import i18nInstance from "@/utils/i18n.tsx"; +import TagList from "@/components/tag-list"; +import {FC} from "react"; +import {useQuery} from "@tanstack/react-query"; +import {GetResource} from "@/services/unstructured.ts"; + +interface ServiceTableProps { + labelTagNum?: number + selectedWorkSpace: string; + searchText: string; + onViewIngressContent: (r:any) => void + onDeleteIngressContent: (r:Ingress) => void +} + +const IngressTable: FC = (props) => { + const { + labelTagNum, selectedWorkSpace, searchText, + onViewIngressContent, onDeleteIngressContent} = props + const columns: TableColumnProps[] = [ + { + title: i18nInstance.t('a4b28a416f0b6f3c215c51e79e517298'), + key: 'namespaceName', + width: 200, + render: (_, r) => { + return r.objectMeta.namespace; + }, + }, + { + title: '名称', + key: 'ingressName', + width: 300, + render: (_, r) => { + return r.objectMeta.name; + }, + }, + { + title: i18nInstance.t('1f7be0a924280cd098db93c9d81ecccd'), + key: 'labelName', + align: 'left', + width: '30%', + render: (_, r) => { + if (!r?.objectMeta?.labels) { + return '-'; + } + const params = Object.keys(r.objectMeta.labels).map((key) => { + return { + key: `${r.objectMeta.name}-${key}`, + value: `${key}:${r.objectMeta.labels[key]}`, + }; + }); + return ( + + ); + }, + }, + { + title: i18nInstance.t('8a99082b2c32c843d2241e0ba60a3619'), + key: 'propagationPolicies', + render: (_, r) => { + const pp = extractPropagationPolicy(r) + return pp ? {pp}: '-'; + }, + }, + { + title: i18nInstance.t('eaf8a02d1b16fcf94302927094af921f'), + key: 'overridePolicies', + width: 150, + render: () => { + return '-'; + }, + }, + { + title: i18nInstance.t('2b6bc0f293f5ca01b006206c2535ccbc'), + key: 'op', + width: 200, + render: (_, r) => { + return ( + + + + + { + + }} + okText={i18nInstance.t('e83a256e4f5bb4ff8b3d804b5473217a')} + cancelText={i18nInstance.t('625fb26b4b3340f7872b411f401e754c')} + > + + + + ); + }, + }, + ]; + const {data, isLoading} = useQuery({ + queryKey: ['GetServices', selectedWorkSpace, searchText], + queryFn: async () => { + const services = await GetIngress({ + namespace: selectedWorkSpace, + keyword: searchText, + }); + return services.data || {}; + }, + }); + return ( + `${r.objectMeta.namespace}-${r.objectMeta.name}` || ''} + columns={columns} + loading={isLoading} + dataSource={data?.services || []} + /> + ) +} + +export default IngressTable; \ No newline at end of file diff --git a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx new file mode 100644 index 0000000..8f24068 --- /dev/null +++ b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx @@ -0,0 +1,97 @@ +import i18nInstance from '@/utils/i18n'; +import { FC, useEffect, useState } from 'react'; +import { Modal } from 'antd'; +import Editor from '@monaco-editor/react'; +import { parse, stringify } from 'yaml'; +import _ from 'lodash'; +import { PutResource } from '@/services/unstructured'; +import { CreateDeployment } from '@/services/workload'; +import { IResponse } from '@/services/base.ts'; + +export interface NewWorkloadEditorModalProps { + mode: 'create' | 'edit'; + open: boolean; + serviceContent?: string; + onOk: (ret: IResponse) => (Promise | void); + onCancel: () => Promise | void; +} + +const ServiceEditorModal: FC = (props) => { + const { mode, open, serviceContent = '', onOk, onCancel } = props; + const [content, setContent] = useState(serviceContent); + useEffect(() => { + console.log('workloadContent', serviceContent); + setContent(serviceContent); + }, [serviceContent]); + + function handleEditorChange( + value: string | undefined, + ) { + setContent(value || ''); + } + return ( + { + // await onOk() + try { + const yamlObject = parse(content) as Record; + const kind = _.get(yamlObject, 'kind'); + const namespace = _.get(yamlObject, 'metadata.namespace'); + const name = _.get(yamlObject, 'metadata.name'); + if (mode === 'create') { + if (kind.toLowerCase() === 'deployment') { + const ret = await CreateDeployment({ + namespace, + name, + content: stringify(yamlObject), + }); + await onOk(ret); + setContent(''); + } + } else { + const ret = await PutResource({ + kind, + name, + namespace, + content: yamlObject, + }); + await onOk(ret); + setContent(''); + } + } catch (e) { + console.log('e', e); + } + }} + onCancel={async () => { + await onCancel(); + setContent(''); + }} + > + + + ); +}; +export default ServiceEditorModal; diff --git a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-table.tsx b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-table.tsx new file mode 100644 index 0000000..ff9d168 --- /dev/null +++ b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-table.tsx @@ -0,0 +1,146 @@ +import {Button, Popconfirm, Space, Table, TableColumnProps, Tag} from "antd"; +import {extractPropagationPolicy, GetServices, Service} from "@/services/service.ts"; +import i18nInstance from "@/utils/i18n.tsx"; +import TagList from "@/components/tag-list"; +import {FC} from "react"; +import {useQuery} from "@tanstack/react-query"; +import {GetResource} from "@/services/unstructured.ts"; + +interface ServiceTableProps { + labelTagNum?: number + selectedWorkSpace: string; + searchText: string; + onViewServiceContent: (r:any) => void + onDeleteServiceContent: (r:Service) => void +} + +const ServiceTable: FC = (props) => { + const { + labelTagNum, selectedWorkSpace, searchText, + onViewServiceContent, onDeleteServiceContent} = props + const columns: TableColumnProps[] = [ + { + title: i18nInstance.t('a4b28a416f0b6f3c215c51e79e517298'), + key: 'namespaceName', + width: 200, + render: (_, r) => { + return r.objectMeta.namespace; + }, + }, + { + title: '服务名称', + key: 'servicename', + width: 300, + render: (_, r) => { + return r.objectMeta.name; + }, + }, + { + title: i18nInstance.t('1f7be0a924280cd098db93c9d81ecccd'), + key: 'labelName', + align: 'left', + width: '30%', + render: (_, r) => { + if (!r?.objectMeta?.labels) { + return '-'; + } + const params = Object.keys(r.objectMeta.labels).map((key) => { + return { + key: `${r.objectMeta.name}-${key}`, + value: `${key}:${r.objectMeta.labels[key]}`, + }; + }); + return ( + + ); + }, + }, + { + title: i18nInstance.t('8a99082b2c32c843d2241e0ba60a3619'), + key: 'propagationPolicies', + render: (_, r) => { + const pp = extractPropagationPolicy(r) + return pp ? {pp}: '-'; + }, + }, + { + title: i18nInstance.t('eaf8a02d1b16fcf94302927094af921f'), + key: 'overridePolicies', + width: 150, + render: () => { + return '-'; + }, + }, + { + title: i18nInstance.t('2b6bc0f293f5ca01b006206c2535ccbc'), + key: 'op', + width: 200, + render: (_, r) => { + return ( + + + + + { + + }} + okText={i18nInstance.t('e83a256e4f5bb4ff8b3d804b5473217a')} + cancelText={i18nInstance.t('625fb26b4b3340f7872b411f401e754c')} + > + + + + ); + }, + }, + ]; + const {data, isLoading} = useQuery({ + queryKey: ['GetServices', selectedWorkSpace, searchText], + queryFn: async () => { + const services = await GetServices({ + namespace: selectedWorkSpace, + keyword: searchText, + }); + return services.data || {}; + }, + }); + return ( +
`${r.objectMeta.namespace}-${r.objectMeta.name}` || ''} + columns={columns} + loading={isLoading} + dataSource={data?.services || []} + /> + ) +} + +export default ServiceTable; \ No newline at end of file diff --git a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx index 27cb297..dd990d6 100644 --- a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx +++ b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx @@ -1,10 +1,186 @@ import Panel from '@/components/panel'; +import {Button, Input, Segmented, Select} from "antd"; +import {ServiceKind} from "@/services/base"; +import {Icons} from "@/components/icons"; +import {useQuery} from "@tanstack/react-query"; +import {GetNamespaces} from "@/services/namespace"; +import {useCallback, useMemo, useState} from "react"; +import {useToggle, useWindowSize} from "@uidotdev/usehooks"; +import ServiceTable from './components/service-table' +import ServiceEditorModal from './components/service-editor-modal' +import i18nInstance from "@/utils/i18n.tsx"; +import {stringify} from "yaml"; +import IngressTable from "@/pages/multicloud-resource-manage/service/components/ingress-table"; + const ServicePage = () => { - return ( - -

this is ServicePage

-
- ); + const [filter, setFilter] = useState<{ + selectedWorkSpace: string; + searchText: string; + kind: ServiceKind, + }>({ + selectedWorkSpace: '', + searchText: '', + kind: ServiceKind.Service + + }); + const {data: nsData, isLoading: isNsDataLoading} = useQuery({ + queryKey: ['GetNamespaces'], + queryFn: async () => { + const clusters = await GetNamespaces({}); + return clusters.data || {}; + }, + }); + const nsOptions = useMemo(() => { + if (!nsData?.namespaces) return []; + return nsData.namespaces.map((item) => { + return { + title: item.objectMeta.name, + value: item.objectMeta.name, + }; + }); + }, [nsData]); + + const size = useWindowSize(); + const labelTagNum = size && size.width! > 1800 ? undefined : 1 + const [editorState, setEditorState] = useState<{ + mode: 'create' | 'edit'; + content: string; + }>({ + mode: 'create', + content: '', + }); + const [showModal, toggleShowModal] = useToggle(false); + const resetEditorState = useCallback(() => { + setEditorState({ + mode: 'create', + content: '', + }); + }, []); + return ( + +
+
+ { + // reset filter when switch workload kind + if (value !== filter.kind) { + setFilter({ + ...filter, + kind: value, + selectedWorkSpace: '', + searchText: '', + }); + } else { + setFilter({ + ...filter, + kind: value, + }); + } + }} + /> +
+ +
+
+

+ {i18nInstance.t('280c56077360c204e536eb770495bc5f')} +

+
`${r.objectMeta.namespace}-${r.objectMeta.name}` || ''} - columns={columns} - loading={isLoading} - dataSource={data?.services || []} - /> - ) -} + onViewIngressContent(ret?.data); + }} + > + {i18nInstance.t('607e7a4f377fa66b0b28ce318aab841f')} + + -export default IngressTable; \ No newline at end of file + {}} + okText={i18nInstance.t('e83a256e4f5bb4ff8b3d804b5473217a')} + cancelText={i18nInstance.t('625fb26b4b3340f7872b411f401e754c')} + > + + + + ); + }, + }, + ]; + const { data, isLoading } = useQuery({ + queryKey: ['GetServices', selectedWorkSpace, searchText], + queryFn: async () => { + const services = await GetIngress({ + namespace: selectedWorkSpace, + keyword: searchText, + }); + return services.data || {}; + }, + }); + return ( +
+ `${r.objectMeta.namespace}-${r.objectMeta.name}` || '' + } + columns={columns} + loading={isLoading} + dataSource={data?.services || []} + /> + ); +}; +export default IngressTable; diff --git a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx index 8f24068..ea4c0f8 100644 --- a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx +++ b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/components/service-editor-modal.tsx @@ -7,15 +7,13 @@ import _ from 'lodash'; import { PutResource } from '@/services/unstructured'; import { CreateDeployment } from '@/services/workload'; import { IResponse } from '@/services/base.ts'; - export interface NewWorkloadEditorModalProps { mode: 'create' | 'edit'; open: boolean; serviceContent?: string; - onOk: (ret: IResponse) => (Promise | void); + onOk: (ret: IResponse) => Promise | void; onCancel: () => Promise | void; } - const ServiceEditorModal: FC = (props) => { const { mode, open, serviceContent = '', onOk, onCancel } = props; const [content, setContent] = useState(serviceContent); @@ -23,19 +21,12 @@ const ServiceEditorModal: FC = (props) => { console.log('workloadContent', serviceContent); setContent(serviceContent); }, [serviceContent]); - - function handleEditorChange( - value: string | undefined, - ) { + function handleEditorChange(value: string | undefined) { setContent(value || ''); } return ( void - onDeleteServiceContent: (r:Service) => void + labelTagNum?: number; + selectedWorkSpace: string; + searchText: string; + onViewServiceContent: (r: any) => void; + onDeleteServiceContent: (r: Service) => void; } - const ServiceTable: FC = (props) => { - const { - labelTagNum, selectedWorkSpace, searchText, - onViewServiceContent, onDeleteServiceContent} = props - const columns: TableColumnProps[] = [ - { - title: i18nInstance.t('a4b28a416f0b6f3c215c51e79e517298'), - key: 'namespaceName', - width: 200, - render: (_, r) => { - return r.objectMeta.namespace; - }, - }, - { - title: '服务名称', - key: 'servicename', - width: 300, - render: (_, r) => { - return r.objectMeta.name; - }, - }, - { - title: i18nInstance.t('1f7be0a924280cd098db93c9d81ecccd'), - key: 'labelName', - align: 'left', - width: '30%', - render: (_, r) => { - if (!r?.objectMeta?.labels) { - return '-'; - } - const params = Object.keys(r.objectMeta.labels).map((key) => { - return { - key: `${r.objectMeta.name}-${key}`, - value: `${key}:${r.objectMeta.labels[key]}`, - }; + const { + labelTagNum, + selectedWorkSpace, + searchText, + onViewServiceContent, + onDeleteServiceContent, + } = props; + const columns: TableColumnProps[] = [ + { + title: i18nInstance.t('a4b28a416f0b6f3c215c51e79e517298'), + key: 'namespaceName', + width: 200, + render: (_, r) => { + return r.objectMeta.namespace; + }, + }, + { + title: i18nInstance.t('8f3747c057d893862fbe4b7980e9b451', '服务名称'), + key: 'servicename', + width: 300, + render: (_, r) => { + return r.objectMeta.name; + }, + }, + { + title: i18nInstance.t('1f7be0a924280cd098db93c9d81ecccd'), + key: 'labelName', + align: 'left', + width: '30%', + render: (_, r) => { + if (!r?.objectMeta?.labels) { + return '-'; + } + const params = Object.keys(r.objectMeta.labels).map((key) => { + return { + key: `${r.objectMeta.name}-${key}`, + value: `${key}:${r.objectMeta.labels[key]}`, + }; + }); + return ; + }, + }, + { + title: i18nInstance.t('8a99082b2c32c843d2241e0ba60a3619'), + key: 'propagationPolicies', + render: (_, r) => { + const pp = extractPropagationPolicy(r); + return pp ? {pp} : '-'; + }, + }, + { + title: i18nInstance.t('eaf8a02d1b16fcf94302927094af921f'), + key: 'overridePolicies', + width: 150, + render: () => { + return '-'; + }, + }, + { + title: i18nInstance.t('2b6bc0f293f5ca01b006206c2535ccbc'), + key: 'op', + width: 200, + render: (_, r) => { + return ( + + - - - { - - }} - okText={i18nInstance.t('e83a256e4f5bb4ff8b3d804b5473217a')} - cancelText={i18nInstance.t('625fb26b4b3340f7872b411f401e754c')} - > - - - - ); - }, - }, - ]; - const {data, isLoading} = useQuery({ - queryKey: ['GetServices', selectedWorkSpace, searchText], - queryFn: async () => { - const services = await GetServices({ - namespace: selectedWorkSpace, - keyword: searchText, - }); - return services.data || {}; - }, - }); - return ( -
`${r.objectMeta.namespace}-${r.objectMeta.name}` || ''} - columns={columns} - loading={isLoading} - dataSource={data?.services || []} - /> - ) -} + onViewServiceContent(ret?.data); + }} + > + {i18nInstance.t('607e7a4f377fa66b0b28ce318aab841f')} + + -export default ServiceTable; \ No newline at end of file + {}} + okText={i18nInstance.t('e83a256e4f5bb4ff8b3d804b5473217a')} + cancelText={i18nInstance.t('625fb26b4b3340f7872b411f401e754c')} + > + + + + ); + }, + }, + ]; + const { data, isLoading } = useQuery({ + queryKey: ['GetServices', selectedWorkSpace, searchText], + queryFn: async () => { + const services = await GetServices({ + namespace: selectedWorkSpace, + keyword: searchText, + }); + return services.data || {}; + }, + }); + return ( +
+ `${r.objectMeta.namespace}-${r.objectMeta.name}` || '' + } + columns={columns} + loading={isLoading} + dataSource={data?.services || []} + /> + ); +}; +export default ServiceTable; diff --git a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx index dd990d6..b0921e4 100644 --- a/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx +++ b/ui/apps/dashboard/src/pages/multicloud-resource-manage/service/index.tsx @@ -1,186 +1,180 @@ +import i18nInstance from '@/utils/i18n'; import Panel from '@/components/panel'; -import {Button, Input, Segmented, Select} from "antd"; -import {ServiceKind} from "@/services/base"; -import {Icons} from "@/components/icons"; -import {useQuery} from "@tanstack/react-query"; -import {GetNamespaces} from "@/services/namespace"; -import {useCallback, useMemo, useState} from "react"; -import {useToggle, useWindowSize} from "@uidotdev/usehooks"; -import ServiceTable from './components/service-table' -import ServiceEditorModal from './components/service-editor-modal' -import i18nInstance from "@/utils/i18n.tsx"; -import {stringify} from "yaml"; -import IngressTable from "@/pages/multicloud-resource-manage/service/components/ingress-table"; - +import { Button, Input, Segmented, Select } from 'antd'; +import { ServiceKind } from '@/services/base'; +import { Icons } from '@/components/icons'; +import { useQuery } from '@tanstack/react-query'; +import { GetNamespaces } from '@/services/namespace'; +import { useCallback, useMemo, useState } from 'react'; +import { useToggle, useWindowSize } from '@uidotdev/usehooks'; +import ServiceTable from './components/service-table'; +import ServiceEditorModal from './components/service-editor-modal'; +import { stringify } from 'yaml'; +import IngressTable from '@/pages/multicloud-resource-manage/service/components/ingress-table'; const ServicePage = () => { - const [filter, setFilter] = useState<{ - selectedWorkSpace: string; - searchText: string; - kind: ServiceKind, - }>({ - selectedWorkSpace: '', - searchText: '', - kind: ServiceKind.Service - + const [filter, setFilter] = useState<{ + selectedWorkSpace: string; + searchText: string; + kind: ServiceKind; + }>({ + selectedWorkSpace: '', + searchText: '', + kind: ServiceKind.Service, + }); + const { data: nsData, isLoading: isNsDataLoading } = useQuery({ + queryKey: ['GetNamespaces'], + queryFn: async () => { + const clusters = await GetNamespaces({}); + return clusters.data || {}; + }, + }); + const nsOptions = useMemo(() => { + if (!nsData?.namespaces) return []; + return nsData.namespaces.map((item) => { + return { + title: item.objectMeta.name, + value: item.objectMeta.name, + }; }); - const {data: nsData, isLoading: isNsDataLoading} = useQuery({ - queryKey: ['GetNamespaces'], - queryFn: async () => { - const clusters = await GetNamespaces({}); - return clusters.data || {}; - }, - }); - const nsOptions = useMemo(() => { - if (!nsData?.namespaces) return []; - return nsData.namespaces.map((item) => { - return { - title: item.objectMeta.name, - value: item.objectMeta.name, - }; - }); - }, [nsData]); - - const size = useWindowSize(); - const labelTagNum = size && size.width! > 1800 ? undefined : 1 - const [editorState, setEditorState] = useState<{ - mode: 'create' | 'edit'; - content: string; - }>({ - mode: 'create', - content: '', + }, [nsData]); + const size = useWindowSize(); + const labelTagNum = size && size.width! > 1800 ? undefined : 1; + const [editorState, setEditorState] = useState<{ + mode: 'create' | 'edit'; + content: string; + }>({ + mode: 'create', + content: '', + }); + const [showModal, toggleShowModal] = useToggle(false); + const resetEditorState = useCallback(() => { + setEditorState({ + mode: 'create', + content: '', }); - const [showModal, toggleShowModal] = useToggle(false); - const resetEditorState = useCallback(() => { - setEditorState({ - mode: 'create', - content: '', - }); - }, []); - return ( - -
-
- { - // reset filter when switch workload kind - if (value !== filter.kind) { - setFilter({ - ...filter, - kind: value, - selectedWorkSpace: '', - searchText: '', - }); - } else { - setFilter({ - ...filter, - kind: value, - }); - } - }} - /> -
- -
-
-

- {i18nInstance.t('280c56077360c204e536eb770495bc5f')} -

- { + setFilter({ + ...filter, + selectedWorkSpace: v, + }); + }} + /> + { + const input = e.currentTarget.value; + setFilter({ + ...filter, + searchText: input, + }); + }} + /> +
+ {filter.kind === ServiceKind.Service && ( + { + setEditorState({ + mode: 'edit', + content: stringify(r), + }); + toggleShowModal(true); + }} + onDeleteServiceContent={() => {}} + /> + )} + {filter.kind === ServiceKind.Ingress && ( + { + setEditorState({ + mode: 'edit', + content: stringify(r), + }); + toggleShowModal(true); + }} + onDeleteIngressContent={() => {}} + /> + )} - }} - /> - } - { - filter.kind === ServiceKind.Ingress && { - setEditorState({ - mode: 'edit', - content: stringify(r), - }); - toggleShowModal(true); - }} - onDeleteIngressContent={() => { - - }} - /> - } - - { - console.log(ret) - }} - onCancel={() => { - resetEditorState(); - toggleShowModal(false); - }} - /> -
- ); + { + console.log(ret); + }} + onCancel={() => { + resetEditorState(); + toggleShowModal(false); + }} + /> + + ); }; - export default ServicePage;