From 1a7c6e9979ae07c3e67b2d86758dd9f2a4594019 Mon Sep 17 00:00:00 2001 From: Thomas L Fagermyr Date: Mon, 21 Oct 2024 12:57:36 +0200 Subject: [PATCH 1/5] feat: Added component to check access --- src/utils/IsOwnerOrAdmin.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/utils/IsOwnerOrAdmin.tsx diff --git a/src/utils/IsOwnerOrAdmin.tsx b/src/utils/IsOwnerOrAdmin.tsx new file mode 100644 index 0000000..c5976fb --- /dev/null +++ b/src/utils/IsOwnerOrAdmin.tsx @@ -0,0 +1,19 @@ +import { useMsal } from '@azure/msal-react'; + +export const isOwnerOrAdmin = (createdBy?: string | null | undefined) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const { accounts } = useMsal(); + const roles = accounts[0].idTokenClaims?.roles; + + if (roles === undefined) return false; + if (roles.includes('PEPM.Admin')) return true; + if (roles.includes('PEPM.User')) { + if (createdBy) { + if (accounts[0].username === createdBy) return true; + return false; + } + return true; + } + + return false; +}; From b1e5a83fb0e114bc1d407db83cfb74d660b57fec Mon Sep 17 00:00:00 2001 From: Thomas L Fagermyr Date: Mon, 21 Oct 2024 12:58:39 +0200 Subject: [PATCH 2/5] feat: Added isOwner agrument to determine what to show and disable --- .../AddCaseButtons/AddCaseButtons.tsx | 10 ++++-- .../CaseCardComponent/CaseCardComponent.tsx | 3 ++ .../GrossDepositionEnviromentGroup.tsx | 30 +++++++++------- .../OutcropAnalogueGroup.tsx | 35 ++++++++++++------- .../StratigrapicGroups/StratigrapicGroups.tsx | 27 +++++++++----- .../CaseGroup/CaseButtons/CaseButtons.tsx | 13 ++++--- src/features/Compute/CaseGroup/CaseGroup.tsx | 7 +++- .../Compute/CaseGroup/CaseRow/CaseRow.tsx | 8 +++++ .../CaseSettingSelects/CaseSettingSelect.tsx | 7 ++-- .../CaseSettingSelects/ModelAreaSelect.tsx | 3 ++ .../VariogramSettingSelect.tsx | 8 +++++ .../ModelView/DeleteButton/DeleteModel.tsx | 9 ++++- .../ModelAreaCoordinates.tsx | 10 ++++-- .../ModelMetadataView/ModelMetadataView.tsx | 24 +++++++++---- src/features/ModelView/ModelView.tsx | 14 ++++++-- src/pages/Browse/Browse.tsx | 17 +++++++-- .../Compute/ComputeObject/ComputeObject.tsx | 9 +++++ .../ComputeVariogram/ComputeVariogram.tsx | 19 ++++++++-- 18 files changed, 190 insertions(+), 63 deletions(-) diff --git a/src/components/AddCaseButtons/AddCaseButtons.tsx b/src/components/AddCaseButtons/AddCaseButtons.tsx index 3f78ea3..080cf9a 100644 --- a/src/components/AddCaseButtons/AddCaseButtons.tsx +++ b/src/components/AddCaseButtons/AddCaseButtons.tsx @@ -6,10 +6,12 @@ export const AddCaseButtons = ({ title, localList, addCase, + isOwner, }: { title: string; localList?: ComputeCaseDto[]; addCase?: (methodType: string) => void; + isOwner: () => boolean; }) => { const filerLocalList = (methodType: string) => { if (!localList) return []; @@ -24,7 +26,7 @@ export const AddCaseButtons = ({ + {hideContent() && ( + + )} {row.grossDepEnv.equinorCode + @@ -180,9 +184,11 @@ export const GrossDepositionEnviromentGroup = ({ )}
- + {hideContent() && ( + + )}
diff --git a/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx b/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx index 1934408..705414f 100644 --- a/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx +++ b/src/components/OutcropAnalogue/OutcropAnalogueGroup/OutcropAnalogueGroup.tsx @@ -42,10 +42,12 @@ export const OutcropAnalogueGroup = ({ modelIdParent, defaultMetadata, outcropGroup, + hideContent, }: { modelIdParent?: string; defaultMetadata: AnalogueModelDetail; outcropGroup: OutcropDto[]; + hideContent: () => boolean; }) => { const [showOutcropDialog, setShowOutcropDialog] = useState(false); const [errors, setErrors] = useState({}); @@ -115,16 +117,21 @@ export const OutcropAnalogueGroup = ({ {outcropGroup.map((row) => ( - + {hideContent() && ( + + )} {row.name} @@ -146,9 +153,11 @@ export const OutcropAnalogueGroup = ({ )}
- + {hideContent() && ( + + )}
Add Outcrop Analogue diff --git a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx index 6f6ed30..9b756d1 100644 --- a/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx +++ b/src/components/StrategraphicColumn/StratigrapicGroups/StratigrapicGroups.tsx @@ -58,6 +58,7 @@ export const StratigrapicGroups = ({ defaultMetadata, stratColumnGroups, deleteStratColRow, + hideContent, }: { modelIdParent?: string; defaultMetadata: AnalogueModelDetail; @@ -65,6 +66,7 @@ export const StratigrapicGroups = ({ deleteStratColRow: ( stratigraphicGroupId: string, ) => Promise; + hideContent: () => boolean; }) => { const [stratColumnObject, setStratColumnObject] = useState( defaultStratColumnData, @@ -169,12 +171,17 @@ export const StratigrapicGroups = ({ {stratColumnGroups.map((row) => ( - + {hideContent() && ( + + )} {row.country.identifier} @@ -221,9 +228,11 @@ export const StratigrapicGroups = ({ )}
- + {hideContent() && ( + + )}
Add stratigraphic column diff --git a/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx b/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx index 56abdf7..4737009 100644 --- a/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx +++ b/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx @@ -21,6 +21,7 @@ export const CaseButtons = ({ saved, isProcessed, caseStatus, + isOwner, hasUnsavedCase, saveCase, runCase, @@ -33,6 +34,7 @@ export const CaseButtons = ({ saved: boolean; isProcessed?: boolean; caseStatus: ComputeJobStatus; + isOwner: () => boolean; hasUnsavedCase: boolean; runCase?: () => void; saveCase: () => void; @@ -60,7 +62,7 @@ export const CaseButtons = ({ return ( - {id.length < 3 ? ( + {id.length < 3 || !isOwner() ? ( + {hideContent() && ( + + )} ); }; diff --git a/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx b/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx index 72dc860..10ffaea 100644 --- a/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx +++ b/src/features/ModelView/ModelMetadataView/ModelMetadataView.tsx @@ -25,6 +25,7 @@ import { useFetchModel } from '../../../hooks/useFetchModel'; import { EditNameDescription } from '../EditNameDescription/EditNameDescription'; import * as Styled from './ModelMetadataView.styled'; import { getAnalogueModelImage } from '../../../api/custom/getAnalogueModelImageById'; +import { isOwnerOrAdmin } from '../../../utils/IsOwnerOrAdmin'; export const ModelMetadataView = ({ modelIdParent, @@ -243,6 +244,10 @@ export const ModelMetadataView = ({ } }; + const hideContent = () => { + return isOwnerOrAdmin(data?.data.createdBy); + }; + if (isLoading || !data?.success) return

Loading ...

; return ( @@ -259,13 +264,15 @@ export const ModelMetadataView = ({ )} - + {hideContent() && ( + + )}
@@ -335,6 +343,7 @@ export const ModelMetadataView = ({ defaultMetadata={defaultMetadata} stratColumnGroups={data.data.stratigraphicGroups} deleteStratColRow={deleteStratColRow} + hideContent={hideContent} />
@@ -343,6 +352,7 @@ export const ModelMetadataView = ({ defaultMetadata={defaultMetadata} gdeGroups={data.data.geologicalGroups} deleteGdeRow={deleteGdeRow} + hideContent={hideContent} />
diff --git a/src/features/ModelView/ModelView.tsx b/src/features/ModelView/ModelView.tsx index 4282d89..f61a5e8 100644 --- a/src/features/ModelView/ModelView.tsx +++ b/src/features/ModelView/ModelView.tsx @@ -5,21 +5,31 @@ import { DeleteModel } from './DeleteButton/DeleteModel'; import { ModelAreaCoordinates } from './ModelAreaCoordinates/ModelAreaCoordinates'; import { ModelFilesView } from './ModelFilesView/ModelFilesView'; import * as Styled from './ModelView.styled'; +import { useFetchModel } from '../../hooks/useFetchModel'; +import { isOwnerOrAdmin } from '../../utils/IsOwnerOrAdmin'; export const ModelView = () => { + const { data } = useFetchModel(); const [open, setOpen] = useState(false); const toggleOpen = () => { setOpen(!open); }; + const hideContent = () => { + return isOwnerOrAdmin(data?.data?.createdBy); + }; + return ( <> - + - + diff --git a/src/pages/Browse/Browse.tsx b/src/pages/Browse/Browse.tsx index 330e774..2e163ae 100644 --- a/src/pages/Browse/Browse.tsx +++ b/src/pages/Browse/Browse.tsx @@ -5,6 +5,7 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { ModelTable } from '../../features/ModelTable/ModelTable'; import * as Styled from './Browse.styled'; +import { isOwnerOrAdmin } from '../../utils/IsOwnerOrAdmin'; export const Browse = () => { const [uploadStatus, setUploadStatus] = useState(); @@ -19,13 +20,23 @@ export const Browse = () => { navigate('/add-model'); } + function disableButton() { + return isOwnerOrAdmin(); + } + return ( <> Browse all models -
- -
+ {disableButton() ? ( +
+ +
+ ) : ( + <> + )}
{ const [showAlert, setAlert] = useState(); const { modelId } = useParams<{ modelId: string }>(); + const model = useFetchModel(); function clearStatus() { setAlert(undefined); @@ -32,6 +35,10 @@ export const ComputeObject = () => { const { data } = useFetchCases(); + const isOwner = () => { + return isOwnerOrAdmin(model?.data?.data.createdBy); + }; + const computeObject = useMutation({ mutationFn: JobsService.postApiJobsComputeObjectEstimations, onSuccess: () => { @@ -71,6 +78,7 @@ export const ComputeObject = () => { methodName="Channel" setAlertMessage={setAlertMessage} runCase={runComputeObject} + isOwner={isOwner} /> { methodName="Mouthbar" setAlertMessage={setAlertMessage} runCase={runComputeObject} + isOwner={isOwner} /> { const [triggerAddCase, setTriggerAddCase] = useState(); const [localCaseList, setLocalCaseList] = useState>([]); const { modelId } = useParams<{ modelId: string }>(); + const model = useFetchModel(); + + const isOwner = () => { + return isOwnerOrAdmin(model?.data?.data.createdBy); + }; const updateLocalCaseList = (type: string, add: boolean) => { if (add) { @@ -102,7 +109,8 @@ export const ComputeVariogram = () => { onClick={() => addCase('Indicator')} disabled={ triggerAddCase?.includes('Indicator') || - localCaseList?.includes('Indicator') + localCaseList?.includes('Indicator') || + !isOwner() } > @@ -113,7 +121,8 @@ export const ComputeVariogram = () => { onClick={() => addCase('Net-To-Gross')} disabled={ triggerAddCase?.includes('Net-To-Gross') || - localCaseList?.includes('Net-To-Gross') + localCaseList?.includes('Net-To-Gross') || + !isOwner() } > @@ -124,7 +133,8 @@ export const ComputeVariogram = () => { onClick={() => addCase('ContiniousParameter')} disabled={ triggerAddCase?.includes('ContiniousParameter') || - localCaseList?.includes('ContiniousParameter') + localCaseList?.includes('ContiniousParameter') || + !isOwner() } > @@ -155,6 +165,7 @@ export const ComputeVariogram = () => { setAlertMessage={setAlertMessage} updateLocalCaseList={updateLocalCaseList} runCase={runComputeVariogram} + isOwner={isOwner} /> { setAlertMessage={setAlertMessage} updateLocalCaseList={updateLocalCaseList} runCase={runComputeVariogram} + isOwner={isOwner} /> { setAlertMessage={setAlertMessage} updateLocalCaseList={updateLocalCaseList} runCase={runComputeVariogram} + isOwner={isOwner} /> Date: Mon, 21 Oct 2024 14:20:26 +0200 Subject: [PATCH 3/5] Update src/pages/Browse/Browse.tsx Co-authored-by: Mathias Oppedal Heggelund <98742460+mheggelund@users.noreply.github.com> --- src/pages/Browse/Browse.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/Browse/Browse.tsx b/src/pages/Browse/Browse.tsx index 2e163ae..eda370f 100644 --- a/src/pages/Browse/Browse.tsx +++ b/src/pages/Browse/Browse.tsx @@ -20,9 +20,7 @@ export const Browse = () => { navigate('/add-model'); } - function disableButton() { - return isOwnerOrAdmin(); - } + return ( <> From 663d92f6e250ff95c331608f109a4c3f842db7f1 Mon Sep 17 00:00:00 2001 From: Thomas Lund Fagermyr <35408743+thomaslf97@users.noreply.github.com> Date: Mon, 21 Oct 2024 14:20:33 +0200 Subject: [PATCH 4/5] Update src/pages/Browse/Browse.tsx Co-authored-by: Mathias Oppedal Heggelund <98742460+mheggelund@users.noreply.github.com> --- src/pages/Browse/Browse.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Browse/Browse.tsx b/src/pages/Browse/Browse.tsx index eda370f..b065ada 100644 --- a/src/pages/Browse/Browse.tsx +++ b/src/pages/Browse/Browse.tsx @@ -26,9 +26,9 @@ export const Browse = () => { <> Browse all models - {disableButton() ? ( + {isOwnerOrAdmin() ? (
-
From a4eeb32e3291566cf6da4557690c96442ab58beb Mon Sep 17 00:00:00 2001 From: Thomas L Fagermyr Date: Wed, 23 Oct 2024 10:36:02 +0200 Subject: [PATCH 5/5] feat: Added tooltip when button is disabled --- .../Compute/CaseGroup/CaseButtons/CaseButtons.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx b/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx index 4737009..64f6522 100644 --- a/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx +++ b/src/features/Compute/CaseGroup/CaseButtons/CaseButtons.tsx @@ -60,10 +60,21 @@ export const CaseButtons = ({ setDeleteConfirm(false); }; + const deleteTooltip = () => { + if (!isOwner()) return 'Can not delete because you are not owner or admin.'; + return 'Can not delete unsaved case.'; + }; + + const duplicateTooltip = () => { + if (!isOwner()) + return 'Can not duplicate because you are not owner or admin.'; + return 'Can not duplicate unsaved case.'; + }; + return ( {id.length < 3 || !isOwner() ? ( - + @@ -81,7 +92,7 @@ export const CaseButtons = ({ {caseType === 'Variogram' && ( <> {id.length < 3 || !isOwner() ? ( - +