From 5f22c0b910316c552f759f59a055e6b190b9cf9f Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 7 Nov 2022 14:23:19 -0500 Subject: [PATCH 1/9] updated the breadcrumb component and added a test for buttons in file dropdown --- .../src/components/ProcessBreadcrumb.tsx | 56 ++++++------- spiffworkflow-frontend/src/index.scss | 26 ++++++ spiffworkflow-frontend/src/interfaces.ts | 2 +- .../src/routes/ProcessModelShow.tsx | 83 +++++++++++++------ 4 files changed, 112 insertions(+), 55 deletions(-) diff --git a/spiffworkflow-frontend/src/components/ProcessBreadcrumb.tsx b/spiffworkflow-frontend/src/components/ProcessBreadcrumb.tsx index 241aaeb7..d5d2eda2 100644 --- a/spiffworkflow-frontend/src/components/ProcessBreadcrumb.tsx +++ b/spiffworkflow-frontend/src/components/ProcessBreadcrumb.tsx @@ -1,12 +1,12 @@ -import { Link } from 'react-router-dom'; -import Breadcrumb from 'react-bootstrap/Breadcrumb'; -import { BreadcrumbItem } from '../interfaces'; +// @ts-ignore +import { Breadcrumb, BreadcrumbItem } from '@carbon/react'; +import { HotCrumbItem } from '../interfaces'; type OwnProps = { processModelId?: string; processGroupId?: string; linkProcessModel?: boolean; - hotCrumbs?: BreadcrumbItem[]; + hotCrumbs?: HotCrumbItem[]; }; export default function ProcessBreadcrumb({ @@ -22,18 +22,20 @@ export default function ProcessBreadcrumb({ if (lastItem === undefined) { return null; } - const lastCrumb = {lastItem[0]}; - const leadingCrumbLinks = hotCrumbs.map((crumb) => { + const lastCrumb = ( + {lastItem[0]} + ); + const leadingCrumbLinks = hotCrumbs.map((crumb: any) => { const valueLabel = crumb[0]; const url = crumb[1]; return ( - + {valueLabel} - + ); }); return ( - + {leadingCrumbLinks} {lastCrumb} @@ -42,42 +44,38 @@ export default function ProcessBreadcrumb({ if (processModelId) { if (linkProcessModel) { processModelBreadcrumb = ( - - Process Model: {processModelId} - + {`Process Model: ${processModelId}`} + ); } else { processModelBreadcrumb = ( - - Process Model: {processModelId} - + + {`Process Model: ${processModelId}`} + ); } processGroupBreadcrumb = ( - - Process Group: {processGroupId} - + {`Process Group: ${processGroupId}`} + ); } else if (processGroupId) { processGroupBreadcrumb = ( - Process Group: {processGroupId} + + {`Process Group: ${processGroupId}`} + ); } return ( - - - Process Groups - + + Process Groups {processGroupBreadcrumb} {processModelBreadcrumb} diff --git a/spiffworkflow-frontend/src/index.scss b/spiffworkflow-frontend/src/index.scss index ee9ca2c2..96dbf3db 100644 --- a/spiffworkflow-frontend/src/index.scss +++ b/spiffworkflow-frontend/src/index.scss @@ -1,10 +1,22 @@ // @use '@carbon/react/scss/themes'; // @use '@carbon/react/scss/theme' with ($theme: themes.$g100); + +@use '@carbon/react/scss/theme' with + ( + $theme: ( + cds-link-text-color: #525252 + ) + ); + @use '@carbon/react'; @use '@carbon/styles'; // @include grid.flex-grid(); +@use '@carbon/colors'; // @use '@carbon/react/scss/colors'; +@use '@carbon/react/scss/themes'; + +// var(--cds-link-text-color, var(--cds-link-primary, #0f62fe)) // site is mainly using white theme. // header is mainly using g100 @@ -13,3 +25,17 @@ // background-color: colors.$gray-100; color: white; } + +.cds--breadcrumb-item a.cds--link:hover { + color: #525252; +} +.cds--breadcrumb-item a.cds--link:visited { + color: #525252; +} +.cds--breadcrumb-item a.cds--link:visited:hover { + color: #525252; +} +.cds--breadcrumb-item a.cds--link { + color: #525252; +} + diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index 14ead3ba..8792c24b 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -25,7 +25,7 @@ export interface ProcessModel { } // tuple of display value and URL -export type BreadcrumbItem = [displayValue: string, url?: string]; +export type HotCrumbItem = [displayValue: string, url?: string]; export interface ErrorForDisplay { message: string; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 30f81e6d..4d55593d 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -1,7 +1,7 @@ import { useContext, useEffect, useState } from 'react'; import { Link, useParams } from 'react-router-dom'; // @ts-ignore -import { Button, Stack } from '@carbon/react'; +import { Grid, Column, Dropdown, Button, Stack } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import FileInput from '../components/FileInput'; import HttpService from '../services/HttpService'; @@ -210,6 +210,54 @@ export default function ProcessModelShow() { }; const processModelButtons = () => { + // + // + // + const items = [ + { + key1: ( + + + + + + + + + ), + }, + ]; return ( - - - + (item ? item.key1 : '')} + onChange={(e: any) => console.log('e', e)} + /> ); }; From 3020c87c986c3e0da8f9a995358377a495df28ae Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 7 Nov 2022 17:32:29 -0500 Subject: [PATCH 2/9] updated process modal show page to use accordion component w/ burnettk --- spiffworkflow-frontend/src/index.css | 4 + spiffworkflow-frontend/src/index.scss | 51 ++- .../src/routes/ProcessModelShow.tsx | 296 ++++++++++-------- 3 files changed, 216 insertions(+), 135 deletions(-) diff --git a/spiffworkflow-frontend/src/index.css b/spiffworkflow-frontend/src/index.css index 988fae27..c9ddd249 100644 --- a/spiffworkflow-frontend/src/index.css +++ b/spiffworkflow-frontend/src/index.css @@ -40,6 +40,10 @@ span.bjs-crumb { opacity: .4; } +.accordion-item-label { + vertical-align: middle; +} + .diagram-editor-canvas { border:1px solid #000000; height:70vh; diff --git a/spiffworkflow-frontend/src/index.scss b/spiffworkflow-frontend/src/index.scss index 96dbf3db..e4a9227d 100644 --- a/spiffworkflow-frontend/src/index.scss +++ b/spiffworkflow-frontend/src/index.scss @@ -1,12 +1,12 @@ // @use '@carbon/react/scss/themes'; // @use '@carbon/react/scss/theme' with ($theme: themes.$g100); -@use '@carbon/react/scss/theme' with - ( - $theme: ( - cds-link-text-color: #525252 - ) - ); +// @use '@carbon/react/scss/theme' with +// ( +// $theme: ( +// cds-link-primary: #525252 +// ) +// ); @use '@carbon/react'; @use '@carbon/styles'; @@ -39,3 +39,42 @@ color: #525252; } +.cds--btn--ghost { + color: black; +} +.cds--btn--ghost:visited { + color: black; +} +.cds--btn--ghost:hover { + color: black; +} +.cds--btn--ghost:visited:hover { + color: black; +} + +$slightly-lighter-gray: #474747; + +.cds--btn--primary { + background-color: #393939; +} +.cds--btn--primary:hover { + background-color: $slightly-lighter-gray; +} +// .cds--btn--ghost:visited { +// color: black; +// } +// .cds--btn--ghost:hover { +// color: black; +// } +// .cds--btn--ghost:visited:hover { +// color: black; +// } + + +// :root { +// --cds-link-primary: #525252; +// } +// .card { +// background: var(--orange); +// --orange: hsl(255, 72%, var(--lightness)); +// } diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 4d55593d..8f91f7cf 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -1,12 +1,25 @@ import { useContext, useEffect, useState } from 'react'; -import { Link, useParams } from 'react-router-dom'; +import { Link, useNavigate, useParams } from 'react-router-dom'; // @ts-ignore -import { Grid, Column, Dropdown, Button, Stack } from '@carbon/react'; +import { Add, Upload } from '@carbon/icons-react'; +import { + Accordion, + AccordionItem, + Grid, + Column, + Dropdown, + Button, + Stack, + ButtonSet, + Modal, + FileUploader, + // @ts-ignore +} from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import FileInput from '../components/FileInput'; import HttpService from '../services/HttpService'; import ErrorContext from '../contexts/ErrorContext'; -import { RecentProcessModel } from '../interfaces'; +import { ProcessModel, RecentProcessModel } from '../interfaces'; const storeRecentProcessModelInLocalStorage = ( processModelForStorage: any, @@ -66,12 +79,16 @@ export default function ProcessModelShow() { const params = useParams(); const setErrorMessage = (useContext as any)(ErrorContext)[1]; - const [processModel, setProcessModel] = useState({}); + const [processModel, setProcessModel] = useState(null); const [processInstanceResult, setProcessInstanceResult] = useState(null); - const [reloadModel, setReloadModel] = useState(false); + const [reloadModel, setReloadModel] = useState(false); + const [filesToUpload, setFilesToUpload] = useState(null); + const [showFileUploadModal, setShowFileUploadModal] = + useState(false); + const navigate = useNavigate(); useEffect(() => { - const processResult = (result: object) => { + const processResult = (result: ProcessModel) => { setProcessModel(result); setReloadModel(false); storeRecentProcessModelInLocalStorage(result, params); @@ -100,40 +117,42 @@ export default function ProcessModelShow() { }); }; - let processInstanceResultTag = null; - if (processInstanceResult) { - let takeMeToMyTaskBlurb = null; - // FIXME: ensure that the task is actually for the current user as well - const processInstanceId = (processInstanceResult as any).id; - const nextTask = (processInstanceResult as any).next_task; - if (nextTask && nextTask.state === 'READY') { - takeMeToMyTaskBlurb = ( - - You have a task to complete. Go to{' '} - my task - . - + const processInstanceResultTag = () => { + if (processModel && processInstanceResult) { + let takeMeToMyTaskBlurb = null; + // FIXME: ensure that the task is actually for the current user as well + const processInstanceId = (processInstanceResult as any).id; + const nextTask = (processInstanceResult as any).next_task; + if (nextTask && nextTask.state === 'READY') { + takeMeToMyTaskBlurb = ( + + You have a task to complete. Go to{' '} + + my task + + . + + ); + } + return ( +
+

