added some support to add process model metadata. need to fix frontend w/ burnettk
This commit is contained in:
parent
20ca5a2978
commit
6b75fc32a3
|
@ -38,6 +38,7 @@ class ProcessModelInfo:
|
|||
fault_or_suspend_on_exception: str = NotificationType.fault.value
|
||||
exception_notification_addresses: list[str] = field(default_factory=list)
|
||||
parent_groups: list[dict] | None = None
|
||||
metadata_extraction_paths: dict[str, str] | None = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""__post_init__."""
|
||||
|
@ -76,6 +77,8 @@ class ProcessModelInfoSchema(Schema):
|
|||
exception_notification_addresses = marshmallow.fields.List(
|
||||
marshmallow.fields.String
|
||||
)
|
||||
metadata_extraction_paths = marshmallow.fields.Dict(keys=marshmallow.fields.Str(required=False), values=marshmallow.fields.Str(required=False), required=False)
|
||||
|
||||
|
||||
@post_load
|
||||
def make_spec(
|
||||
|
|
|
@ -261,19 +261,26 @@ def process_model_create(
|
|||
modified_process_group_id: str, body: Dict[str, Union[str, bool, int]]
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_create."""
|
||||
process_model_info = ProcessModelInfoSchema().load(body)
|
||||
body_include_list = [
|
||||
"id",
|
||||
"display_name",
|
||||
"primary_file_name",
|
||||
"primary_process_id",
|
||||
"description",
|
||||
"metadata_extraction_paths",
|
||||
]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
if modified_process_group_id is None:
|
||||
raise ApiError(
|
||||
error_code="process_group_id_not_specified",
|
||||
message="Process Model could not be created when process_group_id path param is unspecified",
|
||||
status_code=400,
|
||||
)
|
||||
if process_model_info is None:
|
||||
raise ApiError(
|
||||
error_code="process_model_could_not_be_created",
|
||||
message=f"Process Model could not be created from given body: {body}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
unmodified_process_group_id = un_modify_modified_process_model_id(
|
||||
modified_process_group_id
|
||||
|
@ -286,6 +293,14 @@ def process_model_create(
|
|||
status_code=400,
|
||||
)
|
||||
|
||||
process_model_info = ProcessModelInfo(**body_filtered) # type: ignore
|
||||
if process_model_info is None:
|
||||
raise ApiError(
|
||||
error_code="process_model_could_not_be_created",
|
||||
message=f"Process Model could not be created from given body: {body}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
ProcessModelService.add_process_model(process_model_info)
|
||||
return Response(
|
||||
json.dumps(ProcessModelInfoSchema().dump(process_model_info)),
|
||||
|
@ -299,7 +314,6 @@ def process_model_delete(
|
|||
) -> flask.wrappers.Response:
|
||||
"""Process_model_delete."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
# process_model_identifier = f"{process_group_id}/{process_model_id}"
|
||||
ProcessModelService().process_model_delete(process_model_identifier)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
@ -314,6 +328,7 @@ def process_model_update(
|
|||
"primary_file_name",
|
||||
"primary_process_id",
|
||||
"description",
|
||||
"metadata_extraction_paths",
|
||||
]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
|
@ -321,7 +336,6 @@ def process_model_update(
|
|||
if include_item in body
|
||||
}
|
||||
|
||||
# process_model_identifier = f"{process_group_id}/{process_model_id}"
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
ProcessModelService.update_process_model(process_model, body_filtered)
|
||||
return ProcessModelInfoSchema().dump(process_model)
|
||||
|
@ -330,10 +344,7 @@ def process_model_update(
|
|||
def process_model_show(modified_process_model_identifier: str) -> Any:
|
||||
"""Process_model_show."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
# process_model_identifier = f"{process_group_id}/{process_model_id}"
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
# TODO: Temporary. Should not need the next line once models have correct ids
|
||||
# process_model.id = process_model_identifier
|
||||
files = sorted(SpecFileService.get_files(process_model))
|
||||
process_model.files = files
|
||||
for file in process_model.files:
|
||||
|
@ -425,7 +436,6 @@ def process_model_file_update(
|
|||
) -> flask.wrappers.Response:
|
||||
"""Process_model_file_update."""
|
||||
process_model_identifier = modified_process_model_id.replace(":", "/")
|
||||
# process_model_identifier = f"{process_group_id}/{process_model_id}"
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
|
||||
request_file = get_file_from_request()
|
||||
|
@ -1142,7 +1152,7 @@ def process_instance_report_show(
|
|||
per_page: int = 100,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_show."""
|
||||
process_instances = ProcessInstanceModel.query.order_by( # .filter_by(process_model_identifier=process_model.id)
|
||||
process_instances = ProcessInstanceModel.query.order_by(
|
||||
ProcessInstanceModel.start_in_seconds.desc(), ProcessInstanceModel.id.desc() # type: ignore
|
||||
).paginate(
|
||||
page=page, per_page=per_page, error_out=False
|
||||
|
|
|
@ -333,6 +333,7 @@ class TestProcessApi(BaseTest):
|
|||
process_model.display_name = "Updated Display Name"
|
||||
process_model.primary_file_name = "superduper.bpmn"
|
||||
process_model.primary_process_id = "superduper"
|
||||
process_model.metadata_extraction_paths = {'extraction1': 'path1'}
|
||||
|
||||
modified_process_model_identifier = process_model_identifier.replace("/", ":")
|
||||
response = client.put(
|
||||
|
@ -346,6 +347,7 @@ class TestProcessApi(BaseTest):
|
|||
assert response.json["display_name"] == "Updated Display Name"
|
||||
assert response.json["primary_file_name"] == "superduper.bpmn"
|
||||
assert response.json["primary_process_id"] == "superduper"
|
||||
assert response.json["metadata_extraction_paths"] == {'extraction1': 'path1'}
|
||||
|
||||
def test_process_model_list_all(
|
||||
self,
|
||||
|
|
|
@ -142,7 +142,7 @@ export default function ProcessInstanceListTable({
|
|||
ReportColumn[]
|
||||
>([]);
|
||||
const [processInstanceReportJustSaved, setProcessInstanceReportJustSaved] =
|
||||
useState<boolean>(false);
|
||||
useState<string | null>(null);
|
||||
const [showReportColumnForm, setShowReportColumnForm] =
|
||||
useState<boolean>(false);
|
||||
const [reportColumnToOperateOn, setReportColumnToOperateOn] =
|
||||
|
@ -367,10 +367,14 @@ export default function ProcessInstanceListTable({
|
|||
|
||||
const processInstanceReportSaveTag = () => {
|
||||
if (processInstanceReportJustSaved) {
|
||||
let titleOperation = 'Updated';
|
||||
if (processInstanceReportJustSaved === 'new') {
|
||||
titleOperation = 'Created';
|
||||
}
|
||||
return (
|
||||
<InlineNotification
|
||||
title="Perspective Saved"
|
||||
subtitle={`as '${
|
||||
title={`Perspective ${titleOperation}:`}
|
||||
subtitle={`'${
|
||||
processInstanceReportSelection
|
||||
? processInstanceReportSelection.identifier
|
||||
: ''
|
||||
|
@ -498,7 +502,7 @@ export default function ProcessInstanceListTable({
|
|||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
setProcessInstanceReportJustSaved(false);
|
||||
setProcessInstanceReportJustSaved(null);
|
||||
navigate(`/admin/process-instances?${queryParamString}`);
|
||||
};
|
||||
|
||||
|
@ -586,10 +590,7 @@ export default function ProcessInstanceListTable({
|
|||
setEndToTime('');
|
||||
};
|
||||
|
||||
const processInstanceReportDidChange = (
|
||||
selection: any,
|
||||
savedReport: boolean = false
|
||||
) => {
|
||||
const processInstanceReportDidChange = (selection: any, mode?: string) => {
|
||||
clearFilters();
|
||||
const selectedReport = selection.selectedItem;
|
||||
setProcessInstanceReportSelection(selectedReport);
|
||||
|
@ -600,7 +601,7 @@ export default function ProcessInstanceListTable({
|
|||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
setProcessInstanceReportJustSaved(savedReport);
|
||||
setProcessInstanceReportJustSaved(mode || null);
|
||||
navigate(`/admin/process-instances${queryParamString}`);
|
||||
};
|
||||
|
||||
|
@ -615,12 +616,12 @@ export default function ProcessInstanceListTable({
|
|||
};
|
||||
|
||||
// TODO onSuccess reload/select the new report in the report search
|
||||
const onSaveReportSuccess = (result: any) => {
|
||||
const onSaveReportSuccess = (result: any, mode: string) => {
|
||||
processInstanceReportDidChange(
|
||||
{
|
||||
selectedItem: result,
|
||||
},
|
||||
true
|
||||
mode
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -638,7 +639,7 @@ export default function ProcessInstanceListTable({
|
|||
}
|
||||
return (
|
||||
<ProcessInstanceListSaveAsReport
|
||||
onSuccess={onSaveReportSuccess}
|
||||
onSuccess={(result: any) => onSaveReportSuccess(result, 'new')}
|
||||
buttonClassName="narrow-button"
|
||||
columnArray={reportColumns()}
|
||||
orderBy=""
|
||||
|
@ -705,7 +706,7 @@ export default function ProcessInstanceListTable({
|
|||
} else {
|
||||
newReportFilters.splice(existingReportFilterIndex, 1);
|
||||
}
|
||||
} else {
|
||||
} else if (reportColumnForEditing.filter_field_value) {
|
||||
newReportFilters = newReportFilters.concat([newReportFilter]);
|
||||
}
|
||||
}
|
||||
|
@ -1157,7 +1158,7 @@ export default function ProcessInstanceListTable({
|
|||
<Column sm={2} md={4} lg={2}>
|
||||
<ProcessInstanceListSaveAsReport
|
||||
buttonClassName="with-tiny-top-margin"
|
||||
onSuccess={onSaveReportSuccess}
|
||||
onSuccess={(result: any) => onSaveReportSuccess(result, 'edit')}
|
||||
columnArray={reportColumns()}
|
||||
orderBy=""
|
||||
buttonText="Save"
|
||||
|
|
|
@ -2,9 +2,11 @@ import { useState } from 'react';
|
|||
import { useNavigate } from 'react-router-dom';
|
||||
// @ts-ignore
|
||||
import { Button, ButtonSet, Form, Stack, TextInput } from '@carbon/react';
|
||||
// @ts-ignore
|
||||
import { AddAlt } from '@carbon/icons-react';
|
||||
import { modifyProcessIdentifierForPathParam, slugifyString } from '../helpers';
|
||||
import HttpService from '../services/HttpService';
|
||||
import { ProcessModel } from '../interfaces';
|
||||
import { MetadataExtractionPaths, ProcessModel } from '../interfaces';
|
||||
|
||||
type OwnProps = {
|
||||
mode: string;
|
||||
|
@ -23,6 +25,7 @@ export default function ProcessModelForm({
|
|||
const [idHasBeenUpdatedByUser, setIdHasBeenUpdatedByUser] =
|
||||
useState<boolean>(false);
|
||||
const [displayNameInvalid, setDisplayNameInvalid] = useState<boolean>(false);
|
||||
useState<boolean>(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
const navigateToProcessModel = (result: ProcessModel) => {
|
||||
|
@ -64,6 +67,7 @@ export default function ProcessModelForm({
|
|||
const postBody = {
|
||||
display_name: processModel.display_name,
|
||||
description: processModel.description,
|
||||
metadata_extraction_paths: processModel.metadata_extraction_paths,
|
||||
};
|
||||
if (mode === 'new') {
|
||||
Object.assign(postBody, {
|
||||
|
@ -87,6 +91,66 @@ export default function ProcessModelForm({
|
|||
setProcessModel(processModelToCopy);
|
||||
};
|
||||
|
||||
const metadataExtractionPathForm = (
|
||||
metadataKey: string,
|
||||
metadataPath: string
|
||||
) => {
|
||||
return (
|
||||
<>
|
||||
<TextInput
|
||||
id="process-model-metadata-extraction-path-key"
|
||||
labelText="Extraction Key"
|
||||
value={metadataKey}
|
||||
onChange={(event: any) => {
|
||||
const cep: MetadataExtractionPaths =
|
||||
processModel.metadata_extraction_paths || {};
|
||||
delete cep[metadataKey];
|
||||
cep[event.target.value] = metadataPath;
|
||||
updateProcessModel({ metadata_extraction_paths: cep });
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
id="process-model-metadata-extraction-path"
|
||||
labelText="Extraction Path"
|
||||
value={metadataPath}
|
||||
onChange={(event: any) => {
|
||||
const cep: MetadataExtractionPaths =
|
||||
processModel.metadata_extraction_paths || {};
|
||||
cep[metadataKey] = event.target.value;
|
||||
updateProcessModel({ metadata_extraction_paths: cep });
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const metadataExtractionPathFormArea = () => {
|
||||
if (processModel.metadata_extraction_paths) {
|
||||
console.log(
|
||||
'processModel.metadata_extraction_paths',
|
||||
processModel.metadata_extraction_paths
|
||||
);
|
||||
return Object.keys(processModel.metadata_extraction_paths).map(
|
||||
(metadataKey: string) => {
|
||||
return metadataExtractionPathForm(
|
||||
metadataKey,
|
||||
processModel.metadata_extraction_paths
|
||||
? processModel.metadata_extraction_paths[metadataKey]
|
||||
: ''
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const addBlankMetadataExtractionPath = () => {
|
||||
const cep: MetadataExtractionPaths =
|
||||
processModel.metadata_extraction_paths || {};
|
||||
Object.assign(cep, { '': '' });
|
||||
updateProcessModel({ metadata_extraction_paths: cep });
|
||||
};
|
||||
|
||||
const onDisplayNameChanged = (newDisplayName: any) => {
|
||||
setDisplayNameInvalid(false);
|
||||
const updateDict = { display_name: newDisplayName };
|
||||
|
@ -145,6 +209,22 @@ export default function ProcessModelForm({
|
|||
/>
|
||||
);
|
||||
|
||||
textInputs.push(<>{metadataExtractionPathFormArea()}</>);
|
||||
textInputs.push(
|
||||
<Button
|
||||
data-qa="add-metadata-extraction-path-button"
|
||||
renderIcon={AddAlt}
|
||||
className="button-white-background"
|
||||
kind=""
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
addBlankMetadataExtractionPath();
|
||||
}}
|
||||
>
|
||||
Add Metadata Extraction Path
|
||||
</Button>
|
||||
);
|
||||
|
||||
return textInputs;
|
||||
};
|
||||
|
||||
|
|
|
@ -98,6 +98,10 @@ export interface ProcessGroupLite {
|
|||
display_name: string;
|
||||
}
|
||||
|
||||
export interface MetadataExtractionPaths {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
export interface ProcessModel {
|
||||
id: string;
|
||||
description: string;
|
||||
|
@ -105,6 +109,7 @@ export interface ProcessModel {
|
|||
primary_file_name: string;
|
||||
files: ProcessFile[];
|
||||
parent_groups?: ProcessGroupLite[];
|
||||
metadata_extraction_paths?: MetadataExtractionPaths;
|
||||
}
|
||||
|
||||
export interface ProcessGroup {
|
||||
|
|
Loading…
Reference in New Issue