fixed up the process instance show page and moved contents of scss to css file and load that last w/ burnettk

This commit is contained in:
jasquat 2022-11-10 15:44:58 -05:00
parent 2988c3815b
commit 427973a4aa
11 changed files with 242 additions and 170 deletions

View File

@ -64,7 +64,6 @@ class ProcessInstanceStatus(SpiffEnum):
faulted = "faulted" faulted = "faulted"
suspended = "suspended" suspended = "suspended"
terminated = "terminated" terminated = "terminated"
erroring = "erroring"
class ProcessInstanceModel(SpiffworkflowBaseDBModel): class ProcessInstanceModel(SpiffworkflowBaseDBModel):

View File

@ -83,10 +83,6 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
report_metadata = { report_metadata = {
"columns": [ "columns": [
{"Header": "id", "accessor": "id"}, {"Header": "id", "accessor": "id"},
{
"Header": "process_group_identifier",
"accessor": "process_group_identifier",
},
{ {
"Header": "process_model_identifier", "Header": "process_model_identifier",
"accessor": "process_model_identifier", "accessor": "process_model_identifier",

View File

@ -64,7 +64,7 @@ class ProcessInstanceService:
processor.do_engine_steps(save=True) processor.do_engine_steps(save=True)
except Exception as e: except Exception as e:
db.session.rollback() # in case the above left the database with a bad transaction db.session.rollback() # in case the above left the database with a bad transaction
process_instance.status = ProcessInstanceStatus.erroring.value process_instance.status = ProcessInstanceStatus.faulted.value
db.session.add(process_instance) db.session.add(process_instance)
db.session.commit() db.session.commit()
error_message = ( error_message = (

View File

@ -17,5 +17,6 @@ export const PROCESS_STATUSES = [
]; ];
// with time: yyyy-MM-dd HH:mm:ss // with time: yyyy-MM-dd HH:mm:ss
export const DATE_TIME_FORMAT = 'yyyy-MM-dd HH:mm:ss';
export const DATE_FORMAT = 'yyyy-MM-dd'; export const DATE_FORMAT = 'yyyy-MM-dd';
export const DATE_FORMAT_CARBON = 'Y-m-d'; export const DATE_FORMAT_CARBON = 'Y-m-d';

View File

@ -1,5 +1,5 @@
import { format } from 'date-fns'; import { format } from 'date-fns';
import { DATE_FORMAT } from './config'; import { DATE_TIME_FORMAT, DATE_FORMAT } from './config';
import { import {
DEFAULT_PER_PAGE, DEFAULT_PER_PAGE,
DEFAULT_PAGE, DEFAULT_PAGE,
@ -51,6 +51,14 @@ export const convertStringToDate = (dateString: string) => {
return null; return null;
}; };
export const convertSecondsToFormattedDateTime = (seconds: number) => {
if (seconds) {
const dateObject = new Date(seconds * 1000);
return format(dateObject, DATE_TIME_FORMAT);
}
return null;
};
export const convertSecondsToFormattedDate = (seconds: number) => { export const convertSecondsToFormattedDate = (seconds: number) => {
if (seconds) { if (seconds) {
const dateObject = new Date(seconds * 1000); const dateObject = new Date(seconds * 1000);

View File

@ -1,24 +1,79 @@
body { /* site is mainly using white theme. */
margin: 0; /* header is mainly using g100 */
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', /* mockup wanted white, not grey, text */
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', .cds--header, a.cds--header__menu-item {
sans-serif; color: white;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} }
h1{
height: 36px;
font-family: 'IBM Plex Sans';
font-style: normal;
font-weight: 400;
font-size: 28px;
line-height: 36px;
color: #161616;
flex: none;
order: 0;
align-self: stretch;
flex-grow: 0;
margin-bottom: 1em
}
.span-tag {
color: black;
}
.cds--btn.button-white-background {
color: #393939;
background: #FFFFFF;
background-blend-mode: multiply;
border: 1px solid #393939;
}
.cds--btn.button-white-background:hover {
background: #525252;
}
.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;
}
.cds--btn--ghost {
color: black;
}
.cds--btn--ghost:visited {
color: black;
}
.cds--btn--ghost:hover {
color: black;
}
.cds--btn--ghost:visited:hover {
color: black;
}
.cds--header__global .cds--btn--primary {
background-color: #161616
}
.cds--btn--primary {
background-color: #393939;
}
.cds--btn--primary:hover {
background-color: #474747;
}
code { code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace; monospace;
} }
span.bjs-crumb {
color: #0000ff;
}
.bjs-breadcrumbs li:last-of-type span.bjs-crumb a {
color: black;
}
.app-logo { .app-logo {
height: 85%; height: 85%;
width: 85%; width: 85%;
@ -52,6 +107,26 @@ span.bjs-crumb {
margin-bottom: 2em; margin-bottom: 2em;
} }
h1.with-icons {
margin-top: 5px;
}
.grid-list-title {
font-weight: 600;
font-size: 14px;
line-height: 18px;
color: #161616;
}
.grid-date {
font-size: 14px;
line-height: 18px;
letter-spacing: 0.16px;
color: #525252;
}
.smaller-text {
font-size: 14px;
}
.diagram-editor-canvas { .diagram-editor-canvas {
border:1px solid #000000; border:1px solid #000000;
height:70vh; height:70vh;
@ -59,13 +134,6 @@ span.bjs-crumb {
margin:auto; margin:auto;
} }
.cds--btn.button-white-background {
color: #393939;
background: #FFFFFF;
background-blend-mode: multiply;
border: 1px solid #393939;
}
.with-bottom-margin { .with-bottom-margin {
margin-bottom: 1em; margin-bottom: 1em;
} }

View File

@ -15,85 +15,3 @@
@use '@carbon/colors'; @use '@carbon/colors';
// @use '@carbon/react/scss/colors'; // @use '@carbon/react/scss/colors';
@use '@carbon/react/scss/themes'; @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
// mockup wanted white, not grey, text
.cds--header, a.cds--header__menu-item {
// background-color: colors.$gray-100;
color: white;
}
h1{
height: 36px;
font-family: 'IBM Plex Sans';
font-style: normal;
font-weight: 400;
font-size: 28px;
line-height: 36px;
color: #161616;
flex: none;
order: 0;
align-self: stretch;
flex-grow: 0;
margin-bottom: 1em
}
.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;
}
.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;
$spiff-header-background-color: #161616;
.cds--header__global .cds--btn--primary {
background-color: $spiff-header-background-color;
}
.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));
// }

View File

@ -3,8 +3,8 @@ import * as ReactDOMClient from 'react-dom/client';
import App from './App'; import App from './App';
import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap/dist/css/bootstrap.css';
import './index.css';
import './index.scss'; import './index.scss';
import './index.css';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
import UserService from './services/UserService'; import UserService from './services/UserService';

View File

@ -113,11 +113,12 @@ export default function MessageInstanceList() {
)}:link`, )}:link`,
], ],
[ [
`${searchParams.get('process_instance_id')}`, `Process Instance: ${searchParams.get('process_instance_id')}`,
`/admin/process-models/${searchParams.get( `/admin/process-models/${searchParams.get(
'process_model_id' 'process_model_id'
)}/process-instances/${searchParams.get('process_instance_id')}`, )}/process-instances/${searchParams.get('process_instance_id')}`,
], ],
['Messages'],
]} ]}
/> />
); );