+ Process Instance {processInstanceId} kicked off ( + + view + + ). {takeMeToMyTaskBlurb} +

+
); } - processInstanceResultTag = ( -
-

- Process Instance {processInstanceId} kicked off ( - - view - - ). {takeMeToMyTaskBlurb} -

-
- ); - } + return null; + }; const onUploadedCallback = () => { setReloadModel(true); @@ -209,112 +228,131 @@ export default function ProcessModelShow() { ); }; - const processModelButtons = () => { - // - // - // - const items = [ - { - key1: ( - - - - - - - - - ), - }, - ]; + const handleFileUploadCancel = () => { + setShowFileUploadModal(false); + }; + + const handleFileUpload = (event: any) => { + event.preventDefault(); + const url = `/process-models/${(processModel as any).process_group_id}/${ + (processModel as any).id + }/files`; + const formData = new FormData(); + formData.append('file', filesToUpload[0]); + formData.append('fileName', filesToUpload[0].name); + HttpService.makeCallToBackend({ + path: url, + successCallback: onUploadedCallback, + httpMethod: 'POST', + postBody: formData, + }); + setShowFileUploadModal(false); + }; + + const fileUploadModal = () => { return ( - - - - - (item ? item.key1 : '')} - onChange={(e: any) => console.log('e', e)} + + setFilesToUpload(event.target.files)} /> - + ); }; - if (Object.keys(processModel).length > 1) { + const processModelButtons = () => { + return ( + + + + + + + } + > + + + + + + +
+ {processModelFileList()} +
+
+ ); + }; + + if (processModel) { return ( <> - {processInstanceResultTag} - + {fileUploadModal()} + {processInstanceResultTag()}
{processModelButtons()}

Process Instances

{processInstancesUl()} -
-
-

Files

- {processModelFileList()} ); } From 028a9faf14919f1f0a7e699c877fcb485c38c641 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 7 Nov 2022 17:41:35 -0500 Subject: [PATCH 3/9] added a table for files w/ burnettk --- .../src/routes/ProcessModelShow.tsx | 71 +++++++++++++------ 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 8f91f7cf..184f0c6e 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -13,6 +13,12 @@ import { ButtonSet, Modal, FileUploader, + Table, + TableHead, + TableHeader, + TableRow, + TableCell, + TableBody, // @ts-ignore } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; @@ -167,38 +173,61 @@ export default function ProcessModelShow() { primarySuffix = '- Primary File'; } constructedTag = ( -
  • - - {processModelFile.name} - - {primarySuffix} -
  • + + + + {processModelFile.name} + + {primarySuffix} + + ); } else if (processModelFile.name.match(/\.(json|md)$/)) { constructedTag = ( -
  • - - {processModelFile.name} - -
  • + + + + {processModelFile.name} + + + ); } else { constructedTag = ( -
  • {processModelFile.name}
  • + + + {processModelFile.name} + + ); } return constructedTag; }); - return
      {tags}
    ; + // return
      {tags}
    ; + const headers = ['name', 'Actions']; + return ( + + + + {headers.map((header) => ( + + {header} + + ))} + + + {tags} +
    + ); }; const processInstancesUl = () => { From a092cf21dd62dcd130661f4d3c3307cab1dae29c Mon Sep 17 00:00:00 2001 From: burnettk Date: Mon, 7 Nov 2022 18:37:46 -0500 Subject: [PATCH 4/9] add back run and edit and add actions menu --- spiffworkflow-frontend/src/interfaces.ts | 1 + .../src/routes/ProcessModelEdit.tsx | 1 + .../src/routes/ProcessModelShow.tsx | 82 +++++++++++++++++-- 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/spiffworkflow-frontend/src/interfaces.ts b/spiffworkflow-frontend/src/interfaces.ts index 9387f658..ccf636e7 100644 --- a/spiffworkflow-frontend/src/interfaces.ts +++ b/spiffworkflow-frontend/src/interfaces.ts @@ -36,6 +36,7 @@ export interface ProcessFile { export interface ProcessModel { id: string; + description: string; process_group_id: string; display_name: string; primary_file_name: string; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx b/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx index 58375a88..3f3dfb78 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelEdit.tsx @@ -49,6 +49,7 @@ export default function ProcessModelEdit() { }); }; + // share with or delete from ProcessModelEditDiagram const deleteProcessModel = () => { setErrorMessage(null); const processModelToUse = processModel as any; diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index 184f0c6e..d7785e58 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -1,12 +1,10 @@ import { useContext, useEffect, useState } from 'react'; -import { Link, useNavigate, useParams } from 'react-router-dom'; +import { Link, useParams } from 'react-router-dom'; // @ts-ignore import { Add, Upload } from '@carbon/icons-react'; import { Accordion, AccordionItem, - Grid, - Column, Dropdown, Button, Stack, @@ -22,10 +20,15 @@ import { // @ts-ignore } from '@carbon/react'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; -import FileInput from '../components/FileInput'; import HttpService from '../services/HttpService'; import ErrorContext from '../contexts/ErrorContext'; -import { ProcessModel, RecentProcessModel } from '../interfaces'; +import { ProcessFile, ProcessModel, RecentProcessModel } from '../interfaces'; + +interface ProcessModelFileCarbonDropdownItem { + label: string; + action: string; + processModelFile: ProcessFile; +} const storeRecentProcessModelInLocalStorage = ( processModelForStorage: any, @@ -91,7 +94,6 @@ export default function ProcessModelShow() { const [filesToUpload, setFilesToUpload] = useState(null); const [showFileUploadModal, setShowFileUploadModal] = useState(false); - const navigate = useNavigate(); useEffect(() => { const processResult = (result: ProcessModel) => { @@ -164,9 +166,58 @@ export default function ProcessModelShow() { setReloadModel(true); }; + // Remove this code from + const onDeleteFile = (fileName: string) => { + const url = `/process-models/${params.process_group_id}/${params.process_model_id}/files/${fileName}`; + const httpMethod = 'DELETE'; + const reloadModelOhYeah = (_httpResult: any) => { + setReloadModel(!reloadModel); + }; + HttpService.makeCallToBackend({ + path: url, + successCallback: reloadModelOhYeah, + httpMethod, + }); + }; + + const onProcessModelFileAction = (selection: any) => { + const { selectedItem } = selection; + if (selectedItem.action === 'delete') { + onDeleteFile(selectedItem.processModelFile.name); + } + }; + const processModelFileList = () => { let constructedTag; const tags = (processModel as any).files.map((processModelFile: any) => { + const items: ProcessModelFileCarbonDropdownItem[] = [ + { + label: 'Delete', + action: 'delete', + processModelFile, + }, + { + label: 'Mark as Primary', + action: 'mark_as_primary', + processModelFile, + }, + ]; + const actionsTableCell = ( + + { + onProcessModelFileAction(e); + }} + items={items} + itemToString={(item: ProcessModelFileCarbonDropdownItem) => + item ? item.label : '' + } + /> + + ); if (processModelFile.name.match(/\.(dmn|bpmn)$/)) { let primarySuffix = ''; if (processModelFile.name === (processModel as any).primary_file_name) { @@ -184,6 +235,7 @@ export default function ProcessModelShow() { {primarySuffix} + {actionsTableCell} ); } else if (processModelFile.name.match(/\.(json|md)$/)) { @@ -198,6 +250,7 @@ export default function ProcessModelShow() { {processModelFile.name} + {actionsTableCell} ); } else { @@ -213,7 +266,7 @@ export default function ProcessModelShow() { }); // return
      {tags}
    ; - const headers = ['name', 'Actions']; + const headers = ['Name', 'Actions']; return ( @@ -374,6 +427,21 @@ export default function ProcessModelShow() { processGroupId={processModel.process_group_id} processModelId={processModel.id} /> +

    {processModel.display_name}

    +

    {processModel.description}

    + + + + {fileUploadModal()} {processInstanceResultTag()}
    From fa0e3d99337853d810b6263ffe76a60013394dc5 Mon Sep 17 00:00:00 2001 From: jasquat Date: Tue, 8 Nov 2022 09:00:51 -0500 Subject: [PATCH 5/9] change action dropdown direction based on if it is the last one or not --- .../src/routes/ProcessModelShow.tsx | 222 +++++++++--------- 1 file changed, 115 insertions(+), 107 deletions(-) diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index d7785e58..c4d2f8c4 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -147,9 +147,7 @@ export default function ProcessModelShow() {

    Process Instance {processInstanceId} kicked off ( view @@ -188,82 +186,98 @@ export default function ProcessModelShow() { }; const processModelFileList = () => { + if (!processModel) { + return null; + } let constructedTag; - const tags = (processModel as any).files.map((processModelFile: any) => { - const items: ProcessModelFileCarbonDropdownItem[] = [ - { - label: 'Delete', - action: 'delete', - processModelFile, - }, - { - label: 'Mark as Primary', - action: 'mark_as_primary', - processModelFile, - }, - ]; - const actionsTableCell = ( - - { - onProcessModelFileAction(e); - }} - items={items} - itemToString={(item: ProcessModelFileCarbonDropdownItem) => - item ? item.label : '' - } - /> - - ); - if (processModelFile.name.match(/\.(dmn|bpmn)$/)) { - let primarySuffix = ''; - if (processModelFile.name === (processModel as any).primary_file_name) { - primarySuffix = '- Primary File'; + const tags = processModel.files.map( + (processModelFile: any, index: number) => { + const isPrimaryBpmnFile = + processModelFile.name === processModel.primary_file_name; + const items: ProcessModelFileCarbonDropdownItem[] = [ + { + label: 'Delete', + action: 'delete', + processModelFile, + }, + ]; + if (processModelFile.name.match(/\.bpmn$/) && !isPrimaryBpmnFile) { + items.push({ + label: 'Mark as Primary', + action: 'mark_as_primary', + processModelFile, + }); } - constructedTag = ( - - - + + let actionDropDirection = 'bottom'; + if (index + 1 === processModel.files.length) { + actionDropDirection = 'top'; + } + + // The dropdown will get covered up if it extends passed the table container. + // Using bottom direction at least gives a scrollbar so use that and hopefully + // carbon will give access to z-index at some point. + // https://github.com/carbon-design-system/carbon-addons-iot-react/issues/1487 + const actionsTableCell = ( + + { + onProcessModelFileAction(e); + }} + items={items} + itemToString={(item: ProcessModelFileCarbonDropdownItem) => + item ? item.label : '' + } + /> + + ); + + if (processModelFile.name.match(/\.(dmn|bpmn)$/)) { + let primarySuffix = ''; + if (isPrimaryBpmnFile) { + primarySuffix = '- Primary File'; + } + constructedTag = ( + + + + {processModelFile.name} + + {primarySuffix} + + {actionsTableCell} + + ); + } else if (processModelFile.name.match(/\.(json|md)$/)) { + constructedTag = ( + + + + {processModelFile.name} + + + {actionsTableCell} + + ); + } else { + constructedTag = ( + + {processModelFile.name} - - {primarySuffix} - - {actionsTableCell} - - ); - } else if (processModelFile.name.match(/\.(json|md)$/)) { - constructedTag = ( - - - - {processModelFile.name} - - - {actionsTableCell} - - ); - } else { - constructedTag = ( - - - {processModelFile.name} - - - ); + + + ); + } + return constructedTag; } - return constructedTag; - }); + ); // return

      {tags}
    ; const headers = ['Name', 'Actions']; @@ -284,13 +298,14 @@ export default function ProcessModelShow() { }; const processInstancesUl = () => { + if (!processModel) { + return null; + } return (
    • List @@ -298,9 +313,7 @@ export default function ProcessModelShow() {
    • Reports @@ -315,20 +328,20 @@ export default function ProcessModelShow() { }; const handleFileUpload = (event: any) => { - event.preventDefault(); - const url = `/process-models/${(processModel as any).process_group_id}/${ - (processModel as any).id - }/files`; - const formData = new FormData(); - formData.append('file', filesToUpload[0]); - formData.append('fileName', filesToUpload[0].name); - HttpService.makeCallToBackend({ - path: url, - successCallback: onUploadedCallback, - httpMethod: 'POST', - postBody: formData, - }); - setShowFileUploadModal(false); + if (processModel) { + event.preventDefault(); + const url = `/process-models/${processModel.process_group_id}/${processModel.id}/files`; + const formData = new FormData(); + formData.append('file', filesToUpload[0]); + formData.append('fileName', filesToUpload[0].name); + HttpService.makeCallToBackend({ + path: url, + successCallback: onUploadedCallback, + httpMethod: 'POST', + postBody: formData, + }); + setShowFileUploadModal(false); + } }; const fileUploadModal = () => { @@ -362,6 +375,9 @@ export default function ProcessModelShow() { }; const processModelButtons = () => { + if (!processModel) { + return null; + } return ( {confirmationDialog()} diff --git a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx index c4d2f8c4..af64a862 100644 --- a/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx +++ b/spiffworkflow-frontend/src/routes/ProcessModelShow.tsx @@ -211,7 +211,7 @@ export default function ProcessModelShow() { let actionDropDirection = 'bottom'; if (index + 1 === processModel.files.length) { - actionDropDirection = 'top'; + actionDropDirection = 'bottom'; } // The dropdown will get covered up if it extends passed the table container. @@ -401,6 +401,13 @@ export default function ProcessModelShow() { > Upload File +