From d5a1a4efd29117c6219bdf671fa9699966add471 Mon Sep 17 00:00:00 2001 From: John Kim Date: Fri, 4 Oct 2024 15:15:18 -0400 Subject: [PATCH 1/4] feat: global Config Policies UI --- .../src/components/ConfigPolicies.test.tsx | 2 +- webui/react/src/components/ConfigPolicies.tsx | 132 ++++++++++++------ .../src/components/NavigationSideBar.tsx | 10 +- webui/react/src/hooks/usePermissions.ts | 25 ++++ webui/react/src/pages/ConfigPoliciesPage.tsx | 26 ++++ webui/react/src/routes/index.tsx | 2 + webui/react/src/routes/routes.ts | 7 + webui/react/src/routes/utils.ts | 3 + webui/react/src/services/api.ts | 18 +++ webui/react/src/services/apiConfig.ts | 40 ++++++ webui/react/src/services/types.ts | 13 ++ 11 files changed, 236 insertions(+), 42 deletions(-) create mode 100644 webui/react/src/pages/ConfigPoliciesPage.tsx diff --git a/webui/react/src/components/ConfigPolicies.test.tsx b/webui/react/src/components/ConfigPolicies.test.tsx index f96ac7843cf..7c7b8e4c7ee 100644 --- a/webui/react/src/components/ConfigPolicies.test.tsx +++ b/webui/react/src/components/ConfigPolicies.test.tsx @@ -36,7 +36,7 @@ const setup = () => { - + , diff --git a/webui/react/src/components/ConfigPolicies.tsx b/webui/react/src/components/ConfigPolicies.tsx index db34c557e87..73df820a85b 100644 --- a/webui/react/src/components/ConfigPolicies.tsx +++ b/webui/react/src/components/ConfigPolicies.tsx @@ -16,15 +16,20 @@ import { useState } from 'react'; import { useAsync } from 'hooks/useAsync'; import usePermissions from 'hooks/usePermissions'; import { + deleteGlobalConfigPolicies, deleteWorkspaceConfigPolicies, + getGlobalConfigPolicies, getWorkspaceConfigPolicies, + updateGlobalConfigPolicies, updateWorkspaceConfigPolicies, } from 'services/api'; +import { XOR } from 'types'; import handleError from 'utils/error'; -interface Props { - workspaceId?: number; -} +type Props = XOR< + { workspaceId: number }, + { global: true } +>; type ConfigPoliciesType = 'experiments' | 'tasks'; @@ -44,47 +49,86 @@ const ConfigPoliciesValues: Record = { }, }; -interface TabProps { - workspaceId?: number; +type TabProps = Props & { type: ConfigPoliciesType; } type FormInputs = { - configPolicies: string; + [YAML_FORM_ITEM_NAME]: string; }; -const ConfigPolicies: React.FC = ({ workspaceId }: Props) => { - const tabItems: PivotProps['items'] = [ - { - children: , - key: 'experiments', - label: ConfigPoliciesValues.experiments.label, - }, - { - children: , - key: 'tasks', - label: ConfigPoliciesValues.tasks.label, - }, - ]; +const SUCCESS_MESSAGE = 'Config policies updated.'; +const YAML_FORM_ITEM_NAME = 'configPolicies'; + +const ConfigPolicies: React.FC = ({ workspaceId, global }: Props) => { + let tabItems: PivotProps['items']; + if (global) { + tabItems = [ + { + children: , + key: 'experiments', + label: ConfigPoliciesValues.experiments.label, + }, + { + children: , + key: 'tasks', + label: ConfigPoliciesValues.tasks.label, + }, + ]; + } else if (workspaceId) { + tabItems = [ + { + children: , + key: 'experiments', + label: ConfigPoliciesValues.experiments.label, + }, + { + children: , + key: 'tasks', + label: ConfigPoliciesValues.tasks.label, + }, + ]; + } return ; }; -const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps) => { +const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: TabProps) => { const confirm = useConfirm(); const { openToast } = useToast(); - const { canModifyWorkspaceConfigPolicies, loading: rbacLoading } = usePermissions(); + const { canModifyWorkspaceConfigPolicies, canModifyGlobalConfigPolicies, loading: rbacLoading } = usePermissions(); const [form] = Form.useForm(); const [disabled, setDisabled] = useState(true); - const APPLY_MESSAGE = "You're about to apply these config policies to this workspace."; - const VIEW_MESSAGE = 'An admin applied these config policies to this workspace.'; - const CONFIRMATION_MESSAGE = 'Config policies updated'; + const applyMessage = global ? "You're about to apply these config policies to this cluster." : "You're about to apply these config policies to this workspace."; + const viewMessage = global ? 'These global config policies are being applied to this cluster.' : 'These global config policies are being applied to this workspace.'; + const confirmMessageEnding = global ? 'underlying workspaces, projects, and submitted experiments in this cluster.' : 'underlying projects and their experiments in this workspace.'; const updatePolicies = async () => { - if (workspaceId) { - const configPolicies = form.getFieldValue('configPolicies'); + const configPolicies = form.getFieldValue(YAML_FORM_ITEM_NAME); + if (global) { + if (configPolicies.length) { + try { + await updateGlobalConfigPolicies({ + configPolicies, + workloadType: ConfigPoliciesValues[type].workloadType, + }); + openToast({ title: SUCCESS_MESSAGE }); + } catch (error) { + handleError(error); + } + } else { + try { + await deleteGlobalConfigPolicies({ + workloadType: ConfigPoliciesValues[type].workloadType, + }); + openToast({ title: SUCCESS_MESSAGE }); + } catch (error) { + handleError(error); + } + } + } else if (workspaceId) { if (configPolicies.length) { try { await updateWorkspaceConfigPolicies({ @@ -92,7 +136,7 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps) workloadType: ConfigPoliciesValues[type].workloadType, workspaceId, }); - openToast({ title: CONFIRMATION_MESSAGE }); + openToast({ title: SUCCESS_MESSAGE }); } catch (error) { handleError(error); } @@ -102,7 +146,7 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps) workloadType: ConfigPoliciesValues[type].workloadType, workspaceId, }); - openToast({ title: CONFIRMATION_MESSAGE }); + openToast({ title: SUCCESS_MESSAGE }); } catch (error) { handleError(error); } @@ -118,19 +162,25 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps) all {' '} - underlying projects and their experiments in this workspace. + {confirmMessageEnding} ), okText: 'Apply', onConfirm: updatePolicies, onError: handleError, size: 'medium', - title: APPLY_MESSAGE, + title: applyMessage, }); }; const loadableConfigPolicies: Loadable = useAsync(async () => { - if (workspaceId) { + if (global) { + const response = await getGlobalConfigPolicies({ + workloadType: ConfigPoliciesValues[type].workloadType, + }); + if (isEmpty(response.configPolicies)) return undefined; + return response.configPolicies; + } else if (workspaceId) { const response = await getWorkspaceConfigPolicies({ workloadType: ConfigPoliciesValues[type].workloadType, workspaceId, @@ -139,13 +189,15 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps) return response.configPolicies; } return NotLoaded; - }, [workspaceId, type]); + }, [workspaceId, type, global]); + + const initialYAML = yaml.dump(loadableConfigPolicies.getOrElse(undefined)); - const initialConfigPoliciesYAML = yaml.dump(loadableConfigPolicies.getOrElse(undefined)); + const canModify = global ? canModifyGlobalConfigPolicies : canModifyWorkspaceConfigPolicies; const handleChange = () => { setDisabled( - hasErrors(form) || form.getFieldValue('configPolicies') === initialConfigPoliciesYAML, + hasErrors(form) || form.getFieldValue(YAML_FORM_ITEM_NAME) === initialYAML, ); }; @@ -155,18 +207,18 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps)
- {canModifyWorkspaceConfigPolicies ? ( + {canModify ? ( Apply } - message={APPLY_MESSAGE} + message={applyMessage} showIcon /> ) : ( - + )}
@@ -174,7 +226,7 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps)
{ @@ -192,9 +244,9 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, type }: TabProps) }, ]}> { handleError(error); }} diff --git a/webui/react/src/components/NavigationSideBar.tsx b/webui/react/src/components/NavigationSideBar.tsx index 6bc05e85f69..5e49a61dacd 100644 --- a/webui/react/src/components/NavigationSideBar.tsx +++ b/webui/react/src/components/NavigationSideBar.tsx @@ -141,7 +141,7 @@ const NavigationSideBar: React.FC = () => { const shortVersion = version.replace(/^(\d+\.\d+\.\d+).*?$/i, '$1'); const isVersionLong = version !== shortVersion; - const { canCreateWorkspace, canViewWorkspace } = usePermissions(); + const { canCreateWorkspace, canViewWorkspace, canViewGlobalConfigPolicies } = usePermissions(); const canAccessUncategorized = canViewWorkspace({ workspace: { id: 1 } }); @@ -175,6 +175,13 @@ const NavigationSideBar: React.FC = () => { path: paths.templates(), }); } + if (info.branding === BrandingType.HPE && canViewGlobalConfigPolicies) { + topItems.splice(topItems.length - 1, 0, { + icon: 'options', + label: 'Config Policies', + path: paths.configPolicies(), + }); + } if (currentUser?.isAdmin || f_webhook) { topItems.splice(topItems.length - 1, 0, { icon: 'webhooks', @@ -216,6 +223,7 @@ const NavigationSideBar: React.FC = () => { }; }, [ canAccessUncategorized, + canViewGlobalConfigPolicies, info.branding, gasLinkOn, templatesOn, diff --git a/webui/react/src/hooks/usePermissions.ts b/webui/react/src/hooks/usePermissions.ts index c964de151ed..f5ac8f533f0 100644 --- a/webui/react/src/hooks/usePermissions.ts +++ b/webui/react/src/hooks/usePermissions.ts @@ -113,6 +113,8 @@ export interface PermissionsHook { canViewResourceQuotas: boolean; canViewWorkspaceConfigPolicies: boolean; canModifyWorkspaceConfigPolicies: boolean; + canViewGlobalConfigPolicies: boolean; + canModifyGlobalConfigPolicies: boolean; loading: boolean; } @@ -181,6 +183,7 @@ const usePermissions = (): PermissionsHook => { canModifyExperimentMetadata(rbacOpts, args.workspace), canModifyFlatRun: (args: WorkspacePermissionsArgs) => canModifyFlatRun(rbacOpts, args.workspace), + canModifyGlobalConfigPolicies: canModifyGlobalConfigPolicies(rbacOpts), canModifyGroups: canModifyGroups(rbacOpts), canModifyModel: (args: ModelPermissionsArgs) => canModifyModel(rbacOpts, args.model), canModifyModelVersion: (args: ModelVersionPermissionsArgs) => @@ -215,6 +218,7 @@ const usePermissions = (): PermissionsHook => { canUpdateRoles: (args: WorkspacePermissionsArgs) => canUpdateRoles(rbacOpts, args.workspace), canViewExperimentArtifacts: (args: WorkspacePermissionsArgs) => canViewExperimentArtifacts(rbacOpts, args.workspace), + canViewGlobalConfigPolicies: canViewGlobalConfigPolicies(rbacOpts), canViewGroups: canViewGroups(rbacOpts), canViewModelRegistry: (args: WorkspacePermissionsArgs) => canViewModelRegistry(rbacOpts, args.workspace), @@ -837,4 +841,25 @@ const canModifyWorkspaceConfigPolicies = ({ : !!currentUser && currentUser.isAdmin; }; +const canViewGlobalConfigPolicies = ({ + rbacEnabled, + userAssignments, + userRoles, +}: RbacOptsProps): boolean => { + const permitted = relevantPermissions(userAssignments, userRoles); + return !rbacEnabled || permitted.has(V1PermissionType.VIEWGLOBALCONFIGPOLICIES); +}; + +const canModifyGlobalConfigPolicies = ({ + currentUser, + rbacEnabled, + userAssignments, + userRoles, +}: RbacOptsProps): boolean => { + const permitted = relevantPermissions(userAssignments, userRoles); + return rbacEnabled + ? permitted.has(V1PermissionType.MODIFYGLOBALCONFIGPOLICIES) + : !!currentUser && currentUser.isAdmin; +}; + export default usePermissions; diff --git a/webui/react/src/pages/ConfigPoliciesPage.tsx b/webui/react/src/pages/ConfigPoliciesPage.tsx new file mode 100644 index 00000000000..201fe883101 --- /dev/null +++ b/webui/react/src/pages/ConfigPoliciesPage.tsx @@ -0,0 +1,26 @@ +import React, { useRef } from 'react'; + +import ConfigPolicies from 'components/ConfigPolicies'; +import Page from 'components/Page'; +import { paths } from 'routes/utils'; + +const TemplatesPage: React.FC = () => { + const pageRef = useRef(null); + + return ( + + + + ); +}; + +export default TemplatesPage; diff --git a/webui/react/src/routes/index.tsx b/webui/react/src/routes/index.tsx index 593048962ab..a31cba5421f 100644 --- a/webui/react/src/routes/index.tsx +++ b/webui/react/src/routes/index.tsx @@ -27,6 +27,7 @@ const Wait = React.lazy(() => import('pages/Wait')); const Webhooks = React.lazy(() => import('pages/WebhookList')); const WorkspaceDetails = React.lazy(() => import('pages/WorkspaceDetails')); const WorkspaceList = React.lazy(() => import('pages/WorkspaceList')); +const ConfigPoliciesPage = React.lazy(() => import('pages/ConfigPoliciesPage')); import { RouteConfig } from 'types'; import Routes from './routes'; @@ -37,6 +38,7 @@ const routeComponentMap: Record = { clusterHistorical: , clusterLogs: , clusters: , + configPolicies: , dashboard: , default: , experimentDetails: , diff --git a/webui/react/src/routes/routes.ts b/webui/react/src/routes/routes.ts index 21ca2cbdc8c..8413c091148 100644 --- a/webui/react/src/routes/routes.ts +++ b/webui/react/src/routes/routes.ts @@ -154,6 +154,13 @@ const routes: RouteConfig[] = [ path: '/templates', title: 'Manage Templates', }, + { + icon: 'options', + id: 'configPolicies', + needAuth: true, + path: '/policies', + title: 'Config Policies', + }, { icon: 'cluster', id: 'clusterHistorical', diff --git a/webui/react/src/routes/utils.ts b/webui/react/src/routes/utils.ts index dd0c32e55fe..481f835e2a6 100644 --- a/webui/react/src/routes/utils.ts +++ b/webui/react/src/routes/utils.ts @@ -81,6 +81,9 @@ export const paths = { clusters: (): string => { return '/clusters'; }, + configPolicies: (): string => { + return '/policies'; + }, customerAsset: ( name: 'logo', orientation: 'vertical' | 'horizontal', diff --git a/webui/react/src/services/api.ts b/webui/react/src/services/api.ts index f2a707d436f..02a4134d631 100644 --- a/webui/react/src/services/api.ts +++ b/webui/react/src/services/api.ts @@ -1012,3 +1012,21 @@ export const deleteWorkspaceConfigPolicies = generateDetApi< Api.V1DeleteWorkspaceConfigPoliciesResponse, Api.V1DeleteWorkspaceConfigPoliciesResponse >(Config.deleteWorkspaceConfigPolicies); + +export const getGlobalConfigPolicies = generateDetApi< + Service.GetGlobalConfigPolicies, + Api.V1GetGlobalConfigPoliciesResponse, + Api.V1GetGlobalConfigPoliciesResponse +>(Config.getGlobalConfigPolicies); + +export const updateGlobalConfigPolicies = generateDetApi< + Service.UpdateGlobalConfigPolicies, + Api.V1PutGlobalConfigPoliciesResponse, + Api.V1PutGlobalConfigPoliciesResponse +>(Config.updateGlobalConfigPolicies); + +export const deleteGlobalConfigPolicies = generateDetApi< + Service.DeleteGlobalConfigPolicies, + Api.V1DeleteGlobalConfigPoliciesResponse, + Api.V1DeleteGlobalConfigPoliciesResponse +>(Config.deleteGlobalConfigPolicies); diff --git a/webui/react/src/services/apiConfig.ts b/webui/react/src/services/apiConfig.ts index c7c2bea6515..b6c2b0ed1b8 100644 --- a/webui/react/src/services/apiConfig.ts +++ b/webui/react/src/services/apiConfig.ts @@ -2222,3 +2222,43 @@ export const updateWorkspaceConfigPolicies: DetApi< options, ), }; + +export const getGlobalConfigPolicies: DetApi< + Service.GetGlobalConfigPolicies, + Api.V1GetGlobalConfigPoliciesResponse, + Api.V1GetGlobalConfigPoliciesResponse +> = { + name: 'getGlobalConfigPolicies', + postProcess: identity, + request: (params: Service.GetGlobalConfigPolicies, options) => + detApi.Alpha.getGlobalConfigPolicies(params.workloadType, options), +}; + +export const deleteGlobalConfigPolicies: DetApi< + Service.DeleteGlobalConfigPolicies, + Api.V1DeleteGlobalConfigPoliciesResponse, + Api.V1DeleteGlobalConfigPoliciesResponse +> = { + name: 'deleteGlobalConfigPolicies', + postProcess: identity, + request: (params: Service.DeleteGlobalConfigPolicies, options) => + detApi.Alpha.deleteGlobalConfigPolicies(params.workloadType, options), +}; + +export const updateGlobalConfigPolicies: DetApi< + Service.UpdateGlobalConfigPolicies, + Api.V1PutGlobalConfigPoliciesResponse, + Api.V1PutGlobalConfigPoliciesResponse +> = { + name: 'updateGlobalConfigPolicies', + postProcess: identity, + request: (params: Service.UpdateGlobalConfigPolicies, options) => + detApi.Alpha.putGlobalConfigPolicies( + params.workloadType, + { + configPolicies: params.configPolicies, + workloadType: params.workloadType, + }, + options, + ), +}; diff --git a/webui/react/src/services/types.ts b/webui/react/src/services/types.ts index 580eb9e6658..3b41ec11778 100644 --- a/webui/react/src/services/types.ts +++ b/webui/react/src/services/types.ts @@ -579,3 +579,16 @@ export interface DeleteWorkspaceConfigPolicies { workspaceId: number; workloadType: 'NTSC' | 'EXPERIMENT'; } + +export interface GetGlobalConfigPolicies { + workloadType: 'NTSC' | 'EXPERIMENT'; +} + +export interface UpdateGlobalConfigPolicies { + workloadType: 'NTSC' | 'EXPERIMENT'; + configPolicies: string; +} + +export interface DeleteGlobalConfigPolicies { + workloadType: 'NTSC' | 'EXPERIMENT'; +} From b6afe1269272d9c07719a0b71cd0c61ea99a60d9 Mon Sep 17 00:00:00 2001 From: John Kim Date: Fri, 4 Oct 2024 15:16:00 -0400 Subject: [PATCH 2/4] fmt --- webui/react/src/components/ConfigPolicies.tsx | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/webui/react/src/components/ConfigPolicies.tsx b/webui/react/src/components/ConfigPolicies.tsx index 73df820a85b..e35ec03c9a3 100644 --- a/webui/react/src/components/ConfigPolicies.tsx +++ b/webui/react/src/components/ConfigPolicies.tsx @@ -26,10 +26,7 @@ import { import { XOR } from 'types'; import handleError from 'utils/error'; -type Props = XOR< - { workspaceId: number }, - { global: true } ->; +type Props = XOR<{ workspaceId: number }, { global: true }>; type ConfigPoliciesType = 'experiments' | 'tasks'; @@ -51,7 +48,7 @@ const ConfigPoliciesValues: Record = { type TabProps = Props & { type: ConfigPoliciesType; -} +}; type FormInputs = { [YAML_FORM_ITEM_NAME]: string; @@ -96,14 +93,24 @@ const ConfigPolicies: React.FC = ({ workspaceId, global }: Props) => { const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: TabProps) => { const confirm = useConfirm(); const { openToast } = useToast(); - const { canModifyWorkspaceConfigPolicies, canModifyGlobalConfigPolicies, loading: rbacLoading } = usePermissions(); + const { + canModifyWorkspaceConfigPolicies, + canModifyGlobalConfigPolicies, + loading: rbacLoading, + } = usePermissions(); const [form] = Form.useForm(); const [disabled, setDisabled] = useState(true); - const applyMessage = global ? "You're about to apply these config policies to this cluster." : "You're about to apply these config policies to this workspace."; - const viewMessage = global ? 'These global config policies are being applied to this cluster.' : 'These global config policies are being applied to this workspace.'; - const confirmMessageEnding = global ? 'underlying workspaces, projects, and submitted experiments in this cluster.' : 'underlying projects and their experiments in this workspace.'; + const applyMessage = global + ? "You're about to apply these config policies to this cluster." + : "You're about to apply these config policies to this workspace."; + const viewMessage = global + ? 'These global config policies are being applied to this cluster.' + : 'These global config policies are being applied to this workspace.'; + const confirmMessageEnding = global + ? 'underlying workspaces, projects, and submitted experiments in this cluster.' + : 'underlying projects and their experiments in this workspace.'; const updatePolicies = async () => { const configPolicies = form.getFieldValue(YAML_FORM_ITEM_NAME); @@ -196,9 +203,7 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta const canModify = global ? canModifyGlobalConfigPolicies : canModifyWorkspaceConfigPolicies; const handleChange = () => { - setDisabled( - hasErrors(form) || form.getFieldValue(YAML_FORM_ITEM_NAME) === initialYAML, - ); + setDisabled(hasErrors(form) || form.getFieldValue(YAML_FORM_ITEM_NAME) === initialYAML); }; if (rbacLoading) return ; From 89f2831ce1a551ad7d85d3896bc0953d8410c557 Mon Sep 17 00:00:00 2001 From: John Kim Date: Tue, 8 Oct 2024 10:24:22 -0400 Subject: [PATCH 3/4] copy --- webui/react/src/components/ConfigPolicies.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/webui/react/src/components/ConfigPolicies.tsx b/webui/react/src/components/ConfigPolicies.tsx index e35ec03c9a3..04659f6b83a 100644 --- a/webui/react/src/components/ConfigPolicies.tsx +++ b/webui/react/src/components/ConfigPolicies.tsx @@ -54,7 +54,7 @@ type FormInputs = { [YAML_FORM_ITEM_NAME]: string; }; -const SUCCESS_MESSAGE = 'Config policies updated.'; +const SUCCESS_MESSAGE = 'Configuration policies updated.'; const YAML_FORM_ITEM_NAME = 'configPolicies'; const ConfigPolicies: React.FC = ({ workspaceId, global }: Props) => { @@ -103,13 +103,13 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta const [disabled, setDisabled] = useState(true); const applyMessage = global - ? "You're about to apply these config policies to this cluster." - : "You're about to apply these config policies to this workspace."; + ? "You're about to apply these configuration policies to the cluster." + : "You're about to apply these configuration policies to the workspace."; const viewMessage = global - ? 'These global config policies are being applied to this cluster.' - : 'These global config policies are being applied to this workspace.'; + ? 'Global configuration policies are being applied to the cluster.' + : 'Global configuration policies are being applied to the workspace.'; const confirmMessageEnding = global - ? 'underlying workspaces, projects, and submitted experiments in this cluster.' + ? 'underlying workspaces, projects, and submitted experiments in the cluster.' : 'underlying projects and their experiments in this workspace.'; const updatePolicies = async () => { From 9d2e3b52fd90d0e4312286d842fcc9fe04b22683 Mon Sep 17 00:00:00 2001 From: John Kim Date: Wed, 9 Oct 2024 12:35:01 -0400 Subject: [PATCH 4/4] refactor --- webui/react/src/components/ConfigPolicies.tsx | 99 +++++-------------- 1 file changed, 27 insertions(+), 72 deletions(-) diff --git a/webui/react/src/components/ConfigPolicies.tsx b/webui/react/src/components/ConfigPolicies.tsx index 04659f6b83a..6b0c0004f51 100644 --- a/webui/react/src/components/ConfigPolicies.tsx +++ b/webui/react/src/components/ConfigPolicies.tsx @@ -57,35 +57,19 @@ type FormInputs = { const SUCCESS_MESSAGE = 'Configuration policies updated.'; const YAML_FORM_ITEM_NAME = 'configPolicies'; -const ConfigPolicies: React.FC = ({ workspaceId, global }: Props) => { - let tabItems: PivotProps['items']; - if (global) { - tabItems = [ - { - children: , - key: 'experiments', - label: ConfigPoliciesValues.experiments.label, - }, - { - children: , - key: 'tasks', - label: ConfigPoliciesValues.tasks.label, - }, - ]; - } else if (workspaceId) { - tabItems = [ - { - children: , - key: 'experiments', - label: ConfigPoliciesValues.experiments.label, - }, - { - children: , - key: 'tasks', - label: ConfigPoliciesValues.tasks.label, - }, - ]; - } +const ConfigPolicies: React.FC = (props: Props) => { + const tabItems: PivotProps['items'] = [ + { + children: , + key: 'experiments', + label: ConfigPoliciesValues.experiments.label, + }, + { + children: , + key: 'tasks', + label: ConfigPoliciesValues.tasks.label, + }, + ]; return ; }; @@ -114,50 +98,21 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta const updatePolicies = async () => { const configPolicies = form.getFieldValue(YAML_FORM_ITEM_NAME); - if (global) { - if (configPolicies.length) { - try { - await updateGlobalConfigPolicies({ - configPolicies, - workloadType: ConfigPoliciesValues[type].workloadType, - }); - openToast({ title: SUCCESS_MESSAGE }); - } catch (error) { - handleError(error); - } - } else { - try { - await deleteGlobalConfigPolicies({ - workloadType: ConfigPoliciesValues[type].workloadType, - }); - openToast({ title: SUCCESS_MESSAGE }); - } catch (error) { - handleError(error); - } - } - } else if (workspaceId) { - if (configPolicies.length) { - try { - await updateWorkspaceConfigPolicies({ - configPolicies, - workloadType: ConfigPoliciesValues[type].workloadType, - workspaceId, - }); - openToast({ title: SUCCESS_MESSAGE }); - } catch (error) { - handleError(error); - } - } else { - try { - await deleteWorkspaceConfigPolicies({ - workloadType: ConfigPoliciesValues[type].workloadType, - workspaceId, - }); - openToast({ title: SUCCESS_MESSAGE }); - } catch (error) { - handleError(error); - } + const workloadType = ConfigPoliciesValues[type].workloadType; + + try { + if (global) { + configPolicies.length + ? await updateGlobalConfigPolicies({ configPolicies, workloadType }) + : await deleteGlobalConfigPolicies({ workloadType }); + } else if (workspaceId) { + configPolicies.length + ? await updateWorkspaceConfigPolicies({ configPolicies, workloadType, workspaceId }) + : await deleteWorkspaceConfigPolicies({ workloadType, workspaceId }); } + openToast({ title: SUCCESS_MESSAGE }); + } catch (error) { + handleError(error); } };