diff --git a/web/src/components/AllowButton/AllowButton.tsx b/web/src/components/AllowButton/AllowButton.tsx index 6e90d73f46..8e145b9d80 100644 --- a/web/src/components/AllowButton/AllowButton.tsx +++ b/web/src/components/AllowButton/AllowButton.tsx @@ -11,7 +11,7 @@ const AllowButton = ({operation, ...props}: IProps) => { return ( - - + diff --git a/web/src/components/EditTestSuite/EditTestSuite.tsx b/web/src/components/EditTestSuite/EditTestSuite.tsx index dae0061d72..050f75eecc 100644 --- a/web/src/components/EditTestSuite/EditTestSuite.tsx +++ b/web/src/components/EditTestSuite/EditTestSuite.tsx @@ -1,5 +1,6 @@ import {Button, Form} from 'antd'; import {useCallback, useState} from 'react'; +import AllowButton, {Operation} from 'components/AllowButton'; import {TDraftTestSuite} from 'types/TestSuite.types'; import {useTestSuite} from 'providers/TestSuite'; import useValidateTestSuiteDraft from 'hooks/useValidateTestSuiteDraft'; @@ -37,7 +38,8 @@ const EditTestSuite = ({testSuite, testSuiteRun}: IProps) => { - + diff --git a/web/src/components/ResourceCard/ResourceCardActions.tsx b/web/src/components/ResourceCard/ResourceCardActions.tsx index 660c8dbba3..99dd78d77e 100644 --- a/web/src/components/ResourceCard/ResourceCardActions.tsx +++ b/web/src/components/ResourceCard/ResourceCardActions.tsx @@ -1,6 +1,7 @@ import {Dropdown, Menu} from 'antd'; import {useCallback, useMemo} from 'react'; +import {Operation, useCustomization} from 'providers/Customization'; import * as S from './ResourceCard.styled'; interface IProps { @@ -11,6 +12,8 @@ interface IProps { } const ResourceCardActions = ({id, shouldEdit = true, onDelete, onEdit}: IProps) => { + const {getIsAllowed} = useCustomization(); + const onDeleteClick = useCallback( ({domEvent}) => { domEvent?.stopPropagation(); @@ -28,17 +31,30 @@ const ResourceCardActions = ({id, shouldEdit = true, onDelete, onEdit}: IProps) ); const menuItems = useMemo(() => { - const defaultItems = [{key: 'delete', label: Delete, onClick: onDeleteClick}]; + const defaultItems = [ + { + key: 'delete', + label: Delete, + onClick: onDeleteClick, + disabled: !getIsAllowed(Operation.Edit), + }, + ]; - return shouldEdit ? [{key: 'edit', label: Edit, onClick: onEditClick}, ...defaultItems] : defaultItems; - }, [onDeleteClick, onEditClick, shouldEdit]); + return shouldEdit + ? [ + { + key: 'edit', + label: Edit, + onClick: onEditClick, + disabled: !getIsAllowed(Operation.Edit), + }, + ...defaultItems, + ] + : defaultItems; + }, [getIsAllowed, onDeleteClick, onEditClick, shouldEdit]); return ( - } - placement="bottomLeft" - trigger={['click']} - > + } placement="bottomLeft" trigger={['click']}> e.stopPropagation()}> diff --git a/web/src/components/RunActionsMenu/RunActionsMenu.tsx b/web/src/components/RunActionsMenu/RunActionsMenu.tsx index 2a02431c4f..0c37601ba5 100644 --- a/web/src/components/RunActionsMenu/RunActionsMenu.tsx +++ b/web/src/components/RunActionsMenu/RunActionsMenu.tsx @@ -2,6 +2,7 @@ import {Dropdown, Menu} from 'antd'; import {useFileViewerModal} from 'components/FileViewerModal/FileViewerModal.provider'; import useDeleteResourceRun from 'hooks/useDeleteResourceRun'; +import {Operation, useCustomization} from 'providers/Customization'; import {useDashboard} from 'providers/Dashboard/Dashboard.provider'; import TestRunAnalyticsService from 'services/Analytics/TestRunAnalytics.service'; import {ResourceType} from 'types/Resource.type'; @@ -16,6 +17,7 @@ interface IProps { } const RunActionsMenu = ({resultId, testId, testSuiteId, testSuiteRunId, isRunView = false}: IProps) => { + const {getIsAllowed} = useCustomization(); const {onJUnit} = useFileViewerModal(); const {navigate} = useDashboard(); const onDelete = useDeleteResourceRun({id: testId, isRunView, type: ResourceType.Test}); @@ -62,6 +64,7 @@ const RunActionsMenu = ({resultId, testId, testSuiteId, testSuiteRunId, isRunVie navigate(`/test/${testId}/run/${resultId}`); }} key="edit" + disabled={!getIsAllowed(Operation.Edit)} > Edit @@ -72,6 +75,7 @@ const RunActionsMenu = ({resultId, testId, testSuiteId, testSuiteRunId, isRunVie onDelete(resultId); }} key="delete" + disabled={!getIsAllowed(Operation.Edit)} > Delete diff --git a/web/src/components/Settings/Analytics/AnalyticsForm.tsx b/web/src/components/Settings/Analytics/AnalyticsForm.tsx index 7a23b4f230..5a3f9a069c 100644 --- a/web/src/components/Settings/Analytics/AnalyticsForm.tsx +++ b/web/src/components/Settings/Analytics/AnalyticsForm.tsx @@ -1,4 +1,5 @@ -import {Button, Form, Switch} from 'antd'; +import {Form, Switch} from 'antd'; +import AllowButton, {Operation} from 'components/AllowButton'; import {useSettings} from 'providers/Settings/Settings.provider'; import {useSettingsValues} from 'providers/SettingsValues/SettingsValues.provider'; import {useCallback} from 'react'; @@ -40,9 +41,9 @@ const AnalyticsForm = () => { - + ); diff --git a/web/src/components/Settings/DataStoreForm/DataStoreForm.tsx b/web/src/components/Settings/DataStoreForm/DataStoreForm.tsx index 15b30daa48..e80c88b64f 100644 --- a/web/src/components/Settings/DataStoreForm/DataStoreForm.tsx +++ b/web/src/components/Settings/DataStoreForm/DataStoreForm.tsx @@ -81,9 +81,16 @@ const DataStoreForm = ({ {isConfigReady ? ( - + ) : (
)} diff --git a/web/src/components/Settings/Demo/DemoForm.tsx b/web/src/components/Settings/Demo/DemoForm.tsx index a609b19778..b298a22478 100644 --- a/web/src/components/Settings/Demo/DemoForm.tsx +++ b/web/src/components/Settings/Demo/DemoForm.tsx @@ -1,6 +1,7 @@ -import {Button, Form, Switch} from 'antd'; +import {Form, Switch} from 'antd'; import {useCallback} from 'react'; +import AllowButton, {Operation} from 'components/AllowButton'; import {useSettings} from 'providers/Settings/Settings.provider'; import {useSettingsValues} from 'providers/SettingsValues/SettingsValues.provider'; import SettingService from 'services/Setting.service'; @@ -63,9 +64,15 @@ const DemoForm = () => { {otelEnabled && } - + ); diff --git a/web/src/components/Settings/Linter/LinterForm.tsx b/web/src/components/Settings/Linter/LinterForm.tsx index 182d0d1c7e..9f576efc67 100644 --- a/web/src/components/Settings/Linter/LinterForm.tsx +++ b/web/src/components/Settings/Linter/LinterForm.tsx @@ -1,5 +1,6 @@ -import {Button, Col, Form, Input, Row, Switch} from 'antd'; +import {Col, Form, Input, Row, Switch} from 'antd'; import {useEffect} from 'react'; +import AllowButton, {Operation} from 'components/AllowButton'; import {useSettings} from 'providers/Settings/Settings.provider'; import {useSettingsValues} from 'providers/SettingsValues/SettingsValues.provider'; import SettingService from 'services/Setting.service'; @@ -80,9 +81,9 @@ const LinterForm = () => { - + ); diff --git a/web/src/components/Settings/Polling/PollingForm.tsx b/web/src/components/Settings/Polling/PollingForm.tsx index f0a764c768..a45d3ab6a1 100644 --- a/web/src/components/Settings/Polling/PollingForm.tsx +++ b/web/src/components/Settings/Polling/PollingForm.tsx @@ -1,8 +1,9 @@ import {useEffect} from 'react'; -import {Button, Col, Form, Input, Row} from 'antd'; +import {Col, Form, Input, Row} from 'antd'; + +import AllowButton, {Operation} from 'components/AllowButton'; import {useSettings} from 'providers/Settings/Settings.provider'; import {useSettingsValues} from 'providers/SettingsValues/SettingsValues.provider'; - import {ResourceType, TDraftPollingProfiles} from 'types/Settings.types'; import SettingService from 'services/Setting.service'; import * as S from '../common/Settings.styled'; @@ -58,9 +59,9 @@ const PollingForm = () => { - + ); diff --git a/web/src/components/Settings/TestRunner/TestRunnerForm.tsx b/web/src/components/Settings/TestRunner/TestRunnerForm.tsx index dea5c0f902..51e07446dd 100644 --- a/web/src/components/Settings/TestRunner/TestRunnerForm.tsx +++ b/web/src/components/Settings/TestRunner/TestRunnerForm.tsx @@ -1,5 +1,6 @@ import {useCallback, useEffect} from 'react'; -import {Button, Form} from 'antd'; +import {Form} from 'antd'; +import AllowButton, {Operation} from 'components/AllowButton'; import {ResourceType, TDraftTestRunner} from 'types/Settings.types'; import {useSettings} from 'providers/Settings/Settings.provider'; import SettingService from 'services/Setting.service'; @@ -42,9 +43,9 @@ const TestRunnerForm = () => { - + ); diff --git a/web/src/components/TestOutputForm/TestOutputForm.tsx b/web/src/components/TestOutputForm/TestOutputForm.tsx index 9ec5b7fe5d..2621969784 100644 --- a/web/src/components/TestOutputForm/TestOutputForm.tsx +++ b/web/src/components/TestOutputForm/TestOutputForm.tsx @@ -4,6 +4,7 @@ import {Button, Form, Input, Tag} from 'antd'; import {delay} from 'lodash'; import {useEffect} from 'react'; +import AllowButton, {Operation} from 'components/AllowButton'; import Editor from 'components/Editor'; import {EXPRESSIONS_DOCUMENTATION_URL, SELECTOR_LANGUAGE_CHEAT_SHEET_URL} from 'constants/Common.constants'; import {SupportedEditors} from 'constants/Editor.constants'; @@ -131,9 +132,16 @@ const TestOutputForm = ({ - + diff --git a/web/src/components/TestSpecForm/TestSpecForm.tsx b/web/src/components/TestSpecForm/TestSpecForm.tsx index 804216996b..5c9d9ecb1c 100644 --- a/web/src/components/TestSpecForm/TestSpecForm.tsx +++ b/web/src/components/TestSpecForm/TestSpecForm.tsx @@ -2,6 +2,7 @@ import {Button, Form, Input, Tag} from 'antd'; import {LoadingOutlined} from '@ant-design/icons'; import {useEffect} from 'react'; +import AllowButton, {Operation} from 'components/AllowButton'; import {SELECTOR_LANGUAGE_CHEAT_SHEET_URL} from 'constants/Common.constants'; import {CompareOperator} from 'constants/Operator.constants'; import {useAppSelector} from 'redux/hooks'; @@ -184,9 +185,15 @@ const TestSpecForm = ({ - + diff --git a/web/src/components/TestSuiteRunActionsMenu/TestSuiteRunActionsMenu.tsx b/web/src/components/TestSuiteRunActionsMenu/TestSuiteRunActionsMenu.tsx index 5412a465c8..ae04bcfa19 100644 --- a/web/src/components/TestSuiteRunActionsMenu/TestSuiteRunActionsMenu.tsx +++ b/web/src/components/TestSuiteRunActionsMenu/TestSuiteRunActionsMenu.tsx @@ -1,6 +1,7 @@ import {Dropdown, Menu} from 'antd'; import useDeleteResourceRun from 'hooks/useDeleteResourceRun'; +import {Operation, useCustomization} from 'providers/Customization'; import {useDashboard} from 'providers/Dashboard/Dashboard.provider'; import {ResourceType} from 'types/Resource.type'; import * as S from './TestSuiteRunActionsMenu.styled'; @@ -12,6 +13,7 @@ interface IProps { } const TestSuiteRunActionsMenu = ({runId, testSuiteId, isRunView = false}: IProps) => { + const {getIsAllowed} = useCustomization(); const {navigate} = useDashboard(); const onDelete = useDeleteResourceRun({id: testSuiteId, isRunView, type: ResourceType.TestSuite}); @@ -29,6 +31,7 @@ const TestSuiteRunActionsMenu = ({runId, testSuiteId, isRunView = false}: IProps domEvent.stopPropagation(); navigate(`/testsuite/${testSuiteId}/run/${runId}`); }} + disabled={!getIsAllowed(Operation.Edit)} > Edit @@ -38,6 +41,7 @@ const TestSuiteRunActionsMenu = ({runId, testSuiteId, isRunView = false}: IProps domEvent.stopPropagation(); onDelete(runId); }} + disabled={!getIsAllowed(Operation.Edit)} > Delete diff --git a/web/src/components/VariableSetSelector/VariableSetSelector.tsx b/web/src/components/VariableSetSelector/VariableSetSelector.tsx index 18beb734c3..42bcba14cf 100644 --- a/web/src/components/VariableSetSelector/VariableSetSelector.tsx +++ b/web/src/components/VariableSetSelector/VariableSetSelector.tsx @@ -1,12 +1,14 @@ import {DownOutlined} from '@ant-design/icons'; import {Dropdown, Menu, Space} from 'antd'; import type {ItemType} from 'antd/lib/menu/hooks/useItems'; +import {Operation, useCustomization} from 'providers/Customization'; import {useVariableSet} from 'providers/VariableSet'; import {useMemo, useState} from 'react'; import AddVariableSet from './AddVariableSet'; import VariableSetSelectorEntry from './VariableSetSelectorEntry'; const VariableSetSelector = () => { + const {getIsAllowed} = useCustomization(); const {variableSetList, selectedVariableSet, setSelectedVariableSet, isLoading, onOpenModal} = useVariableSet(); const [hoveredOption, setHoveredOption] = useState(); @@ -29,6 +31,7 @@ const VariableSetSelector = () => { onEditClick={onOpenModal} variableSet={variableSet} isHovering={hoveredOption === variableSet.id} + isAllowed={getIsAllowed(Operation.Edit)} /> ), onClick: () => setSelectedVariableSet(variableSet), @@ -43,9 +46,10 @@ const VariableSetSelector = () => { key: 'add-variable-set', label: , onClick: () => onOpenModal(), + disabled: !getIsAllowed(Operation.Edit), }, ]), - [hoveredOption, onOpenModal, setSelectedVariableSet, variableSetList] + [getIsAllowed, hoveredOption, onOpenModal, setSelectedVariableSet, variableSetList] ); return !isLoading ? ( diff --git a/web/src/components/VariableSetSelector/VariableSetSelectorEntry.tsx b/web/src/components/VariableSetSelector/VariableSetSelectorEntry.tsx index 8378adf5fe..a9b7dc84da 100644 --- a/web/src/components/VariableSetSelector/VariableSetSelectorEntry.tsx +++ b/web/src/components/VariableSetSelector/VariableSetSelectorEntry.tsx @@ -5,11 +5,12 @@ import * as S from './VariableSetSelector.styled'; interface IProps { variableSet: VariableSet; + isAllowed: boolean; isHovering: boolean; onEditClick(variableSet: VariableSet): void; } -const VariableSetSelectorEntry = ({variableSet: {name}, variableSet, isHovering, onEditClick}: IProps) => { +const VariableSetSelectorEntry = ({variableSet: {name}, variableSet, isAllowed, isHovering, onEditClick}: IProps) => { const handleClick = useCallback( event => { event.stopPropagation(); @@ -21,7 +22,7 @@ const VariableSetSelectorEntry = ({variableSet: {name}, variableSet, isHovering, return ( {name} - {isHovering && ( + {isAllowed && isHovering && ( diff --git a/web/src/pages/Home/CreateButton.tsx b/web/src/pages/Home/CreateButton.tsx index f0440fefa1..37c38e70e6 100644 --- a/web/src/pages/Home/CreateButton.tsx +++ b/web/src/pages/Home/CreateButton.tsx @@ -1,3 +1,4 @@ +import {Operation} from 'components/AllowButton'; import * as S from '../TestSuites/TestSuites.styled'; interface IProps { @@ -7,7 +8,7 @@ interface IProps { const CreateButton = ({onCreate}: IProps) => { return ( - + Create diff --git a/web/src/pages/TestSuites/TestSuites.styled.tsx b/web/src/pages/TestSuites/TestSuites.styled.tsx index dd3c80e612..5eede5ba11 100644 --- a/web/src/pages/TestSuites/TestSuites.styled.tsx +++ b/web/src/pages/TestSuites/TestSuites.styled.tsx @@ -1,7 +1,8 @@ -import {Button, Dropdown, Row, Space, Typography} from 'antd'; +import {Dropdown, Row, Space, Typography} from 'antd'; +import AllowButton from 'components/AllowButton'; import styled from 'styled-components'; -export const CreateTestButton = styled(Button)` +export const CreateTestButton = styled(AllowButton)` font-weight: 600; `; diff --git a/web/src/pages/VariableSet/VariableSet.styled.tsx b/web/src/pages/VariableSet/VariableSet.styled.tsx index 6e54c2f28c..f821c5d564 100644 --- a/web/src/pages/VariableSet/VariableSet.styled.tsx +++ b/web/src/pages/VariableSet/VariableSet.styled.tsx @@ -1,9 +1,7 @@ import {CheckCircleOutlined} from '@ant-design/icons'; -import {Button, Typography} from 'antd'; +import {Typography} from 'antd'; import styled from 'styled-components'; -export const CreateVarsButton = styled(Button)``; - export const PageHeader = styled.div` display: flex; flex-direction: row; diff --git a/web/src/pages/VariableSet/VariableSetCard.tsx b/web/src/pages/VariableSet/VariableSetCard.tsx index b2d565d33b..251f844185 100644 --- a/web/src/pages/VariableSet/VariableSetCard.tsx +++ b/web/src/pages/VariableSet/VariableSetCard.tsx @@ -6,6 +6,7 @@ import * as T from 'components/ResourceCard/ResourceCard.styled'; import {useFileViewerModal} from 'components/FileViewerModal/FileViewerModal.provider'; import {ResourceType} from 'types/Resource.type'; import VariableSet from 'models/VariableSet.model'; +import {Operation, useCustomization} from 'providers/Customization'; import {useVariableSet} from 'providers/VariableSet'; import * as E from './VariableSet.styled'; @@ -16,6 +17,7 @@ interface IProps { } const VariableSetCard = ({variableSet: {description, id, name, values}, variableSet, onDelete, onEdit}: IProps) => { + const {getIsAllowed} = useCustomization(); const [isCollapsed, setIsCollapsed] = useState(false); const {onDefinition} = useFileViewerModal(); const {selectedVariableSet} = useVariableSet(); @@ -47,6 +49,7 @@ const VariableSetCard = ({variableSet: {description, id, name, values}, variable { key: 'edit', label: Edit, + disabled: !getIsAllowed(Operation.Edit), onClick: e => { e.domEvent.stopPropagation(); onEdit(variableSet); @@ -63,6 +66,7 @@ const VariableSetCard = ({variableSet: {description, id, name, values}, variable { key: 'delete', label: Delete, + disabled: !getIsAllowed(Operation.Edit), onClick: e => { e.domEvent.stopPropagation(); onDelete(id); diff --git a/web/src/pages/VariableSet/VariableSetContent.tsx b/web/src/pages/VariableSet/VariableSetContent.tsx index 0a3d0c753a..af3bcebdf8 100644 --- a/web/src/pages/VariableSet/VariableSetContent.tsx +++ b/web/src/pages/VariableSet/VariableSetContent.tsx @@ -1,5 +1,6 @@ import {useCallback, useState} from 'react'; +import AllowButton, {Operation} from 'components/AllowButton'; import SearchInput from 'components/SearchInput'; import VariableSetsAnalytics from 'services/Analytics/VariableSetsAnalytics.service'; import VariableSet from 'models/VariableSet.model'; @@ -35,9 +36,9 @@ const VariableSetContent = () => { - + Create Variable Set - + diff --git a/web/src/pages/VariableSet/VariableSetList.tsx b/web/src/pages/VariableSet/VariableSetList.tsx index 262a19e751..b34a79e843 100644 --- a/web/src/pages/VariableSet/VariableSetList.tsx +++ b/web/src/pages/VariableSet/VariableSetList.tsx @@ -26,7 +26,7 @@ const VariableSetList = ({onDelete, onEdit, query}: IProps) => { title="You have not created any variable sets yet" message={ <> - Use the Create button to create your first variable set. Learn more about test or test suites{' '} + Use the Create button to create your first variable set. Learn more about variable sets{' '} here. }