View File

@ -88,9 +88,10 @@ export default function ProcessInstanceLogList() {
)}:link`, )}:link`,
], ],
[ [
`${params.process_instance_id}`, `Process Instance: ${params.process_instance_id}`,
`/admin/process-models/${params.process_model_id}/process-instances/${params.process_instance_id}`, `/admin/process-models/${params.process_model_id}/process-instances/${params.process_instance_id}`,
], ],
['Logs'],
]} ]}
/> />
<PaginationForTable <PaginationForTable

View File

@ -1,20 +1,33 @@
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect, useState } from 'react';
import Editor from '@monaco-editor/react'; import Editor from '@monaco-editor/react';
import { useParams, useNavigate, Link } from 'react-router-dom'; import { useParams, useNavigate, Link } from 'react-router-dom';
import {
TrashCan,
StopOutline,
PauseOutline,
PlayOutline,
CaretLeft,
CaretRight,
InProgress,
Checkmark,
Warning,
// @ts-ignore
} from '@carbon/icons-react';
import { import {
Grid, Grid,
Column, Column,
Button, Button,
ButtonSet,
Tag,
Modal, Modal,
Stack, Stack,
UnorderedList,
// @ts-ignore // @ts-ignore
} from '@carbon/react'; } from '@carbon/react';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import HttpService from '../services/HttpService'; import HttpService from '../services/HttpService';
import ReactDiagramEditor from '../components/ReactDiagramEditor'; import ReactDiagramEditor from '../components/ReactDiagramEditor';
import { import {
convertSecondsToFormattedDate, convertSecondsToFormattedDateTime,
unModifyProcessModelPath, unModifyProcessModelPath,
} from '../helpers'; } from '../helpers';
import ButtonWithConfirmation from '../components/ButtonWithConfirmation'; import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
@ -132,7 +145,7 @@ export default function ProcessInstanceShow() {
const spiffStepLink = ( const spiffStepLink = (
processInstanceToUse: any, processInstanceToUse: any,
label: string, label: any,
distance: number distance: number
) => { ) => {
return ( return (
@ -155,7 +168,7 @@ export default function ProcessInstanceShow() {
return null; return null;
} }
return spiffStepLink(processInstanceToUse, '<<', -1); return spiffStepLink(processInstanceToUse, <CaretLeft />, -1);
}; };
const nextStepLink = (processInstanceToUse: any) => { const nextStepLink = (processInstanceToUse: any) => {
@ -163,49 +176,87 @@ export default function ProcessInstanceShow() {
return null; return null;
} }
return spiffStepLink(processInstanceToUse, '>>', 1); return spiffStepLink(processInstanceToUse, <CaretRight />, 1);
}; };
const getInfoTag = (processInstanceToUse: any) => { const getInfoTag = (processInstanceToUse: any) => {
const currentEndDate = convertSecondsToFormattedDate( const currentEndDate = convertSecondsToFormattedDateTime(
processInstanceToUse.end_in_seconds processInstanceToUse.end_in_seconds
); );
let currentEndDateTag; let currentEndDateTag;
if (currentEndDate) { if (currentEndDate) {
currentEndDateTag = ( currentEndDateTag = (
<li> <Grid condensed fullWidth>
Completed:{' '} <Column sm={1} md={1} lg={1} className="grid-list-title">
{convertSecondsToFormattedDate(processInstanceToUse.end_in_seconds) || Completed:{' '}
'N/A'} </Column>
</li> <Column sm={3} md={3} lg={3} className="grid-date">
{convertSecondsToFormattedDateTime(
processInstanceToUse.end_in_seconds
) || 'N/A'}
</Column>
</Grid>
); );
} }
let statusIcon = <InProgress />;
if (processInstanceToUse.status === 'suspended') {
statusIcon = <PauseOutline />;
} else if (processInstanceToUse.status === 'complete') {
statusIcon = <Checkmark />;
} else if (processInstanceToUse.status === 'terminated') {
statusIcon = <StopOutline />;
} else if (processInstanceToUse.status === 'faulted') {
statusIcon = <Warning />;
}
return ( return (
<UnorderedList> <>
<li> <Grid condensed fullWidth>
Started:{' '} <Column sm={1} md={1} lg={1} className="grid-list-title">
{convertSecondsToFormattedDate(processInstanceToUse.start_in_seconds)} Started:{' '}
</li> </Column>
<Column sm={3} md={3} lg={3} className="grid-date">
{convertSecondsToFormattedDateTime(
processInstanceToUse.start_in_seconds
)}
</Column>
</Grid>
{currentEndDateTag} {currentEndDateTag}
<li>Status: {processInstanceToUse.status}</li> <Grid condensed fullWidth>
<li> <Column sm={1} md={1} lg={1} className="grid-list-title">
<Link Status:{' '}
data-qa="process-instance-log-list-link" </Column>
to={`/admin/process-models/${modifiedProcessModelId}/process-instances/${params.process_instance_id}/logs`} <Column sm={3} md={3} lg={3}>
> <Tag type="gray" size="sm" className="span-tag">
Logs {processInstanceToUse.status} {statusIcon}
</Link> </Tag>
</li> </Column>
<li> </Grid>
<Link <br />
data-qa="process-instance-message-instance-list-link" <Grid condensed fullWidth>
to={`/admin/messages?process_model_id=${params.process_model_id}&process_instance_id=${params.process_instance_id}`} <Column sm={2} md={2} lg={2}>
> <ButtonSet>
Messages <Button
</Link> size="sm"
</li> className="button-white-background"
</UnorderedList> data-qa="process-instance-log-list-link"
href={`/admin/process-models/${modifiedProcessModelId}/process-instances/${params.process_instance_id}/logs`}
>
Logs
</Button>
<Button
size="sm"
className="button-white-background"
data-qa="process-instance-message-instance-list-link"
href={`/admin/messages?process_model_id=${params.process_model_id}&process_instance_id=${params.process_instance_id}`}
>
Messages
</Button>
</ButtonSet>
</Column>
</Grid>
</>
); );
}; };
@ -216,9 +267,15 @@ export default function ProcessInstanceShow() {
) === -1 ) === -1
) { ) {
return ( return (
<Button onClick={terminateProcessInstance} variant="warning"> <ButtonWithConfirmation
Terminate kind="ghost"
</Button> renderIcon={StopOutline}
iconDescription="Terminate"
hasIconOnly
description={`Terminate Process Instance: ${processInstanceToUse.id}`}
onConfirmation={terminateProcessInstance}
confirmButtonLabel="Terminate"
/>
); );
} }
return <div />; return <div />;
@ -231,9 +288,14 @@ export default function ProcessInstanceShow() {
) === -1 ) === -1
) { ) {
return ( return (
<Button onClick={suspendProcessInstance} variant="warning"> <Button
Suspend onClick={suspendProcessInstance}
</Button> kind="ghost"
renderIcon={PauseOutline}
iconDescription="Suspend"
hasIconOnly
size="lg"
/>
); );
} }
return <div />; return <div />;
@ -242,9 +304,14 @@ export default function ProcessInstanceShow() {
const resumeButton = (processInstanceToUse: any) => { const resumeButton = (processInstanceToUse: any) => {
if (processInstanceToUse.status === 'suspended') { if (processInstanceToUse.status === 'suspended') {
return ( return (
<Button onClick={resumeProcessInstance} variant="warning"> <Button
Resume onClick={resumeProcessInstance}
</Button> kind="ghost"
renderIcon={PlayOutline}
iconDescription="Resume"
hasIconOnly
size="lg"
/>
); );
} }
return <div />; return <div />;
@ -434,9 +501,9 @@ export default function ProcessInstanceShow() {
const stepsElement = (processInstanceToUse: any) => { const stepsElement = (processInstanceToUse: any) => {
return ( return (
<Grid fullWidth> <Grid condensed fullWidth>
<Column sm={3} md={3} lg={3}> <Column sm={3} md={3} lg={3}>
<Stack orientation="horizontal" gap={3}> <Stack orientation="horizontal" gap={3} className="smaller-text">
{previousStepLink(processInstanceToUse)} {previousStepLink(processInstanceToUse)}
Step {currentSpiffStep(processInstanceToUse)} of{' '} Step {currentSpiffStep(processInstanceToUse)} of{' '}
{processInstanceToUse.spiff_step} {processInstanceToUse.spiff_step}
@ -447,6 +514,25 @@ export default function ProcessInstanceShow() {
); );
}; };
const buttonIcons = (processInstanceToUse: any) => {
const elements = [];
elements.push(terminateButton(processInstanceToUse));
elements.push(suspendButton(processInstanceToUse));
elements.push(resumeButton(processInstanceToUse));
elements.push(
<ButtonWithConfirmation
kind="ghost"
renderIcon={TrashCan}
iconDescription="Delete"
hasIconOnly
description={`Delete Process Instance: ${processInstanceToUse.id}`}
onConfirmation={deleteProcessInstance}
confirmButtonLabel="Delete"
/>
);
return elements;
};
if (processInstance && tasks) { if (processInstance && tasks) {
const processInstanceToUse = processInstance as any; const processInstanceToUse = processInstance as any;
const taskIds = getTaskIds(); const taskIds = getTaskIds();
@ -463,20 +549,14 @@ export default function ProcessInstanceShow() {
`Process Model: ${processModelId}`, `Process Model: ${processModelId}`,
`process_model:${processModelId}:link`, `process_model:${processModelId}:link`,
], ],
[`${processInstanceToUse.id}`], [`Process Instance Id: ${processInstanceToUse.id}`],
]} ]}
/> />
<h1>Process Instance Id: {processInstanceToUse.id}</h1> <Stack orientation="horizontal" gap={1}>
<Stack orientation="horizontal" gap={3}> <h1 className="with-icons">
<ButtonWithConfirmation Process Instance Id: {processInstanceToUse.id}
description="Delete Process Instance?" </h1>
onConfirmation={deleteProcessInstance} {buttonIcons(processInstanceToUse)}
buttonLabel="Delete"
confirmButtonLabel="Delete"
/>
{terminateButton(processInstanceToUse)}
{suspendButton(processInstanceToUse)}
{resumeButton(processInstanceToUse)}
</Stack> </Stack>
<br /> <br />
<br /> <br />