Merge pull request #43 from sartography/send_filters
Send filters used in process_instance_list to the front end
This commit is contained in:
commit
1ec6a1922a
|
@ -439,6 +439,12 @@ paths:
|
||||||
description: For filtering - not_started, user_input_required, waiting, complete, error, or suspended
|
description: For filtering - not_started, user_input_required, waiting, complete, error, or suspended
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
- name: user_filter
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: For filtering - indicates the user has manually entered a query
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
# process_instance_list
|
# process_instance_list
|
||||||
get:
|
get:
|
||||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list
|
||||||
|
|
|
@ -72,6 +72,9 @@ from spiffworkflow_backend.services.message_service import MessageService
|
||||||
from spiffworkflow_backend.services.process_instance_processor import (
|
from spiffworkflow_backend.services.process_instance_processor import (
|
||||||
ProcessInstanceProcessor,
|
ProcessInstanceProcessor,
|
||||||
)
|
)
|
||||||
|
from spiffworkflow_backend.services.process_instance_report_service import (
|
||||||
|
ProcessInstanceReportFilter,
|
||||||
|
)
|
||||||
from spiffworkflow_backend.services.process_instance_report_service import (
|
from spiffworkflow_backend.services.process_instance_report_service import (
|
||||||
ProcessInstanceReportService,
|
ProcessInstanceReportService,
|
||||||
)
|
)
|
||||||
|
@ -732,10 +735,23 @@ def process_instance_list(
|
||||||
end_from: Optional[int] = None,
|
end_from: Optional[int] = None,
|
||||||
end_to: Optional[int] = None,
|
end_to: Optional[int] = None,
|
||||||
process_status: Optional[str] = None,
|
process_status: Optional[str] = None,
|
||||||
|
user_filter: Optional[bool] = False,
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
"""Process_instance_list."""
|
"""Process_instance_list."""
|
||||||
process_instance_report = ProcessInstanceReportModel.default_report(g.user)
|
process_instance_report = ProcessInstanceReportModel.default_report(g.user)
|
||||||
report_filter = ProcessInstanceReportService.filter_from_metadata_with_overrides(
|
|
||||||
|
if user_filter:
|
||||||
|
report_filter = ProcessInstanceReportFilter(
|
||||||
|
process_model_identifier,
|
||||||
|
start_from,
|
||||||
|
start_to,
|
||||||
|
end_from,
|
||||||
|
end_to,
|
||||||
|
process_status.split(",") if process_status else None,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
report_filter = (
|
||||||
|
ProcessInstanceReportService.filter_from_metadata_with_overrides(
|
||||||
process_instance_report,
|
process_instance_report,
|
||||||
process_model_identifier,
|
process_model_identifier,
|
||||||
start_from,
|
start_from,
|
||||||
|
@ -744,6 +760,7 @@ def process_instance_list(
|
||||||
end_to,
|
end_to,
|
||||||
process_status,
|
process_status,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# process_model_identifier = un_modify_modified_process_model_id(modified_process_model_identifier)
|
# process_model_identifier = un_modify_modified_process_model_id(modified_process_model_identifier)
|
||||||
process_instance_query = ProcessInstanceModel.query
|
process_instance_query = ProcessInstanceModel.query
|
||||||
|
@ -811,6 +828,7 @@ def process_instance_list(
|
||||||
response_json = {
|
response_json = {
|
||||||
"report_metadata": report_metadata,
|
"report_metadata": report_metadata,
|
||||||
"results": results,
|
"results": results,
|
||||||
|
"filters": report_filter.to_dict(),
|
||||||
"pagination": {
|
"pagination": {
|
||||||
"count": len(results),
|
"count": len(results),
|
||||||
"total": process_instances.total,
|
"total": process_instances.total,
|
||||||
|
|
|
@ -18,6 +18,25 @@ class ProcessInstanceReportFilter:
|
||||||
end_to: Optional[int] = None
|
end_to: Optional[int] = None
|
||||||
process_status: Optional[list[str]] = None
|
process_status: Optional[list[str]] = None
|
||||||
|
|
||||||
|
def to_dict(self) -> dict[str, str]:
|
||||||
|
"""To_dict."""
|
||||||
|
d = {}
|
||||||
|
|
||||||
|
if self.process_model_identifier is not None:
|
||||||
|
d["process_model_identifier"] = self.process_model_identifier
|
||||||
|
if self.start_from is not None:
|
||||||
|
d["start_from"] = str(self.start_from)
|
||||||
|
if self.start_to is not None:
|
||||||
|
d["start_to"] = str(self.start_to)
|
||||||
|
if self.end_from is not None:
|
||||||
|
d["end_from"] = str(self.end_from)
|
||||||
|
if self.end_to is not None:
|
||||||
|
d["end_to"] = str(self.end_to)
|
||||||
|
if self.process_status is not None:
|
||||||
|
d["process_status"] = ",".join(self.process_status)
|
||||||
|
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
class ProcessInstanceReportService:
|
class ProcessInstanceReportService:
|
||||||
"""ProcessInstanceReportService."""
|
"""ProcessInstanceReportService."""
|
||||||
|
|
|
@ -17,6 +17,80 @@ from spiffworkflow_backend.services.process_instance_report_service import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestProcessInstanceReportFilter(BaseTest):
|
||||||
|
"""TestProcessInstanceReportFilter."""
|
||||||
|
|
||||||
|
def test_empty_filter_to_dict(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Docstring."""
|
||||||
|
d = ProcessInstanceReportFilter().to_dict()
|
||||||
|
|
||||||
|
assert d == {}
|
||||||
|
|
||||||
|
def test_string_value_filter_to_dict(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Docstring."""
|
||||||
|
d = ProcessInstanceReportFilter(process_model_identifier="bob").to_dict()
|
||||||
|
|
||||||
|
assert d == {"process_model_identifier": "bob"}
|
||||||
|
|
||||||
|
def test_int_value_filter_to_dict(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Docstring."""
|
||||||
|
d = ProcessInstanceReportFilter(
|
||||||
|
start_from=1,
|
||||||
|
start_to=2,
|
||||||
|
end_from=3,
|
||||||
|
end_to=4,
|
||||||
|
).to_dict()
|
||||||
|
|
||||||
|
assert d == {
|
||||||
|
"start_from": "1",
|
||||||
|
"start_to": "2",
|
||||||
|
"end_from": "3",
|
||||||
|
"end_to": "4",
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_list_single_value_filter_to_dict(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Docstring."""
|
||||||
|
d = ProcessInstanceReportFilter(process_status=["bob"]).to_dict()
|
||||||
|
|
||||||
|
assert d == {"process_status": "bob"}
|
||||||
|
|
||||||
|
def test_list_multiple_value_filter_to_dict(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Docstring."""
|
||||||
|
d = ProcessInstanceReportFilter(process_status=["joe", "bob", "sue"]).to_dict()
|
||||||
|
|
||||||
|
assert d == {"process_status": "joe,bob,sue"}
|
||||||
|
|
||||||
|
|
||||||
class TestProcessInstanceReportService(BaseTest):
|
class TestProcessInstanceReportService(BaseTest):
|
||||||
"""TestProcessInstanceReportService."""
|
"""TestProcessInstanceReportService."""
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ export default function ProcessInstanceListTable({
|
||||||
const [processInstances, setProcessInstances] = useState([]);
|
const [processInstances, setProcessInstances] = useState([]);
|
||||||
const [reportMetadata, setReportMetadata] = useState({});
|
const [reportMetadata, setReportMetadata] = useState({});
|
||||||
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
||||||
|
const [processInstanceFilters, setProcessInstanceFilters] = useState({});
|
||||||
|
|
||||||
const oneHourInSeconds = 3600;
|
const oneHourInSeconds = 3600;
|
||||||
const oneMonthInSeconds = oneHourInSeconds * 24 * 30;
|
const oneMonthInSeconds = oneHourInSeconds * 24 * 30;
|
||||||
|
@ -108,6 +109,7 @@ export default function ProcessInstanceListTable({
|
||||||
setProcessInstances(processInstancesFromApi);
|
setProcessInstances(processInstancesFromApi);
|
||||||
setReportMetadata(result.report_metadata);
|
setReportMetadata(result.report_metadata);
|
||||||
setPagination(result.pagination);
|
setPagination(result.pagination);
|
||||||
|
setProcessInstanceFilters(result.filters);
|
||||||
}
|
}
|
||||||
function getProcessInstances() {
|
function getProcessInstances() {
|
||||||
// eslint-disable-next-line prefer-const
|
// eslint-disable-next-line prefer-const
|
||||||
|
@ -123,6 +125,11 @@ export default function ProcessInstanceListTable({
|
||||||
}
|
}
|
||||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
let queryParamString = `per_page=${perPage}&page=${page}`;
|
||||||
|
|
||||||
|
const userAppliedFilter = searchParams.get('user_filter');
|
||||||
|
if (userAppliedFilter) {
|
||||||
|
queryParamString += `&user_filter=${userAppliedFilter}`;
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => {
|
Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => {
|
||||||
// @ts-expect-error TS(7053) FIXME:
|
// @ts-expect-error TS(7053) FIXME:
|
||||||
const functionToCall = parametersToAlwaysFilterBy[paramName];
|
const functionToCall = parametersToAlwaysFilterBy[paramName];
|
||||||
|
@ -212,6 +219,45 @@ export default function ProcessInstanceListTable({
|
||||||
perPageOptions,
|
perPageOptions,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const filters = processInstanceFilters as any;
|
||||||
|
Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => {
|
||||||
|
// @ts-expect-error TS(7053) FIXME:
|
||||||
|
const functionToCall = parametersToAlwaysFilterBy[paramName];
|
||||||
|
const paramValue = filters[paramName];
|
||||||
|
functionToCall('');
|
||||||
|
if (paramValue) {
|
||||||
|
const dateString = convertSecondsToFormattedDate(paramValue as any);
|
||||||
|
functionToCall(dateString);
|
||||||
|
setShowFilterOptions(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setProcessModelSelection(null);
|
||||||
|
processModelAvailableItems.forEach((item: any) => {
|
||||||
|
if (item.id === filters.process_model_identifier) {
|
||||||
|
setProcessModelSelection(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const processStatusSelectedArray: string[] = [];
|
||||||
|
if (filters.process_status) {
|
||||||
|
PROCESS_STATUSES.forEach((processStatusOption: any) => {
|
||||||
|
const regex = new RegExp(`\\b${processStatusOption}\\b`);
|
||||||
|
if (filters.process_status.match(regex)) {
|
||||||
|
processStatusSelectedArray.push(processStatusOption);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setShowFilterOptions(true);
|
||||||
|
}
|
||||||
|
setProcessStatusSelection(processStatusSelectedArray);
|
||||||
|
}, [
|
||||||
|
processInstanceFilters,
|
||||||
|
parametersToAlwaysFilterBy,
|
||||||
|
parametersToGetFromSearchParams,
|
||||||
|
processModelAvailableItems,
|
||||||
|
]);
|
||||||
|
|
||||||
// does the comparison, but also returns false if either argument
|
// does the comparison, but also returns false if either argument
|
||||||
// is not truthy and therefore not comparable.
|
// is not truthy and therefore not comparable.
|
||||||
const isTrueComparison = (param1: any, operation: any, param2: any) => {
|
const isTrueComparison = (param1: any, operation: any, param2: any) => {
|
||||||
|
@ -237,7 +283,7 @@ export default function ProcessInstanceListTable({
|
||||||
undefined,
|
undefined,
|
||||||
paginationQueryParamPrefix
|
paginationQueryParamPrefix
|
||||||
);
|
);
|
||||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
let queryParamString = `per_page=${perPage}&page=${page}&user_filter=true`;
|
||||||
|
|
||||||
const startFromSeconds = convertDateStringToSeconds(startFrom);
|
const startFromSeconds = convertDateStringToSeconds(startFrom);
|
||||||
const endFromSeconds = convertDateStringToSeconds(endFrom);
|
const endFromSeconds = convertDateStringToSeconds(endFrom);
|
||||||
|
|
Loading…
Reference in New Issue