merged in main and resolved conflicts w/ burnettk cullerton

This commit is contained in:
jasquat 2022-11-08 17:49:23 -05:00
commit 1029b36a1b
11 changed files with 246 additions and 190 deletions

View File

@ -259,7 +259,7 @@ def process_model_update(
) -> Any:
"""Process_model_update."""
process_model_identifier = modified_process_model_identifier.replace(":", "/")
body_include_list = ["display_name", "primary_file_name", "primary_process_id"]
body_include_list = ["display_name", "primary_file_name", "primary_process_id", "description"]
body_filtered = {
include_item: body[include_item]
for include_item in body_include_list

View File

@ -95,7 +95,7 @@ export default function ProcessGroupForm({
const onDisplayNameChanged = (newDisplayName: any) => {
setDisplayNameInvalid(false);
const updateDict = { display_name: newDisplayName };
if (!idHasBeenUpdatedByUser) {
if (!idHasBeenUpdatedByUser && mode === 'new') {
Object.assign(updateDict, { id: slugifyString(newDisplayName) });
}
updateProcessGroup(updateDict);

View File

@ -0,0 +1,193 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
// @ts-ignore
import { Button, ButtonSet, Form, Stack, TextInput } from '@carbon/react';
import {
getGroupFromModifiedModelId,
modifyProcessModelPath,
slugifyString,
} from '../helpers';
import HttpService from '../services/HttpService';
import { ProcessModel } from '../interfaces';
import ButtonWithConfirmation from './ButtonWithConfirmation';
type OwnProps = {
mode: string;
processModel: ProcessModel;
setProcessModel: (..._args: any[]) => any;
};
export default function ProcessModelForm({
mode,
processModel,
setProcessModel,
}: OwnProps) {
const [identifierInvalid, setIdentifierInvalid] = useState<boolean>(false);
const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] =
useState<boolean>(false);
const [displayNameInvalid, setDisplayNameInvalid] = useState<boolean>(false);
const navigate = useNavigate();
const modifiedProcessModelPath = modifyProcessModelPath(processModel.id);
const navigateToProcessModel = (_result: any) => {
if (processModel) {
navigate(`/admin/process-models/${modifiedProcessModelPath}`);
}
};
const navigateToProcessModels = (_result: any) => {
navigate(
`/admin/process-groups/${getGroupFromModifiedModelId(
modifiedProcessModelPath
)}`
);
};
const hasValidIdentifier = (identifierToCheck: string) => {
return identifierToCheck.match(/^[a-z0-9][0-9a-z-]+[a-z0-9]$/);
};
const deleteProcessModel = () => {
HttpService.makeCallToBackend({
path: `/process-models/${modifiedProcessModelPath}`,
successCallback: navigateToProcessModels,
httpMethod: 'DELETE',
});
};
const handleFormSubmission = (event: any) => {
event.preventDefault();
let hasErrors = false;
if (!hasValidIdentifier(processModel.id)) {
setIdentifierInvalid(true);
hasErrors = true;
}
if (processModel.display_name === '') {
setDisplayNameInvalid(true);
hasErrors = true;
}
if (hasErrors) {
return;
}
let path = `/process-models`;
if (mode === 'edit') {
path = `/process-models/${modifiedProcessModelPath}`;
}
let httpMethod = 'POST';
if (mode === 'edit') {
httpMethod = 'PUT';
}
const postBody = {
display_name: processModel.display_name,
description: processModel.description,
};
if (mode === 'new') {
Object.assign(postBody, {
id: processModel.id,
});
}
HttpService.makeCallToBackend({
path,
successCallback: navigateToProcessModel,
httpMethod,
postBody,
});
};
const updateProcessModel = (newValues: any) => {
const processModelToCopy = {
...processModel,
};
Object.assign(processModelToCopy, newValues);
setProcessModel(processModelToCopy);
};
const onDisplayNameChanged = (newDisplayName: any) => {
setDisplayNameInvalid(false);
const updateDict = { display_name: newDisplayName };
if (!idHasBeenUpdatedByUser && mode === 'new') {
Object.assign(updateDict, { id: slugifyString(newDisplayName) });
}
updateProcessModel(updateDict);
};
const formElements = () => {
const textInputs = [
<TextInput
id="process-model-display-name"
name="display_name"
invalidText="Display Name is required."
invalid={displayNameInvalid}
labelText="Display Name*"
value={processModel.display_name}
onChange={(event: any) => {
onDisplayNameChanged(event.target.value);
}}
onBlur={(event: any) => console.log('event', event)}
/>,
];
if (mode === 'new') {
textInputs.push(
<TextInput
id="process-model-identifier"
name="id"
invalidText="Identifier is required and must be all lowercase characters and hyphens."
invalid={identifierInvalid}
labelText="Identifier*"
value={processModel.id}
onChange={(event: any) => {
updateProcessModel({ id: event.target.value });
// was invalid, and now valid
if (identifierInvalid && hasValidIdentifier(event.target.value)) {
setIdentifierInvalid(false);
}
setIdHasBeenUpdatedByUser(true);
}}
/>
);
}
textInputs.push(
<TextInput
id="process-model-description"
name="description"
labelText="Description"
value={processModel.description}
onChange={(event: any) =>
updateProcessModel({ description: event.target.value })
}
/>
);
return textInputs;
};
const formButtons = () => {
const buttons = [
<Button kind="secondary" type="submit">
Submit
</Button>,
];
if (mode === 'edit') {
buttons.push(
<ButtonWithConfirmation
description={`Delete Process Model ${processModel.id}?`}
onConfirmation={deleteProcessModel}
buttonLabel="Delete"
confirmButtonLabel="Delete"
/>
);
}
return <ButtonSet>{buttons}</ButtonSet>;
};
return (
<Form onSubmit={handleFormSubmission}>
<Stack gap={5}>
{formElements()}
{formButtons()}
</Stack>
</Form>
);
}

View File

@ -21,7 +21,7 @@ export default function ProcessModelSearch({
const shouldFilterProcessModel = (options: any) => {
const processModel: ProcessModel = options.item;
const { inputValue } = options;
return `${processModel.process_group_id}/${processModel.id} (${processModel.display_name})`.includes(
return `${processModel.id} (${processModel.display_name})`.includes(
inputValue
);
};
@ -33,9 +33,10 @@ export default function ProcessModelSearch({
items={processModels}
itemToString={(processModel: ProcessModel) => {
if (processModel) {
return `${processModel.process_group_id}/${
processModel.id
} (${truncateString(processModel.display_name, 20)})`;
return `${processModel.id} (${truncateString(
processModel.display_name,
20
)})`;
}
return null;
}}

View File

@ -27,7 +27,6 @@ export interface ProcessFile {
content_type: string;
last_modified: string;
name: string;
process_group_id: string;
process_model_id: string;
references: ProcessFileReference[];
size: number;
@ -38,7 +37,6 @@ export interface ProcessFile {
export interface ProcessModel {
id: string;
description: string;
process_group_id: string;
display_name: string;
primary_file_name: string;
files: ProcessFile[];

View File

@ -13,7 +13,10 @@ import {
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import PaginationForTable from '../components/PaginationForTable';
import HttpService from '../services/HttpService';
import { getPageInfoFromSearchParams } from '../helpers';
import {
getPageInfoFromSearchParams,
modifyProcessModelPath,
} from '../helpers';
import { CarbonComboBoxSelection, ProcessGroup } from '../interfaces';
import ProcessModelSearch from '../components/ProcessModelSearch';
@ -36,7 +39,7 @@ export default function ProcessGroupList() {
};
const processResultForProcessModels = (result: any) => {
const selectionArray = result.results.map((item: any) => {
const label = `${item.process_group_id}/${item.id}`;
const label = `${item.id}`;
Object.assign(item, { label });
return item;
});
@ -120,7 +123,7 @@ export default function ProcessGroupList() {
const processModelSearchOnChange = (selection: CarbonComboBoxSelection) => {
const processModel = selection.selectedItem;
navigate(
`/admin/process-models/${processModel.process_group_id}/${processModel.id}`
`/admin/process-models/${modifyProcessModelPath(processModel.id)}`
);
};
return (

View File

@ -86,7 +86,6 @@ export default function ProcessInstanceList() {
const parametersToGetFromSearchParams = useMemo(() => {
return {
process_group_identifier: null,
process_model_identifier: null,
process_status: null,
};
@ -138,7 +137,7 @@ export default function ProcessInstanceList() {
const processModelFullIdentifier =
getProcessModelFullIdentifierFromSearchParams(searchParams);
const selectionArray = result.results.map((item: any) => {
const label = `${item.process_group_id}/${item.id}`;
const label = `${item.id}`;
Object.assign(item, { label });
if (label === processModelFullIdentifier) {
setProcessModelSelection(item);
@ -244,7 +243,7 @@ export default function ProcessInstanceList() {
}
if (processModelSelection) {
queryParamString += `&process_group_identifier=${processModelSelection.process_group_id}&process_model_identifier=${processModelSelection.id}`;
queryParamString += `&process_model_identifier=${processModelSelection.id}`;
}
setErrorMessage(null);
@ -383,7 +382,6 @@ export default function ProcessInstanceList() {
const buildTable = () => {
const headerLabels: Record<string, string> = {
id: 'Process Instance Id',
process_group_identifier: 'Process Group',
process_model_identifier: 'Process Model',
start_in_seconds: 'Start Time',
end_in_seconds: 'End Time',
@ -418,7 +416,7 @@ export default function ProcessInstanceList() {
const formatProcessModelIdentifier = (row: any, identifier: any) => {
return (
<Link
to={`/admin/process-models/${row.process_group_identifier}/${identifier}`}
to={`/admin/process-models/${modifyProcessModelPath(identifier)}`}
>
{identifier}
</Link>
@ -433,7 +431,6 @@ export default function ProcessInstanceList() {
const columnFormatters: Record<string, any> = {
id: formatProcessInstanceId,
process_group_identifier: formatProcessGroupIdentifier,
process_model_identifier: formatProcessModelIdentifier,
start_in_seconds: formatSecondsForDisplay,
end_in_seconds: formatSecondsForDisplay,

View File

@ -1,113 +1,32 @@
import { useState, useEffect, useContext } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
// @ts-ignore
import { Button, Stack } from '@carbon/react';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import HttpService from '../services/HttpService';
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
import ErrorContext from '../contexts/ErrorContext';
import {
getGroupFromModifiedModelId,
modifyProcessModelPath,
} from '../helpers';
import ProcessModelForm from '../components/ProcessModelForm';
export default function ProcessModelEdit() {
const [displayName, setDisplayName] = useState('');
const params = useParams();
const navigate = useNavigate();
const [processModel, setProcessModel] = useState(null);
const setErrorMessage = (useContext as any)(ErrorContext)[1];
const processModelPath = `process-models/${params.process_model_id}`;
useEffect(() => {
const processResult = (result: any) => {
setProcessModel(result);
setDisplayName(result.display_name);
};
console.log(`processModelPath: ${processModelPath}`);
HttpService.makeCallToBackend({
path: `/${processModelPath}`,
successCallback: processResult,
successCallback: setProcessModel,
});
}, [processModelPath]);
const navigateToProcessModel = (_result: any) => {
console.log(`processModelPath: ${processModelPath}`);
navigate(`/admin/${processModelPath}`);
};
const navigateToProcessModels = (_result: any) => {
const processGroupId = getGroupFromModifiedModelId(
(params as any).process_model_id
);
const modifiedProcessGroupId = modifyProcessModelPath(processGroupId);
navigate(`/admin/process-groups/${modifiedProcessGroupId}`);
};
const updateProcessModel = (event: any) => {
const processModelToUse = processModel as any;
event.preventDefault();
const processModelToPass = Object.assign(processModelToUse, {
display_name: displayName,
});
console.log(`processModelPath: ${processModelPath}`);
HttpService.makeCallToBackend({
path: `/${processModelPath}`,
successCallback: navigateToProcessModel,
httpMethod: 'PUT',
postBody: processModelToPass,
});
};
// share with or delete from ProcessModelEditDiagram
const deleteProcessModel = () => {
setErrorMessage(null);
const processModelToUse = processModel as any;
const modifiedProcessModelId: String = modifyProcessModelPath(
(processModelToUse as any).id
);
const processModelShowPath = `/process-models/${modifiedProcessModelId}`;
console.log(`processModelShowPath: ${processModelShowPath}`);
HttpService.makeCallToBackend({
path: `${processModelShowPath}`,
successCallback: navigateToProcessModels,
httpMethod: 'DELETE',
failureCallback: setErrorMessage,
});
};
const onDisplayNameChanged = (newDisplayName: any) => {
setDisplayName(newDisplayName);
};
if (processModel) {
return (
<>
<ProcessBreadcrumb processGroupId={(processModel as any).id} />
<h2>Edit Process Group: {(processModel as any).id}</h2>
<form onSubmit={updateProcessModel}>
<label>Display Name:</label>
<input
name="display_name"
type="text"
value={displayName}
onChange={(e) => onDisplayNameChanged(e.target.value)}
/>
<br />
<br />
<Stack orientation="horizontal" gap={3}>
<Button type="submit">Submit</Button>
<Button variant="secondary" href={`/admin/${processModelPath}`}>
Cancel
</Button>
<ButtonWithConfirmation
description={`Delete Process Model ${(processModel as any).id}?`}
onConfirmation={deleteProcessModel}
buttonLabel="Delete"
/>
</Stack>
</form>
<ProcessBreadcrumb processGroupId={params.process_group_id} />
<h2>Edit Process Model: {(processModel as any).id}</h2>
<ProcessModelForm
mode="edit"
processModel={processModel}
setProcessModel={setProcessModel}
/>
</>
);
}

View File

@ -1,74 +1,26 @@
import { useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
import { slugifyString } from '../helpers';
import HttpService from '../services/HttpService';
import { ProcessModel } from '../interfaces';
import ProcessModelForm from '../components/ProcessModelForm';
export default function ProcessModelNew() {
const params = useParams();
const [identifier, setIdentifier] = useState('');
const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] = useState(false);
const [displayName, setDisplayName] = useState('');
const navigate = useNavigate();
const navigateToNewProcessModel = (_result: any) => {
navigate(`/admin/process-models/${params.process_group_id}/${identifier}`);
};
const addProcessModel = (event: any) => {
event.preventDefault();
HttpService.makeCallToBackend({
path: `/process-models`,
successCallback: navigateToNewProcessModel,
httpMethod: 'POST',
postBody: {
id: `${params.process_group_id}/${identifier}`,
display_name: displayName,
description: displayName,
},
});
};
const onDisplayNameChanged = (newDisplayName: any) => {
setDisplayName(newDisplayName);
if (!idHasBeenUpdatedByUser) {
setIdentifier(slugifyString(newDisplayName));
}
};
const [processModel, setProcessModel] = useState<ProcessModel>({
id: '',
display_name: '',
description: '',
primary_file_name: '',
files: [],
});
return (
<>
<ProcessBreadcrumb />
<h2>Add Process Model</h2>
<Form onSubmit={addProcessModel}>
<Form.Group className="mb-3" controlId="display_name">
<Form.Label>Display Name:</Form.Label>
<Form.Control
name="display_name"
type="text"
value={displayName}
onChange={(e) => onDisplayNameChanged(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="identifier">
<Form.Label>ID:</Form.Label>
<Form.Control
name="id"
type="text"
value={identifier}
onChange={(e) => {
setIdentifier(e.target.value);
setIdHasBeenUpdatedByUser(true);
}}
/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
<ProcessModelForm
mode="new"
processModel={processModel}
setProcessModel={setProcessModel}
/>
</>
);
}

View File

@ -32,14 +32,6 @@ import { modifyProcessModelPath, unModifyProcessModelPath } from '../helpers';
import { ProcessFile, ProcessModel, RecentProcessModel } from '../interfaces';
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
// interface ProcessModelFileCarbonDropdownItem {
// label: string;
// action: string;
// processModelFile: ProcessFile;
// needsConfirmation: boolean;
// icon: any;
// }
const storeRecentProcessModelInLocalStorage = (
processModelForStorage: any,
params: any
@ -184,7 +176,7 @@ export default function ProcessModelShow() {
// Remove this code from
const onDeleteFile = (fileName: string) => {
const url = `/process-models/${params.process_group_id}/${params.process_model_id}/files/${fileName}`;
const url = `/process-models/${modifiedProcessModelId}/files/${fileName}`;
const httpMethod = 'DELETE';
HttpService.makeCallToBackend({
path: url,
@ -193,15 +185,8 @@ export default function ProcessModelShow() {
});
};
// const onProcessModelFileAction = (selection: any) => {
// const { selectedItem } = selection;
// if (selectedItem.action === 'delete') {
// onDeleteFile(selectedItem.processModelFile.name);
// }
// };
const onSetPrimaryFile = (fileName: string) => {
const url = `/process-models/${params.process_group_id}/${params.process_model_id}`;
const url = `/process-models/${modifiedProcessModelId}`;
const httpMethod = 'PUT';
const processModelToPass = {
@ -241,7 +226,7 @@ export default function ProcessModelShow() {
const downloadFile = (fileName: string) => {
setErrorMessage(null);
const processModelPath = `process-models/${params.process_group_id}/${params.process_model_id}`;
const processModelPath = `process-models/${modifiedProcessModelId}`;
HttpService.makeCallToBackend({
path: `/${processModelPath}/files/${fileName}`,
successCallback: handleProcessModelFileResult,
@ -405,7 +390,7 @@ export default function ProcessModelShow() {
const handleFileUpload = (event: any) => {
if (processModel) {
event.preventDefault();
const url = `/process-models/${processModel.process_group_id}/${processModel.id}/files`;
const url = `/process-models/${modifiedProcessModelId}/files`;
const formData = new FormData();
formData.append('file', filesToUpload[0]);
formData.append('fileName', filesToUpload[0].name);

View File

@ -152,6 +152,14 @@ export default function ReactFormEditor() {
processGroupId={params.process_group_id}
processModelId={params.process_model_id}
linkProcessModel
hotCrumbs={[
['Process Groups', '/admin'],
[
`Process Model: ${params.process_model_id}`,
`process_model:${params.process_model_id}:link`,
],
[(processModelFile as any).name || ''],
]}
/>
<h2>
Process Model File