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/EditTest/EditTest.tsx b/web/src/components/EditTest/EditTest.tsx
index 32de60c2b6..9633f5ae7b 100644
--- a/web/src/components/EditTest/EditTest.tsx
+++ b/web/src/components/EditTest/EditTest.tsx
@@ -1,4 +1,5 @@
import {Button, Form} from 'antd';
+import AllowButton, {Operation} from 'components/AllowButton';
import EditTestForm from 'components/EditTestForm';
import {TriggerTypeToPlugin} from 'constants/Plugins.constants';
import useValidateTestDraft from 'hooks/useValidateTestDraft';
@@ -43,7 +44,8 @@ const EditTest = ({test}: IProps) => {
-
+
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.
>
}