mirror of
https://github.com/status-im/spiff-arena.git
synced 2025-02-05 22:53:57 +00:00
adds basic support to use certain components in extensions w/ burnettk (#597)
Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
c2ce27e961
commit
566f383918
@ -58,7 +58,7 @@ class ElementUnitsService:
|
|||||||
# make mypy happy
|
# make mypy happy
|
||||||
return None
|
return None
|
||||||
|
|
||||||
current_app.logger.info(f"Checking element unit cache @ {cache_key} :: '{process_id}' - '{element_id}'")
|
current_app.logger.debug(f"Checking element unit cache @ {cache_key} :: '{process_id}' - '{element_id}'")
|
||||||
|
|
||||||
bpmn_spec_json = spiff_element_units.workflow_from_cached_element_unit(
|
bpmn_spec_json = spiff_element_units.workflow_from_cached_element_unit(
|
||||||
cache_dir, cache_key, process_id, element_id
|
cache_dir, cache_key, process_id, element_id
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import MDEditor from '@uiw/react-md-editor';
|
|
||||||
import { Toggle } from '@carbon/react';
|
import { Toggle } from '@carbon/react';
|
||||||
import FormattingService from '../services/FormattingService';
|
import FormattingService from '../services/FormattingService';
|
||||||
|
import MarkdownRenderer from './MarkdownRenderer';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
task: any;
|
task: any;
|
||||||
@ -87,9 +87,8 @@ export default function InstructionsForEndUser({
|
|||||||
https://www.npmjs.com/package/@uiw/react-md-editor switches to dark mode by default by respecting @media (prefers-color-scheme: dark)
|
https://www.npmjs.com/package/@uiw/react-md-editor switches to dark mode by default by respecting @media (prefers-color-scheme: dark)
|
||||||
This makes it look like our site is broken, so until the rest of the site supports dark mode, turn off dark mode for this component.
|
This makes it look like our site is broken, so until the rest of the site supports dark mode, turn off dark mode for this component.
|
||||||
*/}
|
*/}
|
||||||
<div data-color-mode="light">
|
|
||||||
<MDEditor.Markdown linkTarget="_blank" source={instructions} />
|
<MarkdownRenderer linkTarget="_blank" source={instructions} />
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{showCollapseToggle()}
|
{showCollapseToggle()}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import MDEditor from '@uiw/react-md-editor';
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
|
import MarkdownRenderer from './MarkdownRenderer';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
apiPath: string;
|
apiPath: string;
|
||||||
@ -24,9 +24,11 @@ export default function MarkdownDisplayForFile({ apiPath }: OwnProps) {
|
|||||||
|
|
||||||
if (markdownContents) {
|
if (markdownContents) {
|
||||||
return (
|
return (
|
||||||
<div data-color-mode="light" className="with-bottom-margin">
|
<MarkdownRenderer
|
||||||
<MDEditor.Markdown linkTarget="_blank" source={markdownContents} />
|
linkTarget="_blank"
|
||||||
</div>
|
source={markdownContents}
|
||||||
|
wrapperClassName="with-bottom-margin"
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
spiffworkflow-frontend/src/components/MarkdownRenderer.tsx
Normal file
16
spiffworkflow-frontend/src/components/MarkdownRenderer.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import MDEditor from '@uiw/react-md-editor';
|
||||||
|
|
||||||
|
export default function MarkdownRenderer(props: any) {
|
||||||
|
let wrapperClassName = '';
|
||||||
|
const propsToUse = props;
|
||||||
|
if ('wrapperClassName' in propsToUse) {
|
||||||
|
wrapperClassName = propsToUse.wrapperClassName;
|
||||||
|
delete propsToUse.wrapperClassName;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div data-color-mode="light" className={wrapperClassName}>
|
||||||
|
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||||
|
<MDEditor.Markdown {...propsToUse} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -66,20 +66,21 @@ const storeRecentProcessModelInLocalStorage = (
|
|||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
processModel: ProcessModel;
|
processModel: ProcessModel;
|
||||||
onSuccessCallback: Function;
|
|
||||||
className?: string;
|
className?: string;
|
||||||
checkPermissions?: boolean;
|
checkPermissions?: boolean;
|
||||||
|
buttonText?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ProcessInstanceRun({
|
export default function ProcessInstanceRun({
|
||||||
processModel,
|
processModel,
|
||||||
onSuccessCallback,
|
|
||||||
className,
|
className,
|
||||||
checkPermissions = true,
|
checkPermissions = true,
|
||||||
|
buttonText = 'Start',
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { addError, removeError } = useAPIError();
|
const { addError, removeError } = useAPIError();
|
||||||
const [disableStartButton, setDisableStartButton] = useState<boolean>(false);
|
const [disableStartButton, setDisableStartButton] = useState<boolean>(false);
|
||||||
|
|
||||||
const modifiedProcessModelId = modifyProcessIdentifierForPathParam(
|
const modifiedProcessModelId = modifyProcessIdentifierForPathParam(
|
||||||
processModel.id
|
processModel.id
|
||||||
);
|
);
|
||||||
@ -98,16 +99,15 @@ export default function ProcessInstanceRun({
|
|||||||
const onProcessInstanceRun = (processInstance: any) => {
|
const onProcessInstanceRun = (processInstance: any) => {
|
||||||
const processInstanceId = (processInstance as any).id;
|
const processInstanceId = (processInstance as any).id;
|
||||||
navigate(
|
navigate(
|
||||||
`/process-instances/for-me/${modifyProcessIdentifierForPathParam(
|
`/process-instances/for-me/${modifiedProcessModelId}/${processInstanceId}/interstitial`
|
||||||
processModel.id
|
|
||||||
)}/${processInstanceId}/interstitial`
|
|
||||||
);
|
);
|
||||||
onSuccessCallback(processInstance);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const processModelRun = (processInstance: any) => {
|
const processModelRun = (processInstance: any) => {
|
||||||
removeError();
|
removeError();
|
||||||
storeRecentProcessModelInLocalStorage(processModel);
|
if (processModel) {
|
||||||
|
storeRecentProcessModelInLocalStorage(processModel);
|
||||||
|
}
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: `/process-instances/${modifiedProcessModelId}/${processInstance.id}/run`,
|
path: `/process-instances/${modifiedProcessModelId}/${processInstance.id}/run`,
|
||||||
successCallback: onProcessInstanceRun,
|
successCallback: onProcessInstanceRun,
|
||||||
@ -141,7 +141,7 @@ export default function ProcessInstanceRun({
|
|||||||
disabled={disableStartButton}
|
disabled={disableStartButton}
|
||||||
size="md"
|
size="md"
|
||||||
>
|
>
|
||||||
Start
|
{buttonText}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
import { ReactElement, useEffect, useState } from 'react';
|
import { ReactElement, useEffect, useState } from 'react';
|
||||||
import { Link, useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
Tile,
|
Tile,
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
} from '@carbon/react';
|
} from '@carbon/react';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import { ProcessModel, ProcessInstance, ProcessGroup } from '../interfaces';
|
import { ProcessModel, ProcessGroup } from '../interfaces';
|
||||||
import {
|
import {
|
||||||
modifyProcessIdentifierForPathParam,
|
modifyProcessIdentifierForPathParam,
|
||||||
truncateString,
|
truncateString,
|
||||||
} from '../helpers';
|
} from '../helpers';
|
||||||
import ProcessInstanceRun from './ProcessInstanceRun';
|
import ProcessInstanceRun from './ProcessInstanceRun';
|
||||||
import { Notification } from './Notification';
|
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
headerElement?: ReactElement;
|
headerElement?: ReactElement;
|
||||||
@ -28,8 +27,6 @@ export default function ProcessModelListTiles({
|
|||||||
const [processModels, setProcessModels] = useState<ProcessModel[] | null>(
|
const [processModels, setProcessModels] = useState<ProcessModel[] | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
const [processInstance, setProcessInstance] =
|
|
||||||
useState<ProcessInstance | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const setProcessModelsFromResult = (result: any) => {
|
const setProcessModelsFromResult = (result: any) => {
|
||||||
@ -48,27 +45,6 @@ export default function ProcessModelListTiles({
|
|||||||
});
|
});
|
||||||
}, [searchParams, processGroup]);
|
}, [searchParams, processGroup]);
|
||||||
|
|
||||||
const processInstanceRunResultTag = () => {
|
|
||||||
if (processInstance) {
|
|
||||||
return (
|
|
||||||
<Notification
|
|
||||||
title={`Process Instance ${processInstance.id} kicked off`}
|
|
||||||
onClose={() => setProcessInstance(null)}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
to={`/process-instances/${modifyProcessIdentifierForPathParam(
|
|
||||||
processInstance.process_model_identifier
|
|
||||||
)}/${processInstance.id}`}
|
|
||||||
data-qa="process-instance-show-link"
|
|
||||||
>
|
|
||||||
view
|
|
||||||
</Link>
|
|
||||||
</Notification>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const processModelsDisplayArea = () => {
|
const processModelsDisplayArea = () => {
|
||||||
let displayText = null;
|
let displayText = null;
|
||||||
if (processModels && processModels.length > 0) {
|
if (processModels && processModels.length > 0) {
|
||||||
@ -95,7 +71,6 @@ export default function ProcessModelListTiles({
|
|||||||
</p>
|
</p>
|
||||||
<ProcessInstanceRun
|
<ProcessInstanceRun
|
||||||
processModel={row}
|
processModel={row}
|
||||||
onSuccessCallback={setProcessInstance}
|
|
||||||
className="tile-pin-bottom"
|
className="tile-pin-bottom"
|
||||||
checkPermissions={checkPermissions}
|
checkPermissions={checkPermissions}
|
||||||
/>
|
/>
|
||||||
@ -114,7 +89,6 @@ export default function ProcessModelListTiles({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{headerElement}
|
{headerElement}
|
||||||
{processInstanceRunResultTag()}
|
|
||||||
{processModelsDisplayArea()}
|
{processModelsDisplayArea()}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -37,10 +37,16 @@ export interface UiSchemaAction {
|
|||||||
full_api_path?: boolean;
|
full_api_path?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UiSchemaPageComponent {
|
||||||
|
name: string;
|
||||||
|
arguments: object;
|
||||||
|
}
|
||||||
|
|
||||||
export interface UiSchemaPageDefinition {
|
export interface UiSchemaPageDefinition {
|
||||||
header: string;
|
header: string;
|
||||||
api: string;
|
api: string;
|
||||||
|
|
||||||
|
components?: UiSchemaPageComponent[];
|
||||||
form?: UiSchemaForm;
|
form?: UiSchemaForm;
|
||||||
markdown_instruction_filename?: string;
|
markdown_instruction_filename?: string;
|
||||||
navigate_instead_of_post_to_api?: boolean;
|
navigate_instead_of_post_to_api?: boolean;
|
||||||
|
@ -146,6 +146,9 @@ export interface ProcessReference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ObjectWithStringKeysAndValues = { [key: string]: string };
|
export type ObjectWithStringKeysAndValues = { [key: string]: string };
|
||||||
|
export type ObjectWithStringKeysAndFunctionValues = {
|
||||||
|
[key: string]: Function;
|
||||||
|
};
|
||||||
|
|
||||||
export interface FilterOperator {
|
export interface FilterOperator {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { Button } from '@carbon/react';
|
import { Button } from '@carbon/react';
|
||||||
import MDEditor from '@uiw/react-md-editor';
|
|
||||||
import { useParams, useSearchParams } from 'react-router-dom';
|
import { useParams, useSearchParams } from 'react-router-dom';
|
||||||
import { Editor } from '@monaco-editor/react';
|
import { Editor } from '@monaco-editor/react';
|
||||||
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||||
import { ProcessFile, ProcessModel } from '../interfaces';
|
import {
|
||||||
|
ObjectWithStringKeysAndFunctionValues,
|
||||||
|
ProcessFile,
|
||||||
|
ProcessModel,
|
||||||
|
} from '../interfaces';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import useAPIError from '../hooks/UseApiError';
|
import useAPIError from '../hooks/UseApiError';
|
||||||
import { recursivelyChangeNullAndUndefined } from '../helpers';
|
import { recursivelyChangeNullAndUndefined } from '../helpers';
|
||||||
@ -13,10 +16,13 @@ import { BACKEND_BASE_URL } from '../config';
|
|||||||
import {
|
import {
|
||||||
ExtensionPostBody,
|
ExtensionPostBody,
|
||||||
ExtensionUiSchema,
|
ExtensionUiSchema,
|
||||||
|
UiSchemaPageComponent,
|
||||||
UiSchemaPageDefinition,
|
UiSchemaPageDefinition,
|
||||||
} from '../extension_ui_schema_interfaces';
|
} from '../extension_ui_schema_interfaces';
|
||||||
import ErrorDisplay from '../components/ErrorDisplay';
|
import ErrorDisplay from '../components/ErrorDisplay';
|
||||||
import FormattingService from '../services/FormattingService';
|
import FormattingService from '../services/FormattingService';
|
||||||
|
import ProcessInstanceRun from '../components/ProcessInstanceRun';
|
||||||
|
import MarkdownRenderer from '../components/MarkdownRenderer';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
displayErrors?: boolean;
|
displayErrors?: boolean;
|
||||||
@ -43,9 +49,16 @@ export default function Extension({ displayErrors = true }: OwnProps) {
|
|||||||
}>({});
|
}>({});
|
||||||
const [uiSchemaPageDefinition, setUiSchemaPageDefinition] =
|
const [uiSchemaPageDefinition, setUiSchemaPageDefinition] =
|
||||||
useState<UiSchemaPageDefinition | null>(null);
|
useState<UiSchemaPageDefinition | null>(null);
|
||||||
|
const [readyForComponentsToDisplay, setReadyForComponentsToDisplay] =
|
||||||
|
useState<boolean>(false);
|
||||||
|
|
||||||
const { addError, removeError } = useAPIError();
|
const { addError, removeError } = useAPIError();
|
||||||
|
|
||||||
|
const supportedComponents: ObjectWithStringKeysAndFunctionValues = {
|
||||||
|
ProcessInstanceRun,
|
||||||
|
MarkdownRenderer,
|
||||||
|
};
|
||||||
|
|
||||||
const setConfigsIfDesiredSchemaFile = useCallback(
|
const setConfigsIfDesiredSchemaFile = useCallback(
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
(extensionUiSchemaFile: ProcessFile | null, pm: ProcessModel) => {
|
(extensionUiSchemaFile: ProcessFile | null, pm: ProcessModel) => {
|
||||||
@ -57,6 +70,7 @@ export default function Extension({ displayErrors = true }: OwnProps) {
|
|||||||
);
|
);
|
||||||
setMarkdownToRenderOnLoad(newMarkdown);
|
setMarkdownToRenderOnLoad(newMarkdown);
|
||||||
}
|
}
|
||||||
|
setReadyForComponentsToDisplay(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -98,6 +112,8 @@ export default function Extension({ displayErrors = true }: OwnProps) {
|
|||||||
httpMethod: 'POST',
|
httpMethod: 'POST',
|
||||||
postBody,
|
postBody,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
setReadyForComponentsToDisplay(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +254,7 @@ export default function Extension({ displayErrors = true }: OwnProps) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (uiSchemaPageDefinition) {
|
if (readyForComponentsToDisplay && uiSchemaPageDefinition) {
|
||||||
const componentsToDisplay = [<h1>{uiSchemaPageDefinition.header}</h1>];
|
const componentsToDisplay = [<h1>{uiSchemaPageDefinition.header}</h1>];
|
||||||
const markdownContentsToRender = [];
|
const markdownContentsToRender = [];
|
||||||
|
|
||||||
@ -261,12 +277,28 @@ export default function Extension({ displayErrors = true }: OwnProps) {
|
|||||||
|
|
||||||
if (markdownContentsToRender.length > 0) {
|
if (markdownContentsToRender.length > 0) {
|
||||||
componentsToDisplay.push(
|
componentsToDisplay.push(
|
||||||
<div data-color-mode="light" className="with-bottom-margin">
|
<MarkdownRenderer
|
||||||
<MDEditor.Markdown
|
linkTarget={mdEditorLinkTarget}
|
||||||
linkTarget={mdEditorLinkTarget}
|
source={markdownContentsToRender.join('\n')}
|
||||||
source={markdownContentsToRender.join('\n')}
|
wrapperClassName="with-bottom-margin"
|
||||||
/>
|
/>
|
||||||
</div>
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uiSchemaPageDefinition.components) {
|
||||||
|
uiSchemaPageDefinition.components.forEach(
|
||||||
|
(component: UiSchemaPageComponent) => {
|
||||||
|
if (supportedComponents[component.name]) {
|
||||||
|
const argumentsForComponent: any = component.arguments;
|
||||||
|
componentsToDisplay.push(
|
||||||
|
supportedComponents[component.name](argumentsForComponent)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`Extension tried to use component with name '${component.name}' but that is not allowed.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,13 +336,12 @@ export default function Extension({ displayErrors = true }: OwnProps) {
|
|||||||
if (processedTaskData) {
|
if (processedTaskData) {
|
||||||
if (markdownToRenderOnSubmit) {
|
if (markdownToRenderOnSubmit) {
|
||||||
componentsToDisplay.push(
|
componentsToDisplay.push(
|
||||||
<div data-color-mode="light" className="with-top-margin">
|
<MarkdownRenderer
|
||||||
<MDEditor.Markdown
|
className="onboarding"
|
||||||
className="onboarding"
|
linkTarget="_blank"
|
||||||
linkTarget="_blank"
|
source={markdownToRenderOnSubmit}
|
||||||
source={markdownToRenderOnSubmit}
|
wrapperClassName="with-top-margin"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
componentsToDisplay.push(
|
componentsToDisplay.push(
|
||||||
|
@ -2,7 +2,6 @@ import { useEffect, useState } from 'react';
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Button, Table } from '@carbon/react';
|
import { Button, Table } from '@carbon/react';
|
||||||
import { Link, useSearchParams } from 'react-router-dom';
|
import { Link, useSearchParams } from 'react-router-dom';
|
||||||
import { Notification } from '../components/Notification';
|
|
||||||
import PaginationForTable from '../components/PaginationForTable';
|
import PaginationForTable from '../components/PaginationForTable';
|
||||||
import {
|
import {
|
||||||
getPageInfoFromSearchParams,
|
getPageInfoFromSearchParams,
|
||||||
@ -12,7 +11,6 @@ import {
|
|||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import {
|
import {
|
||||||
PaginationObject,
|
PaginationObject,
|
||||||
ProcessInstance,
|
|
||||||
ProcessModel,
|
ProcessModel,
|
||||||
RecentProcessModel,
|
RecentProcessModel,
|
||||||
} from '../interfaces';
|
} from '../interfaces';
|
||||||
@ -25,8 +23,6 @@ export default function MyTasks() {
|
|||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const [tasks, setTasks] = useState([]);
|
const [tasks, setTasks] = useState([]);
|
||||||
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
||||||
const [processInstance, setProcessInstance] =
|
|
||||||
useState<ProcessInstance | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getTasks = () => {
|
const getTasks = () => {
|
||||||
@ -52,27 +48,6 @@ export default function MyTasks() {
|
|||||||
);
|
);
|
||||||
}, [searchParams]);
|
}, [searchParams]);
|
||||||
|
|
||||||
const processInstanceRunResultTag = () => {
|
|
||||||
if (processInstance) {
|
|
||||||
return (
|
|
||||||
<Notification
|
|
||||||
title={`Process Instance ${processInstance.id} kicked off`}
|
|
||||||
onClose={() => setProcessInstance(null)}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
to={`/process-instances/${modifyProcessIdentifierForPathParam(
|
|
||||||
processInstance.process_model_identifier
|
|
||||||
)}/${processInstance.id}`}
|
|
||||||
data-qa="process-instance-show-link"
|
|
||||||
>
|
|
||||||
view
|
|
||||||
</Link>
|
|
||||||
</Notification>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
let recentProcessModels: RecentProcessModel[] = [];
|
let recentProcessModels: RecentProcessModel[] = [];
|
||||||
const recentProcessModelsString = localStorage.getItem('recentProcessModels');
|
const recentProcessModelsString = localStorage.getItem('recentProcessModels');
|
||||||
if (recentProcessModelsString !== null) {
|
if (recentProcessModelsString !== null) {
|
||||||
@ -163,10 +138,7 @@ export default function MyTasks() {
|
|||||||
</Link>
|
</Link>
|
||||||
</td>
|
</td>
|
||||||
<td className="actions-cell">
|
<td className="actions-cell">
|
||||||
<ProcessInstanceRun
|
<ProcessInstanceRun processModel={processModel} />
|
||||||
processModel={processModel}
|
|
||||||
onSuccessCallback={setProcessInstance}
|
|
||||||
/>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
@ -220,7 +192,6 @@ export default function MyTasks() {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{processInstanceRunResultTag()}
|
|
||||||
{tasksWaitingForMe}
|
{tasksWaitingForMe}
|
||||||
<br />
|
<br />
|
||||||
{relevantProcessModelSection}
|
{relevantProcessModelSection}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import MDEditor from '@uiw/react-md-editor';
|
|
||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import { Onboarding } from '../interfaces';
|
import { Onboarding } from '../interfaces';
|
||||||
import { objectIsEmpty } from '../helpers';
|
import { objectIsEmpty } from '../helpers';
|
||||||
|
import MarkdownRenderer from '../components/MarkdownRenderer';
|
||||||
|
|
||||||
export default function OnboardingView() {
|
export default function OnboardingView() {
|
||||||
const [onboarding, setOnboarding] = useState<Onboarding | null>(null);
|
const [onboarding, setOnboarding] = useState<Onboarding | null>(null);
|
||||||
@ -40,13 +40,11 @@ export default function OnboardingView() {
|
|||||||
onboarding.instructions.length > 0
|
onboarding.instructions.length > 0
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<div data-color-mode="light">
|
<MarkdownRenderer
|
||||||
<MDEditor.Markdown
|
className="onboarding"
|
||||||
className="onboarding"
|
linkTarget="_blank"
|
||||||
linkTarget="_blank"
|
source={onboarding.instructions}
|
||||||
source={onboarding.instructions}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -38,12 +38,7 @@ import {
|
|||||||
modifyProcessIdentifierForPathParam,
|
modifyProcessIdentifierForPathParam,
|
||||||
setPageTitle,
|
setPageTitle,
|
||||||
} from '../helpers';
|
} from '../helpers';
|
||||||
import {
|
import { PermissionsToCheck, ProcessFile, ProcessModel } from '../interfaces';
|
||||||
PermissionsToCheck,
|
|
||||||
ProcessFile,
|
|
||||||
ProcessInstance,
|
|
||||||
ProcessModel,
|
|
||||||
} from '../interfaces';
|
|
||||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||||
import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
|
import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
|
||||||
import { usePermissionFetcher } from '../hooks/PermissionService';
|
import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||||
@ -59,8 +54,6 @@ export default function ProcessModelShow() {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [processModel, setProcessModel] = useState<ProcessModel | null>(null);
|
const [processModel, setProcessModel] = useState<ProcessModel | null>(null);
|
||||||
const [processInstance, setProcessInstance] =
|
|
||||||
useState<ProcessInstance | null>(null);
|
|
||||||
const [reloadModel, setReloadModel] = useState<boolean>(false);
|
const [reloadModel, setReloadModel] = useState<boolean>(false);
|
||||||
const [filesToUpload, setFilesToUpload] = useState<any>(null);
|
const [filesToUpload, setFilesToUpload] = useState<any>(null);
|
||||||
const [showFileUploadModal, setShowFileUploadModal] =
|
const [showFileUploadModal, setShowFileUploadModal] =
|
||||||
@ -120,25 +113,6 @@ export default function ProcessModelShow() {
|
|||||||
});
|
});
|
||||||
}, [reloadModel, modifiedProcessModelId]);
|
}, [reloadModel, modifiedProcessModelId]);
|
||||||
|
|
||||||
const processInstanceRunResultTag = () => {
|
|
||||||
if (processInstance) {
|
|
||||||
return (
|
|
||||||
<Notification
|
|
||||||
title="Process Instance Kicked Off:"
|
|
||||||
onClose={() => setProcessInstance(null)}
|
|
||||||
>
|
|
||||||
<Link
|
|
||||||
to={`/process-instances/for-me/${modifiedProcessModelId}/${processInstance.id}`}
|
|
||||||
data-qa="process-instance-show-link"
|
|
||||||
>
|
|
||||||
view
|
|
||||||
</Link>
|
|
||||||
</Notification>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onUploadedCallback = () => {
|
const onUploadedCallback = () => {
|
||||||
setReloadModel(true);
|
setReloadModel(true);
|
||||||
};
|
};
|
||||||
@ -729,10 +703,7 @@ export default function ProcessModelShow() {
|
|||||||
ability={ability}
|
ability={ability}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<ProcessInstanceRun
|
<ProcessInstanceRun processModel={processModel} />
|
||||||
processModel={processModel}
|
|
||||||
onSuccessCallback={setProcessInstance}
|
|
||||||
/>
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
</>
|
</>
|
||||||
@ -753,7 +724,6 @@ export default function ProcessModelShow() {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{processModelPublishMessage()}
|
{processModelPublishMessage()}
|
||||||
{processInstanceRunResultTag()}
|
|
||||||
<Stack orientation="horizontal" gap={1}>
|
<Stack orientation="horizontal" gap={1}>
|
||||||
<h1 className="with-icons">
|
<h1 className="with-icons">
|
||||||
Process Model: {processModel.display_name}
|
Process Model: {processModel.display_name}
|
||||||
|
@ -4,7 +4,6 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|||||||
import { Grid, Column, Button, ButtonSet, Loading } from '@carbon/react';
|
import { Grid, Column, Button, ButtonSet, Loading } from '@carbon/react';
|
||||||
|
|
||||||
import { useDebouncedCallback } from 'use-debounce';
|
import { useDebouncedCallback } from 'use-debounce';
|
||||||
import MDEditor from '@uiw/react-md-editor';
|
|
||||||
import HttpService from '../services/HttpService';
|
import HttpService from '../services/HttpService';
|
||||||
import useAPIError from '../hooks/UseApiError';
|
import useAPIError from '../hooks/UseApiError';
|
||||||
import {
|
import {
|
||||||
@ -23,6 +22,7 @@ import CustomForm from '../components/CustomForm';
|
|||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
import InstructionsForEndUser from '../components/InstructionsForEndUser';
|
import InstructionsForEndUser from '../components/InstructionsForEndUser';
|
||||||
import UserService from '../services/UserService';
|
import UserService from '../services/UserService';
|
||||||
|
import MarkdownRenderer from '../components/MarkdownRenderer';
|
||||||
|
|
||||||
export default function TaskShow() {
|
export default function TaskShow() {
|
||||||
// get a basic task which doesn't get the form data so we can load
|
// get a basic task which doesn't get the form data so we can load
|
||||||
@ -397,9 +397,7 @@ export default function TaskShow() {
|
|||||||
|
|
||||||
if (guestConfirmationText) {
|
if (guestConfirmationText) {
|
||||||
pageElements.push(
|
pageElements.push(
|
||||||
<div data-color-mode="light">
|
<MarkdownRenderer linkTarget="_blank" source={guestConfirmationText} />
|
||||||
<MDEditor.Markdown linkTarget="_blank" source={guestConfirmationText} />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
} else if (basicTask && taskData) {
|
} else if (basicTask && taskData) {
|
||||||
pageElements.push(<InstructionsForEndUser task={taskWithTaskData} />);
|
pageElements.push(<InstructionsForEndUser task={taskWithTaskData} />);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user