Allow switching between user defined reports (#56)
This commit is contained in:
parent
2f1329e046
commit
016d2b19e2
|
@ -71,37 +71,6 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
|
|||
created_at_in_seconds = db.Column(db.Integer)
|
||||
updated_at_in_seconds = db.Column(db.Integer)
|
||||
|
||||
@classmethod
|
||||
def default_report(cls, user: UserModel) -> ProcessInstanceReportModel:
|
||||
"""Default_report."""
|
||||
identifier = "default"
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=identifier, created_by_id=user.id
|
||||
).first()
|
||||
|
||||
# TODO replace with system report that is loaded on launch (or similar)
|
||||
if process_instance_report is None:
|
||||
report_metadata = {
|
||||
"columns": [
|
||||
{"Header": "id", "accessor": "id"},
|
||||
{
|
||||
"Header": "process_model_identifier",
|
||||
"accessor": "process_model_identifier",
|
||||
},
|
||||
{"Header": "start_in_seconds", "accessor": "start_in_seconds"},
|
||||
{"Header": "end_in_seconds", "accessor": "end_in_seconds"},
|
||||
{"Header": "status", "accessor": "status"},
|
||||
],
|
||||
}
|
||||
|
||||
process_instance_report = cls(
|
||||
identifier=identifier,
|
||||
created_by_id=user.id,
|
||||
report_metadata=report_metadata,
|
||||
)
|
||||
|
||||
return process_instance_report # type: ignore
|
||||
|
||||
@classmethod
|
||||
def add_fixtures(cls) -> None:
|
||||
"""Add_fixtures."""
|
||||
|
|
|
@ -846,6 +846,7 @@ def process_instance_list(
|
|||
report_metadata = process_instance_report.report_metadata
|
||||
|
||||
response_json = {
|
||||
"report_identifier": process_instance_report.identifier,
|
||||
"report_metadata": report_metadata,
|
||||
"results": results,
|
||||
"filters": report_filter.to_dict(),
|
||||
|
|
|
@ -48,10 +48,29 @@ class ProcessInstanceReportService:
|
|||
) -> ProcessInstanceReportModel:
|
||||
"""Report_with_filter."""
|
||||
if report_identifier is None:
|
||||
return ProcessInstanceReportModel.default_report(user)
|
||||
report_identifier = "default"
|
||||
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
identifier=report_identifier, created_by_id=user.id
|
||||
).first()
|
||||
|
||||
if process_instance_report is not None:
|
||||
return process_instance_report # type: ignore
|
||||
|
||||
# TODO replace with system reports that are loaded on launch (or similar)
|
||||
temp_system_metadata_map = {
|
||||
"default": {
|
||||
"columns": [
|
||||
{"Header": "id", "accessor": "id"},
|
||||
{
|
||||
"Header": "process_model_identifier",
|
||||
"accessor": "process_model_identifier",
|
||||
},
|
||||
{"Header": "start_in_seconds", "accessor": "start_in_seconds"},
|
||||
{"Header": "end_in_seconds", "accessor": "end_in_seconds"},
|
||||
{"Header": "status", "accessor": "status"},
|
||||
],
|
||||
},
|
||||
"system_report_instances_initiated_by_me": {
|
||||
"columns": [
|
||||
{
|
||||
|
@ -96,7 +115,7 @@ class ProcessInstanceReportService:
|
|||
report_metadata=temp_system_metadata_map[report_identifier],
|
||||
)
|
||||
|
||||
return process_instance_report
|
||||
return process_instance_report # type: ignore
|
||||
|
||||
@classmethod
|
||||
def filter_by_to_dict(
|
||||
|
|
|
@ -43,8 +43,13 @@ import HttpService from '../services/HttpService';
|
|||
|
||||
import 'react-bootstrap-typeahead/css/Typeahead.css';
|
||||
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
||||
import { PaginationObject, ProcessModel } from '../interfaces';
|
||||
import {
|
||||
PaginationObject,
|
||||
ProcessModel,
|
||||
ProcessInstanceReport,
|
||||
} from '../interfaces';
|
||||
import ProcessModelSearch from './ProcessModelSearch';
|
||||
import ProcessInstanceReportSearch from './ProcessInstanceReportSearch';
|
||||
|
||||
type OwnProps = {
|
||||
filtersEnabled?: boolean;
|
||||
|
@ -102,6 +107,8 @@ export default function ProcessInstanceListTable({
|
|||
>([]);
|
||||
const [processModelSelection, setProcessModelSelection] =
|
||||
useState<ProcessModel | null>(null);
|
||||
const [processInstanceReportSelection, setProcessInstanceReportSelection] =
|
||||
useState<ProcessInstanceReport | null>(null);
|
||||
|
||||
const dateParametersToAlwaysFilterBy: dateParameters = useMemo(() => {
|
||||
return {
|
||||
|
@ -136,6 +143,14 @@ export default function ProcessInstanceListTable({
|
|||
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,
|
||||
});
|
||||
}
|
||||
}
|
||||
function getProcessInstances() {
|
||||
// eslint-disable-next-line prefer-const
|
||||
|
@ -156,6 +171,11 @@ export default function ProcessInstanceListTable({
|
|||
queryParamString += `&user_filter=${userAppliedFilter}`;
|
||||
}
|
||||
|
||||
const reportIdentifier = searchParams.get('report_identifier');
|
||||
if (reportIdentifier) {
|
||||
queryParamString += `&report_identifier=${reportIdentifier}`;
|
||||
}
|
||||
|
||||
Object.keys(dateParametersToAlwaysFilterBy).forEach(
|
||||
(paramName: string) => {
|
||||
const dateFunctionToCall =
|
||||
|
@ -389,6 +409,10 @@ export default function ProcessInstanceListTable({
|
|||
queryParamString += `&process_model_identifier=${processModelSelection.id}`;
|
||||
}
|
||||
|
||||
if (processInstanceReportSelection) {
|
||||
queryParamString += `&report_identifier=${processInstanceReportSelection.id}`;
|
||||
}
|
||||
|
||||
setErrorMessage(null);
|
||||
navigate(`/admin/process-instances?${queryParamString}`);
|
||||
};
|
||||
|
@ -664,6 +688,29 @@ export default function ProcessInstanceListTable({
|
|||
setShowFilterOptions(!showFilterOptions);
|
||||
};
|
||||
|
||||
const processInstanceReportDidChange = (selection: any) => {
|
||||
clearFilters();
|
||||
|
||||
const selectedReport = selection.selectedItem;
|
||||
setProcessInstanceReportSelection(selectedReport);
|
||||
|
||||
const queryParamString = selectedReport
|
||||
? `&report_identifier=${selectedReport.id}`
|
||||
: '';
|
||||
|
||||
setErrorMessage(null);
|
||||
navigate(`/admin/process-instances?${queryParamString}`);
|
||||
};
|
||||
|
||||
const reportSearchComponent = () => {
|
||||
return (
|
||||
<ProcessInstanceReportSearch
|
||||
onChange={processInstanceReportDidChange}
|
||||
selectedItem={processInstanceReportSelection}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const filterComponent = () => {
|
||||
if (!filtersEnabled) {
|
||||
return null;
|
||||
|
@ -707,6 +754,7 @@ export default function ProcessInstanceListTable({
|
|||
return (
|
||||
<>
|
||||
{filterComponent()}
|
||||
{reportSearchComponent()}
|
||||
<PaginationForTable
|
||||
page={page}
|
||||
perPage={perPage}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
import { useState } from 'react';
|
||||
import {
|
||||
ComboBox,
|
||||
// @ts-ignore
|
||||
} from '@carbon/react';
|
||||
import { truncateString } from '../helpers';
|
||||
import { ProcessInstanceReport } from '../interfaces';
|
||||
import HttpService from '../services/HttpService';
|
||||
|
||||
type OwnProps = {
|
||||
onChange: (..._args: any[]) => any;
|
||||
selectedItem?: ProcessInstanceReport | null;
|
||||
titleText?: string;
|
||||
};
|
||||
|
||||
export default function ProcessInstanceReportSearch({
|
||||
selectedItem,
|
||||
onChange,
|
||||
titleText = 'Process instance perspectives',
|
||||
}: OwnProps) {
|
||||
const [processInstanceReports, setProcessInstanceReports] = useState<
|
||||
ProcessInstanceReport[] | null
|
||||
>(null);
|
||||
|
||||
function setProcessInstanceReportsFromResult(result: any) {
|
||||
const processInstanceReportsFromApi = result.map((item: any) => {
|
||||
return { id: item.identifier, display_name: item.identifier };
|
||||
});
|
||||
setProcessInstanceReports(processInstanceReportsFromApi);
|
||||
}
|
||||
|
||||
if (processInstanceReports === null) {
|
||||
setProcessInstanceReports([]);
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-instances/reports`,
|
||||
successCallback: setProcessInstanceReportsFromResult,
|
||||
});
|
||||
}
|
||||
|
||||
const shouldFilterProcessInstanceReport = (options: any) => {
|
||||
const processInstanceReport: ProcessInstanceReport = options.item;
|
||||
const { inputValue } = options;
|
||||
return `${processInstanceReport.id} (${processInstanceReport.display_name})`.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;
|
||||
}
|
|
@ -41,6 +41,11 @@ export interface ProcessInstance {
|
|||
process_model_identifier: string;
|
||||
}
|
||||
|
||||
export interface ProcessInstanceReport {
|
||||
id: string;
|
||||
display_name: string;
|
||||
}
|
||||
|
||||
export interface ProcessModel {
|
||||
id: string;
|
||||
description: string;
|
||||
|
|
Loading…
Reference in New Issue