favor report id over identifier but support both and ui updates to allow setting a condition value on a metadata field, changing the display name, and fixes for saving and updating a report
This commit is contained in:
parent
d1a69073a2
commit
a4edb5d766
|
@ -544,6 +544,12 @@ paths:
|
|||
description: Specifies the identifier of a report to use, if any
|
||||
schema:
|
||||
type: string
|
||||
- name: report_id
|
||||
in: query
|
||||
required: false
|
||||
description: Specifies the identifier of a report to use, if any
|
||||
schema:
|
||||
type: integer
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list
|
||||
summary: Returns a list of process instances for a given process model
|
||||
|
@ -857,14 +863,14 @@ paths:
|
|||
items:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
|
||||
/process-instances/reports/{report_identifier}:
|
||||
/process-instances/reports/{report_id}:
|
||||
parameters:
|
||||
- name: report_identifier
|
||||
- name: report_id
|
||||
in: path
|
||||
required: true
|
||||
description: The unique id of an existing report
|
||||
schema:
|
||||
type: string
|
||||
type: integer
|
||||
- name: page
|
||||
in: query
|
||||
required: false
|
||||
|
|
|
@ -26,6 +26,10 @@ from spiffworkflow_backend.services.process_instance_processor import (
|
|||
ReportMetadata = dict[str, Any]
|
||||
|
||||
|
||||
class ProcessInstanceReportAlreadyExistsError(Exception):
|
||||
"""ProcessInstanceReportAlreadyExistsError."""
|
||||
|
||||
|
||||
class ProcessInstanceReportResult(TypedDict):
|
||||
"""ProcessInstanceReportResult."""
|
||||
|
||||
|
@ -63,7 +67,7 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
|
|||
),
|
||||
)
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
id: int = db.Column(db.Integer, primary_key=True)
|
||||
identifier: str = db.Column(db.String(50), nullable=False, index=True)
|
||||
report_metadata: dict = deferred(db.Column(db.JSON)) # type: ignore
|
||||
created_by_id = db.Column(ForeignKey(UserModel.id), nullable=False, index=True)
|
||||
|
@ -120,21 +124,27 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
|
|||
identifier: str,
|
||||
user: UserModel,
|
||||
report_metadata: ReportMetadata,
|
||||
) -> None:
|
||||
) -> ProcessInstanceReportModel:
|
||||
"""Make_fixture_report."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=identifier,
|
||||
created_by_id=user.id,
|
||||
).first()
|
||||
|
||||
if process_instance_report is None:
|
||||
process_instance_report = cls(
|
||||
identifier=identifier,
|
||||
created_by_id=user.id,
|
||||
report_metadata=report_metadata,
|
||||
if process_instance_report is not None:
|
||||
raise ProcessInstanceReportAlreadyExistsError(
|
||||
f"Process instance report with identifier already exists: {identifier}"
|
||||
)
|
||||
db.session.add(process_instance_report)
|
||||
db.session.commit()
|
||||
|
||||
process_instance_report = cls(
|
||||
identifier=identifier,
|
||||
created_by_id=user.id,
|
||||
report_metadata=report_metadata,
|
||||
)
|
||||
db.session.add(process_instance_report)
|
||||
db.session.commit()
|
||||
|
||||
return process_instance_report # type: ignore
|
||||
|
||||
@classmethod
|
||||
def ticket_for_month_report(cls) -> dict:
|
||||
|
|
|
@ -782,10 +782,12 @@ def process_instance_list(
|
|||
with_tasks_completed_by_my_group: Optional[bool] = None,
|
||||
user_filter: Optional[bool] = False,
|
||||
report_identifier: Optional[str] = None,
|
||||
report_id: Optional[int] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_list."""
|
||||
|
||||
process_instance_report = ProcessInstanceReportService.report_with_identifier(
|
||||
g.user, report_identifier
|
||||
g.user, report_id, report_identifier
|
||||
)
|
||||
|
||||
if user_filter:
|
||||
|
@ -960,11 +962,9 @@ def process_instance_list(
|
|||
results = ProcessInstanceReportService.add_metadata_columns_to_process_instance(
|
||||
process_instances.items, process_instance_report.report_metadata["columns"]
|
||||
)
|
||||
report_metadata = process_instance_report.report_metadata
|
||||
|
||||
response_json = {
|
||||
"report_identifier": process_instance_report.identifier,
|
||||
"report_metadata": report_metadata,
|
||||
"report": process_instance_report,
|
||||
"results": results,
|
||||
"filters": report_filter.to_dict(),
|
||||
"pagination": {
|
||||
|
@ -982,7 +982,8 @@ def process_instance_report_column_list() -> flask.wrappers.Response:
|
|||
table_columns = ProcessInstanceReportService.builtin_column_options()
|
||||
columns_for_metadata = db.session.query(ProcessInstanceMetadataModel.key).distinct().all() # type: ignore
|
||||
columns_for_metadata_strings = [
|
||||
{"Header": i[0], "accessor": i[0], "filterable": True} for i in columns_for_metadata
|
||||
{"Header": i[0], "accessor": i[0], "filterable": True}
|
||||
for i in columns_for_metadata
|
||||
]
|
||||
return make_response(jsonify(table_columns + columns_for_metadata_strings), 200)
|
||||
|
||||
|
@ -1043,22 +1044,22 @@ def process_instance_report_list(
|
|||
|
||||
def process_instance_report_create(body: Dict[str, Any]) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
ProcessInstanceReportModel.create_report(
|
||||
process_instance_report = ProcessInstanceReportModel.create_report(
|
||||
identifier=body["identifier"],
|
||||
user=g.user,
|
||||
report_metadata=body["report_metadata"],
|
||||
)
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
return make_response(jsonify(process_instance_report), 201)
|
||||
|
||||
|
||||
def process_instance_report_update(
|
||||
report_identifier: str,
|
||||
report_id: int,
|
||||
body: Dict[str, Any],
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=report_identifier,
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
|
@ -1071,15 +1072,15 @@ def process_instance_report_update(
|
|||
process_instance_report.report_metadata = body["report_metadata"]
|
||||
db.session.commit()
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
return make_response(jsonify(process_instance_report), 201)
|
||||
|
||||
|
||||
def process_instance_report_delete(
|
||||
report_identifier: str,
|
||||
report_id: int,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=report_identifier,
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
|
@ -1098,8 +1099,6 @@ def process_instance_report_delete(
|
|||
def service_tasks_show() -> flask.wrappers.Response:
|
||||
"""Service_tasks_show."""
|
||||
available_connectors = ServiceTaskService.available_connectors()
|
||||
print(available_connectors)
|
||||
|
||||
return Response(
|
||||
json.dumps(available_connectors), status=200, mimetype="application/json"
|
||||
)
|
||||
|
@ -1133,10 +1132,11 @@ def authentication_callback(
|
|||
|
||||
|
||||
def process_instance_report_show(
|
||||
report_identifier: str,
|
||||
report_id: int,
|
||||
page: int = 1,
|
||||
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)
|
||||
ProcessInstanceModel.start_in_seconds.desc(), ProcessInstanceModel.id.desc() # type: ignore
|
||||
).paginate(
|
||||
|
@ -1144,7 +1144,7 @@ def process_instance_report_show(
|
|||
)
|
||||
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=report_identifier,
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
|
@ -1421,9 +1421,6 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response
|
|||
task.form_ui_schema = ui_form_contents
|
||||
|
||||
if task.properties and task.data and "instructionsForEndUser" in task.properties:
|
||||
print(
|
||||
f"task.properties['instructionsForEndUser']: {task.properties['instructionsForEndUser']}"
|
||||
)
|
||||
if task.properties["instructionsForEndUser"]:
|
||||
task.properties["instructionsForEndUser"] = render_jinja_template(
|
||||
task.properties["instructionsForEndUser"], task.data
|
||||
|
|
|
@ -29,6 +29,8 @@ class ProcessInstanceReportFilter:
|
|||
"""To_dict."""
|
||||
d = {}
|
||||
|
||||
print(f"dir(self): {dir(self)}")
|
||||
|
||||
if self.process_model_identifier is not None:
|
||||
d["process_model_identifier"] = self.process_model_identifier
|
||||
if self.start_from is not None:
|
||||
|
@ -60,12 +62,21 @@ class ProcessInstanceReportService:
|
|||
|
||||
@classmethod
|
||||
def report_with_identifier(
|
||||
cls, user: UserModel, report_identifier: Optional[str] = None
|
||||
cls,
|
||||
user: UserModel,
|
||||
report_id: Optional[int] = None,
|
||||
report_identifier: Optional[str] = None,
|
||||
) -> ProcessInstanceReportModel:
|
||||
"""Report_with_filter."""
|
||||
if report_id is not None:
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id, created_by_id=user.id
|
||||
).first()
|
||||
if process_instance_report is not None:
|
||||
return process_instance_report # type: ignore
|
||||
|
||||
if report_identifier is None:
|
||||
report_identifier = "default"
|
||||
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=report_identifier, created_by_id=user.id
|
||||
).first()
|
||||
|
@ -75,9 +86,7 @@ class ProcessInstanceReportService:
|
|||
|
||||
# TODO replace with system reports that are loaded on launch (or similar)
|
||||
temp_system_metadata_map = {
|
||||
"default": {
|
||||
"columns": cls.builtin_column_options()
|
||||
},
|
||||
"default": {"columns": cls.builtin_column_options()},
|
||||
"system_report_instances_initiated_by_me": {
|
||||
"columns": [
|
||||
{"Header": "id", "accessor": "id"},
|
||||
|
@ -113,6 +122,7 @@ class ProcessInstanceReportService:
|
|||
created_by_id=user.id,
|
||||
report_metadata=temp_system_metadata_map[report_identifier], # type: ignore
|
||||
)
|
||||
# db.session.add(pro
|
||||
|
||||
return process_instance_report # type: ignore
|
||||
|
||||
|
@ -246,7 +256,8 @@ class ProcessInstanceReportService:
|
|||
{"Header": "Id", "accessor": "id", "filterable": False},
|
||||
{
|
||||
"Header": "Process",
|
||||
"accessor": "process_model_display_name", "filterable": False,
|
||||
"accessor": "process_model_display_name",
|
||||
"filterable": False,
|
||||
},
|
||||
{"Header": "Start", "accessor": "start_in_seconds", "filterable": False},
|
||||
{"Header": "End", "accessor": "end_in_seconds", "filterable": False},
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
Stack,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import { ProcessModel } from '../interfaces';
|
||||
import { ProcessInstanceReport, ProcessModel } from '../interfaces';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
||||
type OwnProps = {
|
||||
|
@ -20,6 +20,8 @@ type OwnProps = {
|
|||
endFromSeconds: string | null;
|
||||
endToSeconds: string | null;
|
||||
buttonText?: string;
|
||||
buttonClassName?: string;
|
||||
processInstanceReportSelection?: ProcessInstanceReport | null;
|
||||
};
|
||||
|
||||
export default function ProcessInstanceListSaveAsReport({
|
||||
|
@ -27,25 +29,33 @@ export default function ProcessInstanceListSaveAsReport({
|
|||
columnArray,
|
||||
orderBy,
|
||||
processModelSelection,
|
||||
processInstanceReportSelection,
|
||||
processStatusSelection,
|
||||
startFromSeconds,
|
||||
startToSeconds,
|
||||
endFromSeconds,
|
||||
endToSeconds,
|
||||
buttonText = 'Save as Perspective',
|
||||
buttonClassName,
|
||||
}: OwnProps) {
|
||||
const [identifier, setIdentifier] = useState('');
|
||||
const [identifier, setIdentifier] = useState<string>(
|
||||
processInstanceReportSelection?.identifier || ''
|
||||
);
|
||||
|
||||
const hasIdentifier = () => {
|
||||
return identifier?.length > 0;
|
||||
};
|
||||
|
||||
const responseHandler = (result: any) => {
|
||||
if (result.ok === true) {
|
||||
onSuccess(identifier);
|
||||
if (result) {
|
||||
onSuccess(result);
|
||||
}
|
||||
};
|
||||
|
||||
const isEditMode = () => {
|
||||
return !!processInstanceReportSelection;
|
||||
};
|
||||
|
||||
const addProcessInstanceReport = (event: any) => {
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -94,10 +104,17 @@ export default function ProcessInstanceListSaveAsReport({
|
|||
});
|
||||
}
|
||||
|
||||
let path = `/process-instances/reports`;
|
||||
let httpMethod = 'POST';
|
||||
if (isEditMode() && processInstanceReportSelection) {
|
||||
httpMethod = 'PUT';
|
||||
path = `${path}/${processInstanceReportSelection.id}`;
|
||||
}
|
||||
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-instances/reports`,
|
||||
path,
|
||||
successCallback: responseHandler,
|
||||
httpMethod: 'POST',
|
||||
httpMethod,
|
||||
postBody: {
|
||||
identifier,
|
||||
report_metadata: {
|
||||
|
@ -109,19 +126,31 @@ export default function ProcessInstanceListSaveAsReport({
|
|||
});
|
||||
};
|
||||
|
||||
let textInputComponent = null;
|
||||
if (!isEditMode()) {
|
||||
textInputComponent = (
|
||||
<TextInput
|
||||
id="identifier"
|
||||
name="identifier"
|
||||
labelText="Identifier"
|
||||
className="no-wrap"
|
||||
inline
|
||||
value={identifier}
|
||||
onChange={(e: any) => setIdentifier(e.target.value)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Form onSubmit={addProcessInstanceReport}>
|
||||
<Stack gap={5} orientation="horizontal">
|
||||
<TextInput
|
||||
id="identifier"
|
||||
name="identifier"
|
||||
labelText="Identifier"
|
||||
className="no-wrap"
|
||||
inline
|
||||
value={identifier}
|
||||
onChange={(e: any) => setIdentifier(e.target.value)}
|
||||
/>
|
||||
<Button disabled={!hasIdentifier()} size="sm" type="submit">
|
||||
{textInputComponent}
|
||||
<Button
|
||||
disabled={!hasIdentifier()}
|
||||
size="sm"
|
||||
type="submit"
|
||||
className={buttonClassName}
|
||||
>
|
||||
{buttonText}
|
||||
</Button>
|
||||
</Stack>
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from 'react-router-dom';
|
||||
|
||||
// @ts-ignore
|
||||
import { Filter, Close, AddAlt, AddFilled } from '@carbon/icons-react';
|
||||
import { Filter, Close, AddAlt } from '@carbon/icons-react';
|
||||
import {
|
||||
Button,
|
||||
ButtonSet,
|
||||
|
@ -27,6 +27,7 @@ import {
|
|||
Modal,
|
||||
ComboBox,
|
||||
TextInput,
|
||||
FormLabel,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config';
|
||||
|
@ -93,7 +94,7 @@ export default function ProcessInstanceListTable({
|
|||
autoReload = false,
|
||||
}: OwnProps) {
|
||||
const params = useParams();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [processInstances, setProcessInstances] = useState([]);
|
||||
|
@ -175,16 +176,12 @@ export default function ProcessInstanceListTable({
|
|||
function setProcessInstancesFromResult(result: any) {
|
||||
const processInstancesFromApi = result.results;
|
||||
setProcessInstances(processInstancesFromApi);
|
||||
setReportMetadata(result.report_metadata);
|
||||
setPagination(result.pagination);
|
||||
setProcessInstanceFilters(result.filters);
|
||||
|
||||
// TODO: need to iron out this interaction some more
|
||||
if (result.report_identifier !== 'default') {
|
||||
setProcessInstanceReportSelection({
|
||||
id: result.report_identifier,
|
||||
display_name: result.report_identifier,
|
||||
});
|
||||
setReportMetadata(result.report.report_metadata);
|
||||
if (result.report.id) {
|
||||
setProcessInstanceReportSelection(result.report);
|
||||
}
|
||||
}
|
||||
function getProcessInstances() {
|
||||
|
@ -206,14 +203,10 @@ export default function ProcessInstanceListTable({
|
|||
queryParamString += `&user_filter=${userAppliedFilter}`;
|
||||
}
|
||||
|
||||
let reportIdentifierToUse: any = reportIdentifier;
|
||||
|
||||
if (!reportIdentifierToUse) {
|
||||
reportIdentifierToUse = searchParams.get('report_identifier');
|
||||
}
|
||||
|
||||
if (reportIdentifierToUse) {
|
||||
queryParamString += `&report_identifier=${reportIdentifierToUse}`;
|
||||
if (searchParams.get('report_id')) {
|
||||
queryParamString += `&report_id=${searchParams.get('report_id')}`;
|
||||
} else if (reportIdentifier) {
|
||||
queryParamString += `&report_identifier=${reportIdentifier}`;
|
||||
}
|
||||
|
||||
Object.keys(dateParametersToAlwaysFilterBy).forEach(
|
||||
|
@ -376,7 +369,7 @@ export default function ProcessInstanceListTable({
|
|||
title="Perspective Saved"
|
||||
subtitle={`as '${
|
||||
processInstanceReportSelection
|
||||
? processInstanceReportSelection.display_name
|
||||
? processInstanceReportSelection.identifier
|
||||
: ''
|
||||
}'`}
|
||||
kind="success"
|
||||
|
@ -498,7 +491,7 @@ export default function ProcessInstanceListTable({
|
|||
}
|
||||
|
||||
if (processInstanceReportSelection) {
|
||||
queryParamString += `&report_identifier=${processInstanceReportSelection.id}`;
|
||||
queryParamString += `&report_id=${processInstanceReportSelection.id}`;
|
||||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
|
@ -595,18 +588,17 @@ export default function ProcessInstanceListTable({
|
|||
savedReport: boolean = false
|
||||
) => {
|
||||
clearFilters();
|
||||
|
||||
const selectedReport = selection.selectedItem;
|
||||
setProcessInstanceReportSelection(selectedReport);
|
||||
|
||||
let queryParamString = '';
|
||||
if (selectedReport) {
|
||||
queryParamString = `&report_identifier=${selectedReport.id}`;
|
||||
queryParamString = `?report_id=${selectedReport.id}`;
|
||||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
setProcessInstanceReportJustSaved(savedReport);
|
||||
navigate(`/admin/process-instances?${queryParamString}`);
|
||||
navigate(`/admin/process-instances${queryParamString}`);
|
||||
};
|
||||
|
||||
const reportColumns = () => {
|
||||
|
@ -619,16 +611,17 @@ export default function ProcessInstanceListTable({
|
|||
});
|
||||
};
|
||||
|
||||
// TODO onSuccess reload/select the new report in the report search
|
||||
const onSaveReportSuccess = (result: any) => {
|
||||
processInstanceReportDidChange(
|
||||
{
|
||||
selectedItem: result,
|
||||
},
|
||||
true
|
||||
);
|
||||
};
|
||||
|
||||
const saveAsReportComponent = () => {
|
||||
// TODO onSuccess reload/select the new report in the report search
|
||||
const callback = (identifier: string) => {
|
||||
processInstanceReportDidChange(
|
||||
{
|
||||
selectedItem: { id: identifier, display_name: identifier },
|
||||
},
|
||||
true
|
||||
);
|
||||
};
|
||||
const {
|
||||
valid,
|
||||
startFromSeconds,
|
||||
|
@ -642,9 +635,10 @@ export default function ProcessInstanceListTable({
|
|||
}
|
||||
return (
|
||||
<ProcessInstanceListSaveAsReport
|
||||
onSuccess={callback}
|
||||
onSuccess={onSaveReportSuccess}
|
||||
columnArray={reportColumns()}
|
||||
orderBy=""
|
||||
buttonText="Save As New Perspective"
|
||||
processModelSelection={processModelSelection}
|
||||
processStatusSelection={processStatusSelection}
|
||||
startFromSeconds={startFromSeconds}
|
||||
|
@ -710,6 +704,16 @@ export default function ProcessInstanceListTable({
|
|||
);
|
||||
};
|
||||
|
||||
const setReportColumnConditionValue = (event: any) => {
|
||||
if (reportColumnToOperateOn) {
|
||||
const reportColumnToOperateOnCopy = {
|
||||
...reportColumnToOperateOn,
|
||||
};
|
||||
reportColumnToOperateOnCopy.condition_value = event.target.value;
|
||||
setReportColumnToOperateOn(reportColumnToOperateOnCopy);
|
||||
}
|
||||
};
|
||||
|
||||
const reportColumnForm = () => {
|
||||
if (reportColumnFormMode === '') {
|
||||
return null;
|
||||
|
@ -732,6 +736,22 @@ export default function ProcessInstanceListTable({
|
|||
}}
|
||||
/>,
|
||||
];
|
||||
if (reportColumnToOperateOn && reportColumnToOperateOn.filterable) {
|
||||
console.log('reportColumnToOperateOn', reportColumnToOperateOn);
|
||||
formElements.push(
|
||||
<TextInput
|
||||
id="report-column-condition-value"
|
||||
name="report-column-condition-value"
|
||||
labelText="Condition Value"
|
||||
value={
|
||||
reportColumnToOperateOn
|
||||
? reportColumnToOperateOn.condition_value
|
||||
: ''
|
||||
}
|
||||
onChange={setReportColumnConditionValue}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (reportColumnFormMode === 'new') {
|
||||
formElements.push(
|
||||
<ComboBox
|
||||
|
@ -783,20 +803,24 @@ export default function ProcessInstanceListTable({
|
|||
if (reportColumn.filterable) {
|
||||
tagType = 'green';
|
||||
}
|
||||
let reportColumnLabel = reportColumn.Header;
|
||||
if (reportColumn.condition_value) {
|
||||
reportColumnLabel = `${reportColumnLabel}=${reportColumn.condition_value}`;
|
||||
}
|
||||
tags.push(
|
||||
<Tag type={tagType} size="sm" title={reportColumn.accessor}>
|
||||
<Tag type={tagType} size="sm">
|
||||
<Button
|
||||
kind="ghost"
|
||||
size="sm"
|
||||
className="button-tag-icon"
|
||||
title="Edit Header"
|
||||
title={`Edit ${reportColumn.accessor}`}
|
||||
onClick={() => {
|
||||
setReportColumnToOperateOn(reportColumn);
|
||||
setShowReportColumnForm(true);
|
||||
setReportColumnFormMode('edit');
|
||||
}}
|
||||
>
|
||||
{reportColumn.Header}
|
||||
{reportColumnLabel}
|
||||
</Button>
|
||||
<Button
|
||||
data-qa="remove-report-column"
|
||||
|
@ -841,6 +865,8 @@ export default function ProcessInstanceListTable({
|
|||
<>
|
||||
<Grid fullWidth className="with-bottom-margin">
|
||||
<Column md={8} lg={16} sm={4}>
|
||||
<FormLabel>Columns</FormLabel>
|
||||
<br />
|
||||
{columnSelections()}
|
||||
</Column>
|
||||
</Grid>
|
||||
|
@ -1043,11 +1069,40 @@ export default function ProcessInstanceListTable({
|
|||
|
||||
const reportSearchComponent = () => {
|
||||
if (showReports) {
|
||||
const { startFromSeconds, startToSeconds, endFromSeconds, endToSeconds } =
|
||||
calculateStartAndEndSeconds();
|
||||
const columns = [
|
||||
<Column sm={2} md={4} lg={7}>
|
||||
<ProcessInstanceReportSearch
|
||||
onChange={processInstanceReportDidChange}
|
||||
selectedItem={processInstanceReportSelection}
|
||||
/>
|
||||
</Column>,
|
||||
];
|
||||
if (processInstanceReportSelection && showFilterOptions) {
|
||||
columns.push(
|
||||
<Column sm={2} md={4} lg={2}>
|
||||
<ProcessInstanceListSaveAsReport
|
||||
buttonClassName="with-tiny-top-margin"
|
||||
onSuccess={onSaveReportSuccess}
|
||||
columnArray={reportColumns()}
|
||||
orderBy=""
|
||||
buttonText="Save"
|
||||
processModelSelection={processModelSelection}
|
||||
processStatusSelection={processStatusSelection}
|
||||
startFromSeconds={startFromSeconds}
|
||||
startToSeconds={startToSeconds}
|
||||
endFromSeconds={endFromSeconds}
|
||||
endToSeconds={endToSeconds}
|
||||
processInstanceReportSelection={processInstanceReportSelection}
|
||||
/>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<ProcessInstanceReportSearch
|
||||
onChange={processInstanceReportDidChange}
|
||||
selectedItem={processInstanceReportSelection}
|
||||
/>
|
||||
<Grid className="with-tiny-bottom-margin" fullWidth>
|
||||
{columns}
|
||||
</Grid>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import {
|
||||
ComboBox,
|
||||
Stack,
|
||||
FormLabel,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import { truncateString } from '../helpers';
|
||||
|
@ -22,52 +24,59 @@ export default function ProcessInstanceReportSearch({
|
|||
ProcessInstanceReport[] | null
|
||||
>(null);
|
||||
|
||||
function setProcessInstanceReportsFromResult(result: any) {
|
||||
const processInstanceReportsFromApi = result.map((item: any) => {
|
||||
return { id: item.identifier, display_name: item.identifier };
|
||||
});
|
||||
setProcessInstanceReports(processInstanceReportsFromApi);
|
||||
}
|
||||
useEffect(() => {
|
||||
function setProcessInstanceReportsFromResult(
|
||||
result: ProcessInstanceReport[]
|
||||
) {
|
||||
setProcessInstanceReports(result);
|
||||
}
|
||||
|
||||
if (processInstanceReports === null) {
|
||||
setProcessInstanceReports([]);
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-instances/reports`,
|
||||
successCallback: setProcessInstanceReportsFromResult,
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const reportSelectionString = (
|
||||
processInstanceReport: ProcessInstanceReport
|
||||
) => {
|
||||
return `${truncateString(processInstanceReport.identifier, 20)} (${
|
||||
processInstanceReport.id
|
||||
})`;
|
||||
};
|
||||
|
||||
const shouldFilterProcessInstanceReport = (options: any) => {
|
||||
const processInstanceReport: ProcessInstanceReport = options.item;
|
||||
const { inputValue } = options;
|
||||
return `${processInstanceReport.id} (${processInstanceReport.display_name})`.includes(
|
||||
inputValue
|
||||
);
|
||||
return reportSelectionString(processInstanceReport).includes(inputValue);
|
||||
};
|
||||
|
||||
const reportsAvailable = () => {
|
||||
return processInstanceReports && processInstanceReports.length > 0;
|
||||
};
|
||||
|
||||
return reportsAvailable() ? (
|
||||
<ComboBox
|
||||
onChange={onChange}
|
||||
id="process-instance-report-select"
|
||||
data-qa="process-instance-report-selection"
|
||||
items={processInstanceReports}
|
||||
itemToString={(processInstanceReport: ProcessInstanceReport) => {
|
||||
if (processInstanceReport) {
|
||||
return `${processInstanceReport.id} (${truncateString(
|
||||
processInstanceReport.display_name,
|
||||
20
|
||||
)})`;
|
||||
}
|
||||
return null;
|
||||
}}
|
||||
shouldFilterItem={shouldFilterProcessInstanceReport}
|
||||
placeholder="Choose a process instance perspective"
|
||||
titleText={titleText}
|
||||
selectedItem={selectedItem}
|
||||
/>
|
||||
) : null;
|
||||
if (reportsAvailable()) {
|
||||
return (
|
||||
<Stack orientation="horizontal" gap={2}>
|
||||
<FormLabel className="with-top-margin">{titleText}</FormLabel>
|
||||
<ComboBox
|
||||
onChange={onChange}
|
||||
id="process-instance-report-select"
|
||||
data-qa="process-instance-report-selection"
|
||||
items={processInstanceReports}
|
||||
itemToString={(processInstanceReport: ProcessInstanceReport) => {
|
||||
if (processInstanceReport) {
|
||||
return reportSelectionString(processInstanceReport);
|
||||
}
|
||||
return null;
|
||||
}}
|
||||
shouldFilterItem={shouldFilterProcessInstanceReport}
|
||||
placeholder="Choose a process instance perspective"
|
||||
selectedItem={selectedItem}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -177,6 +177,10 @@ h1.with-icons {
|
|||
margin-bottom: 3em;
|
||||
}
|
||||
|
||||
.with-tiny-bottom-margin {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.diagram-viewer-canvas {
|
||||
border:1px solid #000000;
|
||||
height:70vh;
|
||||
|
|
|
@ -63,9 +63,22 @@ export interface MessageInstance {
|
|||
message_correlations?: MessageCorrelations;
|
||||
}
|
||||
|
||||
export interface ReportColumn {
|
||||
Header: string;
|
||||
accessor: string;
|
||||
filterable: boolean;
|
||||
condition_value?: string;
|
||||
}
|
||||
|
||||
export interface ReportMetadata {
|
||||
columns: ReportColumn[];
|
||||
}
|
||||
|
||||
export interface ProcessInstanceReport {
|
||||
id: string;
|
||||
display_name: string;
|
||||
id: number;
|
||||
identifier: string;
|
||||
name: string;
|
||||
report_metadata: ReportMetadata;
|
||||
}
|
||||
|
||||
export interface ProcessGroupLite {
|
||||
|
@ -152,9 +165,3 @@ export interface FormField {
|
|||
type: string;
|
||||
enum: string[];
|
||||
}
|
||||
|
||||
export interface ReportColumn {
|
||||
Header: string;
|
||||
accessor: string;
|
||||
filterable: boolean;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue