diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py index ed02134c..9f849bd8 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/routes/process_instances_controller.py @@ -231,6 +231,7 @@ def process_instance_list_for_me( page: int = 1, per_page: int = 100, ) -> flask.wrappers.Response: + ProcessInstanceReportService.add_or_update_filter(body['report_metadata']['filter_by'], {"field_name": 'with_relation_to_me', "field_value": True}) return process_instance_list( process_model_identifier=process_model_identifier, page=page, diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py index dee7ea09..fa342cb5 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_report_service.py @@ -330,6 +330,17 @@ class ProcessInstanceReportService: if value is not None: yield value + @classmethod + def add_or_update_filter(cls, filters: list[FilterValue], new_filter: FilterValue) -> None: + filter_found = False + for filter in filters: + if filter["field_name"] == new_filter['field_name']: + filter['field_value'] = new_filter['field_value'] + filter_found = True + if filter_found is False: + filters.append(new_filter) + + @classmethod def run_process_instance_report( cls, @@ -374,7 +385,8 @@ class ProcessInstanceReportService: for value in cls.check_filter_value(filters, "initiated_by_me"): if value is True: - process_instance_query = process_instance_query.filter_by(process_initiator=user) + # process_instance_query = process_instance_query.filter_by(process_initiator=user) + cls.add_or_update_filter(filters, {'field_name': 'process_initiator_username', 'field_value': user.username}) for value in cls.check_filter_value(filters, "has_terminal_status"): if value is True: @@ -385,11 +397,12 @@ class ProcessInstanceReportService: process_instance_query = process_instance_query.filter( ProcessInstanceModel.status.not_in(ProcessInstanceModel.terminal_statuses()) # type: ignore ) - for value in cls.check_filter_value(filters, "has_active_status"): - if value is True: - process_instance_query = process_instance_query.filter( - ProcessInstanceModel.status.in_(ProcessInstanceModel.active_statuses()) # type: ignore - ) + + has_active_status = cls.get_filter_value(filters, "has_active_status") + if has_active_status: + process_instance_query = process_instance_query.filter( + ProcessInstanceModel.status.in_(ProcessInstanceModel.active_statuses()) # type: ignore + ) for value in cls.check_filter_value(filters, "process_initiator_username"): initiator = UserModel.query.filter_by(username=value).first() @@ -402,8 +415,6 @@ class ProcessInstanceReportService: with_tasks_assigned_to_my_group = cls.get_filter_value(filters, "with_tasks_assigned_to_my_group") with_tasks_i_can_complete = cls.get_filter_value(filters, "with_tasks_i_can_complete") with_relation_to_me = cls.get_filter_value(filters, "with_relation_to_me") - has_active_status = cls.get_filter_value(filters, "has_active_status") - user_group_identifier = cls.get_filter_value(filters, "user_group_identifier") if ( not with_tasks_completed_by_me and not with_tasks_assigned_to_my_group @@ -436,6 +447,8 @@ class ProcessInstanceReportService: ), ) + # this excludes some tasks you can complete, because that's the way the requirements were described. + # if it's assigned to one of your groups, it does not get returned by this query. if with_tasks_i_can_complete is True: process_instance_query = process_instance_query.filter( ProcessInstanceModel.process_initiator_id != user.id @@ -445,17 +458,15 @@ class ProcessInstanceReportService: and_( HumanTaskModel.process_instance_id == ProcessInstanceModel.id, HumanTaskModel.lane_assignment_id.is_(None), # type: ignore + HumanTaskModel.completed.is_(False) # type: ignore ), ).join( HumanTaskUserModel, and_(HumanTaskUserModel.human_task_id == HumanTaskModel.id, HumanTaskUserModel.user_id == user.id), ) - if has_active_status: - process_instance_query = process_instance_query.filter( - HumanTaskModel.completed.is_(False) # type: ignore - ) if with_tasks_assigned_to_my_group is True: + user_group_identifier = cls.get_filter_value(filters, "user_group_identifier") group_model_join_conditions = [GroupModel.id == HumanTaskModel.lane_assignment_id] if user_group_identifier: group_model_join_conditions.append(GroupModel.identifier == user_group_identifier) @@ -528,10 +539,10 @@ class ProcessInstanceReportService: for value in cls.check_filter_value(filters, "oldest_open_human_task_fields"): results = cls.add_human_task_fields(results, value.split(",")) + report_metadata['filter_by'] = filters response_json = { "report_metadata": report_metadata, "results": results, - "filters": filters, "pagination": { "count": len(results), "total": process_instances.total, diff --git a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx index 4430a500..942d7ed8 100644 --- a/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx +++ b/spiffworkflow-frontend/src/components/ProcessInstanceListTable.tsx @@ -1,5 +1,10 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { useNavigate, useParams, useSearchParams } from 'react-router-dom'; +import { + Link, + useNavigate, + useParams, + useSearchParams, +} from 'react-router-dom'; // @ts-ignore import { Close, AddAlt } from '@carbon/icons-react'; @@ -91,6 +96,7 @@ type OwnProps = { variant?: string; canCompleteAllTasks?: boolean; showActionsColumn?: boolean; + showLinkToReport?: boolean; }; interface dateParameters { @@ -111,6 +117,7 @@ export default function ProcessInstanceListTable({ variant = 'for-me', canCompleteAllTasks = false, showActionsColumn = false, + showLinkToReport = false, }: OwnProps) { let processInstanceApiSearchPath = '/process-instances/for-me'; if (variant === 'all') { @@ -200,6 +207,8 @@ export default function ProcessInstanceListTable({ string | null >(null); + const [reportHash, setReportHash] = useState(null); + const [ processInitiatorNotFoundErrorText, setProcessInitiatorNotFoundErrorText, @@ -280,6 +289,9 @@ export default function ProcessInstanceListTable({ setPagination(result.pagination); setReportMetadata(result.report_metadata); + if (result.report_hash) { + setReportHash(result.report_hash); + } }, []); const setProcessInstancesFromApplyFilter = (result: any) => { @@ -1550,6 +1562,15 @@ export default function ProcessInstanceListTable({ return null; }; + const linkToReport = () => { + if (!showLinkToReport) { + return null; + } + return ( + Hey + ); + }; + let resultsTable = null; if (pagination && (!textToShowIfEmpty || pagination.total > 0)) { // eslint-disable-next-line prefer-const @@ -1598,6 +1619,7 @@ export default function ProcessInstanceListTable({ <> {reportColumnForm()} {processInstanceReportSaveTag()} + {linkToReport()} ); @@ -67,9 +67,11 @@ export default function InProgressInstances() { showReports={false} textToShowIfEmpty="There are no open instances you started at this time." paginationClassName="with-large-bottom-margin" + showLinkToReport showActionsColumn - autoReload + autoReload={false} /> + {/*

{groupTableComponents()} + */} ); }