= ({ selectedElemen
onClick={() => {
setShowPopupEditor(true);
}}
+ disabled={readOnly}
>
Add Description
diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/image-selection-section.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/image-selection-section.tsx
index 689fb272d..cdf9a3bfe 100644
--- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/image-selection-section.tsx
+++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/image-selection-section.tsx
@@ -14,6 +14,7 @@ import { EntityType } from '@/lib/helpers/fileManagerHelpers';
type ImageSelectionSectionProperties = {
imageFileName?: string;
onImageUpdate: (imageFileName?: string) => void;
+ readOnly?: boolean;
};
export const fallbackImage =
@@ -22,6 +23,7 @@ export const fallbackImage =
const ImageSelectionSection: React.FC
= ({
imageFileName,
onImageUpdate,
+ readOnly = false,
}) => {
const { processId } = useParams();
const { fileUrl: imageUrlfm, download: getImageURL } = useFileManager({
@@ -85,6 +87,7 @@ const ImageSelectionSection: React.FC = ({
useDefaultRemoveFunction: true,
fileName: imageFileName,
}}
+ readOnly={readOnly}
/>
),
}}
diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/milestone-selection-section.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/milestone-selection-section.tsx
index f6fe5b877..ce09eb4da 100644
--- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/milestone-selection-section.tsx
+++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/milestone-selection-section.tsx
@@ -136,9 +136,13 @@ const MilestoneDescriptionViewer: React.FC
type MilestoneSelectionProperties = {
selectedElement: ElementLike;
+ readOnly?: boolean;
};
-const MilestoneSelection: React.FC = ({ selectedElement }) => {
+const MilestoneSelection: React.FC = ({
+ selectedElement,
+ readOnly = false,
+}) => {
const [isMilestoneModalOpen, setIsMilestoneModalOpen] = useState(false);
const [initialMilestoneValues, setInitialMilestoneValues] = useState<
| {
@@ -239,11 +243,13 @@ const MilestoneSelection: React.FC = ({ selectedEl
onClick={() => {
openMilestoneModal(record);
}}
+ disabled={readOnly}
/>
{
removeMilestone(record.id);
}}
+ disabled={readOnly}
/>
),
@@ -261,6 +267,7 @@ const MilestoneSelection: React.FC = ({ selectedEl
size="small"
style={{ fontSize: '0.75rem' }}
icon={}
+ disabled={readOnly}
>
Add Milestone
diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler-toolbar.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler-toolbar.tsx
index 1babccc1b..1c2fa7076 100644
--- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler-toolbar.tsx
+++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler-toolbar.tsx
@@ -16,7 +16,7 @@ import Icon, {
import { SvgXML } from '@/components/svg';
import PropertiesPanel from './properties-panel';
import useModelerStateStore from './use-modeler-state-store';
-import { useRouter, useSearchParams } from 'next/navigation';
+import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import ProcessExportModal from '@/components/process-export';
import VersionCreationButton from '@/components/version-creation-button';
import useMobileModeler from '@/lib/useMobileModeler';
@@ -50,6 +50,7 @@ const ModelerToolbar = ({
versions,
}: ModelerToolbarProps) => {
const router = useRouter();
+ const pathname = usePathname();
const environment = useEnvironment();
const { message } = App.useApp();
const env = use(EnvVarsContext);
@@ -67,6 +68,9 @@ const ModelerToolbar = ({
const query = useSearchParams();
const subprocessId = query.get('subprocess');
+ const processContextPath = pathname.split('/').slice(0, -1).join('/'); // Component can be used in /processes/list or /processes/editor route
+ const isReadOnlyListView = processContextPath.includes('/list');
+
const modeler = useModelerStateStore((state) => state.modeler);
const selectedElementId = useModelerStateStore((state) => state.selectedElementId);
const selectedElement = modeler
@@ -244,16 +248,18 @@ const ModelerToolbar = ({
router.push(
spaceURL(
environment,
- `/processes/${processId as string}${
+ `${processContextPath}/${processId as string}${
searchParams.size ? '?' + searchParams.toString() : ''
}`,
),
);
}}
- options={[LATEST_VERSION].concat(versions ?? []).map(({ id, name }) => ({
- value: id,
- label: name,
- }))}
+ options={(isReadOnlyListView ? [] : [LATEST_VERSION])
+ .concat(versions ?? [])
+ .map(({ id, name }) => ({
+ value: id,
+ label: name,
+ }))}
/>
{!showMobileView && (
<>
@@ -261,6 +267,7 @@ const ModelerToolbar = ({
}
createVersion={createProcessVersion}
+ disabled={isReadOnlyListView}
>
@@ -282,11 +289,13 @@ const ModelerToolbar = ({
{selectedElement &&
- ((env.PROCEED_PUBLIC_ENABLE_EXECUTION && bpmnIs(selectedElement, 'bpmn:UserTask') && (
-
- } onClick={() => setShowUserTaskEditor(true)} />
-
- )) ||
+ ((env.PROCEED_PUBLIC_ENABLE_EXECUTION &&
+ bpmnIs(selectedElement, 'bpmn:UserTask') &&
+ !isReadOnlyListView && (
+
+ } onClick={() => setShowUserTaskEditor(true)} />
+
+ )) ||
(bpmnIs(selectedElement, 'bpmn:SubProcess') && selectedElement.collapsed && (
)) ||
(env.PROCEED_PUBLIC_ENABLE_EXECUTION &&
- bpmnIs(selectedElement, 'bpmn:ScriptTask') && (
+ bpmnIs(selectedElement, 'bpmn:ScriptTask') &&
+ !isReadOnlyListView && (
}
@@ -346,6 +356,7 @@ const ModelerToolbar = ({
isOpen={showPropertiesPanel}
close={handlePropertiesPanelToggle}
selectedElement={selectedElement}
+ readOnly={isReadOnlyListView}
/>
)}
diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler.tsx
index a31dbd9df..7f1ee423c 100644
--- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler.tsx
+++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/modeler.tsx
@@ -79,12 +79,14 @@ const Modeler = ({ versionName, process, versions, ...divProps }: ModelerProps)
/// Derived State
const minimized = !decodeURIComponent(pathname).includes(process.id);
+ const isReadOnlyListView = decodeURIComponent(pathname).includes('/list/');
+
const selectedVersionId = query.get('version');
const subprocessId = query.get('subprocess');
const showMobileView = useMobileModeler();
- const canEdit = !selectedVersionId && !showMobileView;
+ const canEdit = !selectedVersionId && !showMobileView && !isReadOnlyListView;
const saveDebounced = useMemo(
() =>
@@ -328,7 +330,9 @@ const Modeler = ({ versionName, process, versions, ...divProps }: ModelerProps)
canUndo={canUndo}
/>
)}
- {selectedVersionId && !showMobileView && }
+ {selectedVersionId && !showMobileView && (
+
+ )}
{!!xmlEditorBpmn && (
void;
+ readOnly?: boolean;
};
const PlannedCostInput: React.FC = ({
costsPlanned: { value, currency = 'EUR' },
onInput,
+ readOnly = false,
}) => {
const [costsPlanned, setCostsPlanned] = useState<{ value?: number; currency: string }>({
value,
@@ -69,6 +71,7 @@ const PlannedCostInput: React.FC = ({
}).format(costsPlanned.value)
: costsPlanned.value
}
+ disabled={readOnly}
/>
);
};
diff --git a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/planned-duration-input.tsx b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/planned-duration-input.tsx
index a6efd20e8..9f08e4ce3 100644
--- a/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/planned-duration-input.tsx
+++ b/src/management-system-v2/app/(dashboard)/[environmentId]/processes/[processId]/planned-duration-input.tsx
@@ -106,11 +106,13 @@ const PlannedDurationModal: React.FC = ({
type PlannedDurationInputProperties = {
timePlannedDuration: string;
onChange: (changedTimePlannedDuration: string) => void;
+ readOnly?: boolean;
};
const PlannedDurationInput: React.FC = ({
timePlannedDuration,
onChange,
+ readOnly = false,
}) => {
const [isPlannedDurationModalOpen, setIsPlannedDurationModalOpen] = useState(false);
@@ -154,6 +156,7 @@ const PlannedDurationInput: React.FC = ({
value={durationString}
placeholder="Planned Duration"
onClick={() => setIsPlannedDurationModalOpen(true)}
+ disabled={readOnly}
/>
= ({
selectedElement,
+ readOnly = false,
}) => {
const router = useRouter();
const { spaceId } = useEnvironment();
@@ -170,6 +172,7 @@ const PropertiesPanelContent: React.FC = ({
value={name}
onChange={(e) => setName(e.target.value)}
onBlur={handleNameChange}
+ disabled={readOnly}
/>
= ({
onImageUpdate={(imageFileName) => {
updateMetaData('overviewImage', imageFileName);
}}
+ readOnly={readOnly}
>
-
+
-
+
Properties
@@ -205,12 +215,14 @@ const PropertiesPanelContent: React.FC = ({
onInput={({ value, currency }) => {
updateMetaData('costsPlanned', value, { unit: currency });
}}
+ readOnly={readOnly}
>
{
updateMetaData('timePlannedDuration', changedTimePlannedDuration);
}}
timePlannedDuration={timePlannedDuration || ''}
+ readOnly={readOnly}
>
@@ -228,6 +240,7 @@ const PropertiesPanelContent: React.FC = ({
: undefined,
);
}}
+ readOnly={readOnly}
>
{selectedElement.type !== 'bpmn:Process' && (
@@ -240,6 +253,7 @@ const PropertiesPanelContent: React.FC = ({
presets={colorPickerPresets}
value={backgroundColor}
onChange={(_, hex) => updateBackgroundColor(hex)}
+ disabled={readOnly}
/>
Background Colour
@@ -250,6 +264,7 @@ const PropertiesPanelContent: React.FC = ({
presets={colorPickerPresets}
value={strokeColor}
onChange={(_, hex) => updateStrokeColor(hex)}
+ disabled={readOnly}
/>
Stroke Colour
@@ -263,12 +278,14 @@ type PropertiesPanelProperties = {
selectedElement: ElementLike;
isOpen: boolean;
close: () => void;
+ readOnly?: boolean;
};
const PropertiesPanel: React.FC = ({
selectedElement,
isOpen,
close,
+ readOnly = false,
}) => {
const [showInfo, setShowInfo] = useState(true);
@@ -303,7 +320,10 @@ const PropertiesPanel: React.FC = ({
title="Properties"
collapsedWidth="40px"
>
-
+
) : (
@@ -326,7 +346,10 @@ const PropertiesPanel: React.FC = ({
}
>
-