diff --git a/webui/react/src/components/ConfigPolicies.tsx b/webui/react/src/components/ConfigPolicies.tsx index 6b0c0004f51..2899a24175e 100644 --- a/webui/react/src/components/ConfigPolicies.tsx +++ b/webui/react/src/components/ConfigPolicies.tsx @@ -11,10 +11,12 @@ import useConfirm from 'hew/useConfirm'; import { Loadable, NotLoaded } from 'hew/utils/loadable'; import yaml from 'js-yaml'; import { isEmpty } from 'lodash'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; +import Link from 'components/Link'; import { useAsync } from 'hooks/useAsync'; import usePermissions from 'hooks/usePermissions'; +import { paths } from 'routes/utils'; import { deleteGlobalConfigPolicies, deleteWorkspaceConfigPolicies, @@ -85,13 +87,14 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta const [form] = Form.useForm(); const [disabled, setDisabled] = useState(true); + const [updatedYAML, setUpdatedYAML] = useState(); const applyMessage = global ? "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 - ? 'Global configuration policies are being applied to the cluster.' - : 'Global configuration policies are being applied to the workspace.'; + ? 'Configuration policies are being applied to the cluster.' + : 'Configuration policies are being applied to the workspace.'; const confirmMessageEnding = global ? 'underlying workspaces, projects, and submitted experiments in the cluster.' : 'underlying projects and their experiments in this workspace.'; @@ -110,6 +113,7 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta ? await updateWorkspaceConfigPolicies({ configPolicies, workloadType, workspaceId }) : await deleteWorkspaceConfigPolicies({ workloadType, workspaceId }); } + setUpdatedYAML(configPolicies); openToast({ title: SUCCESS_MESSAGE }); } catch (error) { handleError(error); @@ -157,10 +161,25 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta const canModify = global ? canModifyGlobalConfigPolicies : canModifyWorkspaceConfigPolicies; + useEffect(() => { + if (updatedYAML) setDisabled(form.getFieldValue(YAML_FORM_ITEM_NAME) === updatedYAML); + }, [updatedYAML, form]); + const handleChange = () => { - setDisabled(hasErrors(form) || form.getFieldValue(YAML_FORM_ITEM_NAME) === initialYAML); + setDisabled( + hasErrors(form) || + (updatedYAML + ? form.getFieldValue(YAML_FORM_ITEM_NAME) === updatedYAML + : form.getFieldValue(YAML_FORM_ITEM_NAME) === initialYAML), + ); }; + const docsLink = ( + + Learn more + + ); + if (rbacLoading) return ; return ( @@ -174,11 +193,12 @@ const ConfigPoliciesTab: React.FC = ({ workspaceId, global, type }: Ta Apply } + description={docsLink} message={applyMessage} showIcon /> ) : ( - + )} diff --git a/webui/react/src/pages/ConfigPoliciesPage.tsx b/webui/react/src/pages/ConfigPoliciesPage.tsx index 201fe883101..96c5ea84fe9 100644 --- a/webui/react/src/pages/ConfigPoliciesPage.tsx +++ b/webui/react/src/pages/ConfigPoliciesPage.tsx @@ -1,11 +1,24 @@ +import Spinner from 'hew/Spinner'; import React, { useRef } from 'react'; import ConfigPolicies from 'components/ConfigPolicies'; import Page from 'components/Page'; +import PageNotFound from 'components/PageNotFound'; +import usePermissions from 'hooks/usePermissions'; import { paths } from 'routes/utils'; +import determinedStore, { BrandingType } from 'stores/determinedInfo'; +import { useObservable } from 'utils/observable'; const TemplatesPage: React.FC = () => { const pageRef = useRef(null); + const info = useObservable(determinedStore.info); + const { canViewGlobalConfigPolicies, loading: rbacLoading } = usePermissions(); + + const canView = info.branding === BrandingType.HPE && canViewGlobalConfigPolicies; + + if (rbacLoading) return ; + + if (!canView) return ; return (