diff --git a/spiffworkflow-backend/bin/run_local_python_script b/spiffworkflow-backend/bin/run_local_python_script
index 83f3ddd12..e8683fa86 100755
--- a/spiffworkflow-backend/bin/run_local_python_script
+++ b/spiffworkflow-backend/bin/run_local_python_script
@@ -17,4 +17,4 @@ script_dir="$(
export SPIFFWORKFLOW_BACKEND_RUN_BACKGROUND_SCHEDULER_IN_CREATE_APP=false
-exec poet run python "$script" "$@"
+exec poetry run python "$script" "$@"
diff --git a/spiffworkflow-frontend/src/components/ProcessModelFileList.tsx b/spiffworkflow-frontend/src/components/ProcessModelFileList.tsx
new file mode 100644
index 000000000..1260a89ed
--- /dev/null
+++ b/spiffworkflow-frontend/src/components/ProcessModelFileList.tsx
@@ -0,0 +1,218 @@
+import React from 'react';
+import { Link } from 'react-router-dom';
+import { Download, Edit, Favorite, TrashCan, View } from '@carbon/icons-react';
+import {
+ Button,
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from '@carbon/react';
+import { Can } from '@casl/react';
+import { PureAbility } from '@casl/ability';
+import ButtonWithConfirmation from './ButtonWithConfirmation';
+import ProcessModelTestRun from './ProcessModelTestRun';
+import { ProcessFile } from '../interfaces';
+
+interface ProcessModelFileListProps {
+ processModel: any;
+ ability: PureAbility;
+ targetUris: any;
+ modifiedProcessModelId: string;
+ onDeleteFile: (fileName: string) => void;
+ onSetPrimaryFile: (fileName: string) => void;
+ isTestCaseFile: (processModelFile: ProcessFile) => boolean;
+}
+
+export default function ProcessModelFileList({
+ processModel,
+ ability,
+ targetUris,
+ modifiedProcessModelId,
+ onDeleteFile,
+ onSetPrimaryFile,
+ isTestCaseFile,
+}: ProcessModelFileListProps) {
+ const profileModelFileEditUrl = (processModelFile: ProcessFile) => {
+ if (processModel) {
+ if (processModelFile.name.match(/\.(dmn|bpmn)$/)) {
+ return `/editor/process-models/${modifiedProcessModelId}/files/${processModelFile.name}`;
+ }
+ if (processModelFile.name.match(/\.(json|md)$/)) {
+ return `/process-models/${modifiedProcessModelId}/form/${processModelFile.name}`;
+ }
+ }
+ return null;
+ };
+
+ const renderButtonElements = (
+ processModelFile: ProcessFile,
+ isPrimaryBpmnFile: boolean,
+ ) => {
+ const elements = [];
+
+ let icon = View;
+ let actionWord = 'View';
+ if (ability.can('PUT', targetUris.processModelFileCreatePath)) {
+ icon = Edit;
+ actionWord = 'Edit';
+ }
+ elements.push(
+
+
+ ,
+ );
+ elements.push(
+
+
+ window.open(
+ `/${targetUris.processModelFilePath}/${processModelFile.name}`,
+ '_blank',
+ )
+ }
+ />
+ ,
+ );
+
+ if (!isPrimaryBpmnFile) {
+ elements.push(
+
+ {
+ onDeleteFile(processModelFile.name);
+ }}
+ confirmButtonLabel="Delete"
+ classNameForModal="modal-within-table-cell"
+ />
+ ,
+ );
+ }
+ if (processModelFile.name.match(/\.bpmn$/) && !isPrimaryBpmnFile) {
+ elements.push(
+
+ onSetPrimaryFile(processModelFile.name)}
+ />
+ ,
+ );
+ }
+ if (isTestCaseFile(processModelFile)) {
+ elements.push(
+
+
+ ,
+ );
+ }
+ return elements;
+ };
+
+ if (!processModel) {
+ return null;
+ }
+
+ const tags = processModel.files
+ .map((processModelFile: ProcessFile) => {
+ if (!processModelFile.name.match(/\.(dmn|bpmn|json|md)$/)) {
+ return undefined;
+ }
+ const isPrimaryBpmnFile =
+ processModelFile.name === processModel.primary_file_name;
+
+ const actionsTableCell = (
+
+ {renderButtonElements(processModelFile, isPrimaryBpmnFile)}
+
+ );
+
+ let primarySuffix = null;
+ if (isPrimaryBpmnFile) {
+ primarySuffix = (
+
+ -{' '}
+ Primary File
+
+ );
+ }
+ let fileLink = null;
+ const fileUrl = profileModelFileEditUrl(processModelFile);
+ if (fileUrl) {
+ fileLink = {processModelFile.name};
+ }
+ return (
+
+
+ {fileLink}
+ {primarySuffix}
+
+ {actionsTableCell}
+
+ );
+ })
+ .filter((element: any) => element !== undefined);
+
+ if (tags.length === 0) {
+ return null;
+ }
+
+ return (
+
+
+
+
+ Name
+
+
+ Actions
+
+
+
+ {tags}
+
+ );
+}
diff --git a/spiffworkflow-frontend/src/components/ProcessModelFileUploadModal.tsx b/spiffworkflow-frontend/src/components/ProcessModelFileUploadModal.tsx
new file mode 100644
index 000000000..4cae0e56a
--- /dev/null
+++ b/spiffworkflow-frontend/src/components/ProcessModelFileUploadModal.tsx
@@ -0,0 +1,114 @@
+import React, { useState } from 'react';
+import { FileUploader, Modal } from '@carbon/react';
+
+interface ProcessModelFileUploadModalProps {
+ showFileUploadModal: boolean;
+ processModel: any;
+ handleFileUploadCancel: () => void;
+ checkDuplicateFile: (files: File[], forceOverwrite?: boolean) => void;
+ doFileUpload: Function;
+ setShowFileUploadModal: Function;
+}
+
+export default function ProcessModelFileUploadModal({
+ showFileUploadModal,
+ processModel,
+ handleFileUploadCancel,
+ checkDuplicateFile,
+ doFileUpload,
+ setShowFileUploadModal,
+}: ProcessModelFileUploadModalProps) {
+ const [filesToUpload, setFilesToUpload] = useState(null);
+ const [duplicateFilename, setDuplicateFilename] = useState('');
+ const [showOverwriteConfirmationPrompt, setShowOverwriteConfirmationPrompt] =
+ useState(false);
+
+ const handleOverwriteFileConfirm = () => {
+ setShowOverwriteConfirmationPrompt(false);
+ doFileUpload(filesToUpload);
+ };
+
+ const handleOverwriteFileCancel = () => {
+ setShowFileUploadModal(true);
+ setShowOverwriteConfirmationPrompt(false);
+ };
+
+ const displayOverwriteConfirmation = (filename: string) => {
+ setDuplicateFilename(filename);
+ setShowFileUploadModal(false);
+ setShowOverwriteConfirmationPrompt(true);
+ };
+
+ const handleLocalFileUpload = () => {
+ if (!filesToUpload) {
+ return;
+ }
+ if (processModel) {
+ let foundExistingFile = false;
+ if (processModel.files && processModel.files.length > 0) {
+ processModel.files.forEach((file: { name: string }) => {
+ if (file.name === filesToUpload[0].name) {
+ foundExistingFile = true;
+ }
+ });
+ }
+ if (foundExistingFile) {
+ displayOverwriteConfirmation(filesToUpload[0].name);
+ } else {
+ checkDuplicateFile(filesToUpload);
+ setShowOverwriteConfirmationPrompt(false);
+ }
+ }
+ };
+
+ const confirmOverwriteFileDialog = () => {
+ return (
+
+ );
+ };
+
+ return (
+ <>
+ {confirmOverwriteFileDialog()}
+
+ setFilesToUpload(null)}
+ onChange={(event: any) => setFilesToUpload(event.target.files)}
+ />
+
+ >
+ );
+}
diff --git a/spiffworkflow-frontend/src/components/ProcessModelReadmeArea.tsx b/spiffworkflow-frontend/src/components/ProcessModelReadmeArea.tsx
new file mode 100644
index 000000000..490622c88
--- /dev/null
+++ b/spiffworkflow-frontend/src/components/ProcessModelReadmeArea.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import { Button, Column, Grid } from '@carbon/react';
+import { Can } from '@casl/react';
+import { Edit } from '@carbon/icons-react';
+import { PureAbility } from '@casl/ability';
+import MarkdownDisplayForFile from './MarkdownDisplayForFile';
+import { ProcessFile } from '../interfaces';
+
+interface ProcessModelReadmeAreaProps {
+ readmeFile: ProcessFile | null;
+ ability: PureAbility;
+ targetUris: any;
+ modifiedProcessModelId: string;
+}
+
+export default function ProcessModelReadmeArea({
+ readmeFile,
+ ability,
+ targetUris,
+ modifiedProcessModelId,
+}: ProcessModelReadmeAreaProps) {
+ if (readmeFile) {
+ return (
+
+
+
+ {readmeFile.name}
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+ return (
+ <>
+ No README file found
+
+
+ Add README.md
+
+
+ >
+ );
+}
diff --git a/spiffworkflow-frontend/src/components/ProcessModelTabs.tsx b/spiffworkflow-frontend/src/components/ProcessModelTabs.tsx
new file mode 100644
index 000000000..37f8e03ea
--- /dev/null
+++ b/spiffworkflow-frontend/src/components/ProcessModelTabs.tsx
@@ -0,0 +1,187 @@
+import React from 'react';
+import {
+ Column,
+ Dropdown,
+ Grid,
+ Tab,
+ TabList,
+ TabPanel,
+ TabPanels,
+ Tabs,
+} from '@carbon/react';
+import { Can } from '@casl/react'; // Corrected import
+import { useNavigate } from 'react-router-dom';
+import { PureAbility } from '@casl/ability';
+import ProcessInstanceListTable from './ProcessInstanceListTable';
+import ProcessModelFileList from './ProcessModelFileList';
+import { ProcessFile } from '../interfaces';
+import ProcessModelReadmeArea from './ProcessModelReadmeArea';
+
+interface ProcessModelTabsProps {
+ processModel: any;
+ ability: PureAbility;
+ targetUris: any;
+ modifiedProcessModelId: string;
+ selectedTabIndex: number;
+ updateSelectedTab: (newTabIndex: any) => void;
+ onDeleteFile: (fileName: string) => void;
+ onSetPrimaryFile: (fileName: string) => void;
+ isTestCaseFile: (processModelFile: ProcessFile) => boolean;
+ readmeFile: ProcessFile | null;
+ setShowFileUploadModal: Function;
+}
+
+export default function ProcessModelTabs({
+ processModel,
+ ability,
+ targetUris,
+ modifiedProcessModelId,
+ selectedTabIndex,
+ updateSelectedTab,
+ onDeleteFile,
+ onSetPrimaryFile,
+ isTestCaseFile,
+ readmeFile,
+ setShowFileUploadModal,
+}: ProcessModelTabsProps) {
+ const navigate = useNavigate();
+
+ if (!processModel) {
+ return null;
+ }
+
+ let helpText = null;
+ if (processModel.files.length === 0) {
+ helpText = (
+
+
+ **This process model does not have any files associated with it. Try
+ creating a bpmn file by selecting "New BPMN File" in the
+ dropdown below.**
+
+
+ );
+ }
+
+ const items = [
+ 'Upload File',
+ 'New BPMN File',
+ 'New DMN File',
+ 'New JSON File',
+ 'New Markdown File',
+ ].map((item) => ({
+ text: item,
+ }));
+
+ const addFileComponent = () => {
+ return (
+ {
+ if (a.selectedItem.text === 'New BPMN File') {
+ navigate(
+ `/editor/process-models/${modifiedProcessModelId}/files?file_type=bpmn`,
+ );
+ } else if (a.selectedItem.text === 'Upload File') {
+ // Handled by parent component via prop
+ updateSelectedTab({ selectedIndex: 1 }); // Switch to Files tab
+ // Open file upload modal (handled by parent)
+ setShowFileUploadModal(true);
+ } else if (a.selectedItem.text === 'New DMN File') {
+ navigate(
+ `/editor/process-models/${modifiedProcessModelId}/files?file_type=dmn`,
+ );
+ } else if (a.selectedItem.text === 'New JSON File') {
+ navigate(
+ `/process-models/${modifiedProcessModelId}/form?file_ext=json`,
+ );
+ } else if (a.selectedItem.text === 'New Markdown File') {
+ navigate(
+ `/process-models/${modifiedProcessModelId}/form?file_ext=md`,
+ );
+ }
+ }}
+ items={items}
+ itemToString={(item: any) => (item ? item.text : '')}
+ />
+ );
+ };
+
+ return (
+
+
+ About
+ Files
+ My process instances
+
+
+
+ {readmeFile && (
+
+ )}
+
+
+
+
+
+ {helpText}
+
+ Files
+ {processModel &&
+ processModel.bpmn_version_control_identifier &&
+ ` (revision ${processModel.bpmn_version_control_identifier})`}
+
+ {addFileComponent()}
+
+
+
+
+
+
+
+ {selectedTabIndex !== 2 ? null : (
+
+
+
+ )}
+
+
+
+ );
+}
diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx
index 4f03c1864..97a6a9d99 100644
--- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx
+++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx
@@ -1,33 +1,7 @@
-import { useEffect, useState } from 'react';
-import { Link, useNavigate, useParams } from 'react-router-dom';
-import {
- Download,
- Edit,
- Favorite,
- TrashCan,
- Upload,
- View,
-} from '@carbon/icons-react';
-import {
- Button,
- Column,
- Dropdown,
- FileUploader,
- Grid,
- Modal,
- Stack,
- Table,
- TableBody,
- TableCell,
- TableHead,
- TableHeader,
- TableRow,
- Tabs,
- Tab,
- TabList,
- TabPanels,
- TabPanel,
-} from '@carbon/react';
+import React, { useEffect, useState } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { Upload, Edit, TrashCan } from '@carbon/icons-react';
+import { Button, Stack } from '@carbon/react';
import { Can } from '@casl/react';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import HttpService from '../services/HttpService';
@@ -45,8 +19,8 @@ import { useUriListForPermissions } from '../hooks/UriListForPermissions';
import ProcessInstanceRun from '../components/ProcessInstanceRun';
import { Notification } from '../components/Notification';
import ProcessModelTestRun from '../components/ProcessModelTestRun';
-import MarkdownDisplayForFile from '../components/MarkdownDisplayForFile';
-import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
+import ProcessModelTabs from '../components/ProcessModelTabs';
+import ProcessModelFileUploadModal from '../components/ProcessModelFileUploadModal';
export default function ProcessModelShow() {
const params = useParams();
@@ -55,7 +29,6 @@ export default function ProcessModelShow() {
const [processModel, setProcessModel] = useState(null);
const [reloadModel, setReloadModel] = useState(false);
- const [filesToUpload, setFilesToUpload] = useState(null);
const [showFileUploadModal, setShowFileUploadModal] =
useState(false);
const [processModelPublished, setProcessModelPublished] = useState(null);
@@ -83,7 +56,7 @@ export default function ProcessModelShow() {
let hasTestCaseFiles: boolean = false;
const isTestCaseFile = (processModelFile: ProcessFile) => {
- return processModelFile.name.match(/^test_.*\.json$/);
+ return !!processModelFile.name.match(/^test_.*\.json$/);
};
if (processModel) {
@@ -99,12 +72,14 @@ export default function ProcessModelShow() {
setPageTitle([result.display_name]);
let newTabIndex = 1;
+ let foundReadme = null;
result.files.forEach((file: ProcessFile) => {
if (file.name === 'README.md') {
- setReadmeFile(file);
+ foundReadme = file;
newTabIndex = 0;
}
});
+ setReadmeFile(foundReadme);
setSelectedTabIndex(newTabIndex);
};
HttpService.makeCallToBackend({
@@ -116,11 +91,11 @@ export default function ProcessModelShow() {
const onUploadedCallback = () => {
setReloadModel(true);
};
+
const reloadModelOhYeah = (_httpResult: any) => {
setReloadModel(!reloadModel);
};
- // Remove this code from
const onDeleteFile = (fileName: string) => {
const url = `/process-models/${modifiedProcessModelId}/files/${fileName}`;
const httpMethod = 'DELETE';
@@ -145,51 +120,6 @@ export default function ProcessModelShow() {
postBody: processModelToPass,
});
};
- const handleProcessModelFileResult = (processModelFile: ProcessFile) => {
- if (
- !('file_contents' in processModelFile) ||
- processModelFile.file_contents === undefined
- ) {
- addError({
- message: `Could not file file contents for file: ${processModelFile.name}`,
- });
- return;
- }
- let contentType = 'application/xml';
- if (processModelFile.type === 'json') {
- contentType = 'application/json';
- }
- const element = document.createElement('a');
- const file = new Blob([processModelFile.file_contents], {
- type: contentType,
- });
- const downloadFileName = processModelFile.name;
- element.href = URL.createObjectURL(file);
- element.download = downloadFileName;
- document.body.appendChild(element);
- element.click();
- };
-
- const downloadFile = (fileName: string) => {
- removeError();
- const processModelPath = `process-models/${modifiedProcessModelId}`;
- HttpService.makeCallToBackend({
- path: `/${processModelPath}/files/${fileName}`,
- successCallback: handleProcessModelFileResult,
- });
- };
-
- const profileModelFileEditUrl = (processModelFile: ProcessFile) => {
- if (processModel) {
- if (processModelFile.name.match(/\.(dmn|bpmn)$/)) {
- return `/editor/process-models/${modifiedProcessModelId}/files/${processModelFile.name}`;
- }
- if (processModelFile.name.match(/\.(json|md)$/)) {
- return `/process-models/${modifiedProcessModelId}/form/${processModelFile.name}`;
- }
- }
- return null;
- };
const navigateToProcessModels = (_result: any) => {
navigate(
@@ -220,202 +150,17 @@ export default function ProcessModelShow() {
});
};
- const navigateToFileEdit = (processModelFile: ProcessFile) => {
- const url = profileModelFileEditUrl(processModelFile);
- if (url) {
- navigate(url);
+ const doFileUpload = (filesToUpload: File[], forceOverwrite = false) => {
+ if (!filesToUpload || filesToUpload.length === 0) {
+ return; // No files to upload
}
- };
-
- const renderButtonElements = (
- processModelFile: ProcessFile,
- isPrimaryBpmnFile: boolean,
- ) => {
- const elements = [];
-
- // So there is a bug in here. Since we use a react context for error messages, and since
- // its provider wraps the entire app, child components will re-render when there is an
- // error displayed. This is normally fine, but it interacts badly with the casl ability.can
- // functionality. We have observed that permissionsLoaded is never set to false. So when
- // you run a process and it fails, for example, process model show will re-render, the ability
- // will be cleared out and it will start fetching permissions from the server, but this
- // component still thinks permissionsLoaded is telling the truth (it says true, but it's actually false).
- // The only bad effect that we know of is that the Edit icon becomes an eye icon even for admins.
- let icon = View;
- let actionWord = 'View';
- if (ability.can('PUT', targetUris.processModelFileCreatePath)) {
- icon = Edit;
- actionWord = 'Edit';
- }
- elements.push(
-
- navigateToFileEdit(processModelFile)}
- />
- ,
- );
- elements.push(
-
- downloadFile(processModelFile.name)}
- />
- ,
- );
-
- if (!isPrimaryBpmnFile) {
- elements.push(
-
- {
- onDeleteFile(processModelFile.name);
- }}
- confirmButtonLabel="Delete"
- classNameForModal="modal-within-table-cell"
- />
- ,
- );
- }
- if (processModelFile.name.match(/\.bpmn$/) && !isPrimaryBpmnFile) {
- elements.push(
-
- onSetPrimaryFile(processModelFile.name)}
- />
- ,
- );
- }
- if (isTestCaseFile(processModelFile)) {
- elements.push(
-
-
- ,
- );
- }
- return elements;
- };
-
- const processModelFileList = () => {
- if (!processModel || !permissionsLoaded) {
- return null;
- }
- let constructedTag;
- const tags = processModel.files
- .map((processModelFile: ProcessFile) => {
- if (!processModelFile.name.match(/\.(dmn|bpmn|json|md)$/)) {
- return undefined;
- }
- const isPrimaryBpmnFile =
- processModelFile.name === processModel.primary_file_name;
-
- let actionsTableCell = null;
- if (processModelFile.name.match(/\.(dmn|bpmn|json|md)$/)) {
- actionsTableCell = (
-
- {renderButtonElements(processModelFile, isPrimaryBpmnFile)}
-
- );
- }
-
- let primarySuffix = null;
- if (isPrimaryBpmnFile) {
- primarySuffix = (
-
- -{' '}
- Primary File
-
- );
- }
- let fileLink = null;
- const fileUrl = profileModelFileEditUrl(processModelFile);
- if (fileUrl) {
- fileLink = {processModelFile.name};
- }
- constructedTag = (
-
-
- {fileLink}
- {primarySuffix}
-
- {actionsTableCell}
-
- );
- return constructedTag;
- })
- .filter((element: any) => element !== undefined);
-
- if (tags.length > 0) {
- return (
-
-
-
-
- Name
-
-
- Actions
-
-
-
- {tags}
-
- );
- }
- return null;
- };
-
- const [fileUploadEvent, setFileUploadEvent] = useState(null);
- const [duplicateFilename, setDuplicateFilename] = useState('');
- const [showOverwriteConfirmationPrompt, setShowOverwriteConfirmationPrompt] =
- useState(false);
-
- const doFileUpload = (event: any) => {
- event.preventDefault();
removeError();
const url = `/process-models/${modifiedProcessModelId}/files`;
const formData = new FormData();
formData.append('file', filesToUpload[0]);
formData.append('fileName', filesToUpload[0].name);
+ formData.append('overwrite', forceOverwrite.toString()); // Add overwrite parameter
+
HttpService.makeCallToBackend({
path: url,
successCallback: onUploadedCallback,
@@ -423,279 +168,25 @@ export default function ProcessModelShow() {
postBody: formData,
failureCallback: addError,
});
- setFilesToUpload(null);
};
const handleFileUploadCancel = () => {
setShowFileUploadModal(false);
- setFilesToUpload(null);
- };
- const handleOverwriteFileConfirm = () => {
- setShowOverwriteConfirmationPrompt(false);
- doFileUpload(fileUploadEvent);
- };
- const handleOverwriteFileCancel = () => {
- setShowOverwriteConfirmationPrompt(false);
- setFilesToUpload(null);
};
- const confirmOverwriteFileDialog = () => {
- return (
-
- );
- };
- const displayOverwriteConfirmation = (filename: string) => {
- setDuplicateFilename(filename);
- setShowOverwriteConfirmationPrompt(true);
- };
-
- const checkDuplicateFile = (event: any) => {
- if (processModel) {
- let foundExistingFile = false;
- if (processModel.files.length > 0) {
- processModel.files.forEach((file) => {
- if (file.name === filesToUpload[0].name) {
- foundExistingFile = true;
- }
- });
- }
- if (foundExistingFile) {
- displayOverwriteConfirmation(filesToUpload[0].name);
- setFileUploadEvent(event);
- } else {
- doFileUpload(event);
- }
+ const checkDuplicateFile = (files: File[], forceOverwrite = false) => {
+ if (forceOverwrite) {
+ doFileUpload(files, true);
+ } else {
+ doFileUpload(files);
}
- return null;
- };
-
- const handleFileUpload = (event: any) => {
- checkDuplicateFile(event);
setShowFileUploadModal(false);
};
- const fileUploadModal = () => {
- return (
-
- setFilesToUpload(null)}
- onChange={(event: any) => setFilesToUpload(event.target.files)}
- />
-
- );
- };
-
- const items = [
- 'Upload File',
- 'New BPMN File',
- 'New DMN File',
- 'New JSON File',
- 'New Markdown File',
- ].map((item) => ({
- text: item,
- }));
-
- const addFileComponent = () => {
- return (
- {
- if (a.selectedItem.text === 'New BPMN File') {
- navigate(
- `/editor/process-models/${modifiedProcessModelId}/files?file_type=bpmn`,
- );
- } else if (a.selectedItem.text === 'Upload File') {
- setShowFileUploadModal(true);
- } else if (a.selectedItem.text === 'New DMN File') {
- navigate(
- `/editor/process-models/${modifiedProcessModelId}/files?file_type=dmn`,
- );
- } else if (a.selectedItem.text === 'New JSON File') {
- navigate(
- `/process-models/${modifiedProcessModelId}/form?file_ext=json`,
- );
- } else if (a.selectedItem.text === 'New Markdown File') {
- navigate(
- `/process-models/${modifiedProcessModelId}/form?file_ext=md`,
- );
- }
- }}
- items={items}
- itemToString={(item: any) => (item ? item.text : '')}
- />
- );
- };
-
- const readmeFileArea = () => {
- if (readmeFile) {
- return (
-
-
-
- {readmeFile.name}
-
-
-
-
-
-
-
-
-
-
- );
- }
- return (
- <>
- No README file found
-
-
- Add README.md
-
-
- >
- );
- };
-
const updateSelectedTab = (newTabIndex: any) => {
setSelectedTabIndex(newTabIndex.selectedIndex);
};
- const tabArea = () => {
- if (!processModel) {
- return null;
- }
-
- let helpText = null;
- if (processModel.files.length === 0) {
- helpText = (
-
-
- **This process model does not have any files associated with it. Try
- creating a bpmn file by selecting "New BPMN File" in the
- dropdown below.**
-
-
- );
- }
-
- return (
-
-
- About
- Files
- My process instances
-
-
- {readmeFileArea()}
-
-
-
-
- {helpText}
-
- Files
- {processModel &&
- processModel.bpmn_version_control_identifier &&
- ` (revision ${processModel.bpmn_version_control_identifier})`}
-
- {addFileComponent()}
-
-
- {processModelFileList()}
-
-
-
-
- {selectedTabIndex !== 2 ? null : (
-
-
-
- )}
-
-
-
- );
- };
-
const processModelPublishMessage = () => {
if (processModelPublished) {
const prUrl: string = processModelPublished.pr_url;
@@ -721,18 +212,20 @@ export default function ProcessModelShow() {
a={targetUris.processInstanceCreatePath}
ability={ability}
>
- <>
-
-
-
- >
+
);
return (
<>
- {fileUploadModal()}
- {confirmOverwriteFileDialog()}
+
{tabArea()}
+
+
+
+
+
{permissionsLoaded ? (
) : null}