created process instance list and show pages to handle all and for-me w/ burnettk
This commit is contained in:
parent
389c919d99
commit
eb98086cb6
|
@ -509,6 +509,119 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/OkTrue"
|
||||
|
||||
/process-instances/for-me:
|
||||
parameters:
|
||||
- name: process_model_identifier
|
||||
in: query
|
||||
required: false
|
||||
description: The unique id of an existing process model.
|
||||
schema:
|
||||
type: string
|
||||
- name: page
|
||||
in: query
|
||||
required: false
|
||||
description: The page number to return. Defaults to page 1.
|
||||
schema:
|
||||
type: integer
|
||||
- name: per_page
|
||||
in: query
|
||||
required: false
|
||||
description: The page number to return. Defaults to page 1.
|
||||
schema:
|
||||
type: integer
|
||||
- name: start_from
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - beginning of start window - in seconds since epoch
|
||||
schema:
|
||||
type: integer
|
||||
- name: start_to
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - end of start window - in seconds since epoch
|
||||
schema:
|
||||
type: integer
|
||||
- name: end_from
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - beginning of end window - in seconds since epoch
|
||||
schema:
|
||||
type: integer
|
||||
- name: end_to
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - end of end window - in seconds since epoch
|
||||
schema:
|
||||
type: integer
|
||||
- name: process_status
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - not_started, user_input_required, waiting, complete, error, or suspended
|
||||
schema:
|
||||
type: string
|
||||
- name: initiated_by_me
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - show instances initiated by me
|
||||
schema:
|
||||
type: boolean
|
||||
- name: with_tasks_completed_by_me
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - show instances with tasks completed by me
|
||||
schema:
|
||||
type: boolean
|
||||
- name: with_tasks_completed_by_my_group
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - show instances with tasks completed by my group
|
||||
schema:
|
||||
type: boolean
|
||||
- name: with_relation_to_me
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - show instances that have something to do with me
|
||||
schema:
|
||||
type: boolean
|
||||
- name: user_filter
|
||||
in: query
|
||||
required: false
|
||||
description: For filtering - indicates the user has manually entered a query
|
||||
schema:
|
||||
type: boolean
|
||||
- name: report_identifier
|
||||
in: query
|
||||
required: false
|
||||
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
|
||||
- name: group_identifier
|
||||
in: query
|
||||
required: false
|
||||
description: The identifier of the group to get the process instances for
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list_for_me
|
||||
summary: Returns a list of process instances that are associated with me.
|
||||
tags:
|
||||
- Process Instances
|
||||
responses:
|
||||
"200":
|
||||
description: Workflow.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
|
||||
/process-instances:
|
||||
parameters:
|
||||
- name: process_model_identifier
|
||||
|
@ -609,7 +722,7 @@ paths:
|
|||
type: string
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list
|
||||
summary: Returns a list of process instances for a given process model
|
||||
summary: Returns a list of process instances.
|
||||
tags:
|
||||
- Process Instances
|
||||
responses:
|
||||
|
@ -732,6 +845,39 @@ paths:
|
|||
items:
|
||||
$ref: "#/components/schemas/Task"
|
||||
|
||||
/process-instances/for-me/{modified_process_model_identifier}/{process_instance_id}:
|
||||
parameters:
|
||||
- name: modified_process_model_identifier
|
||||
in: path
|
||||
required: true
|
||||
description: The unique id of an existing process model
|
||||
schema:
|
||||
type: string
|
||||
- name: process_instance_id
|
||||
in: path
|
||||
required: true
|
||||
description: The unique id of an existing process instance.
|
||||
schema:
|
||||
type: integer
|
||||
- name: process_identifier
|
||||
in: query
|
||||
required: false
|
||||
description: The identifier of the process to use for the diagram. Useful for displaying the diagram for a call activity.
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_show_for_me
|
||||
summary: Show information about a process instance that is associated with me
|
||||
responses:
|
||||
"200":
|
||||
description: One Process Instance
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
|
||||
/process-instances/{modified_process_model_identifier}/{process_instance_id}:
|
||||
parameters:
|
||||
- name: modified_process_model_identifier
|
||||
|
|
|
@ -115,11 +115,11 @@ permissions:
|
|||
users: []
|
||||
allowed_permissions: [read]
|
||||
uri: /v1.0/process-models/*
|
||||
read-all-process-instance:
|
||||
read-all-process-instance-for-me:
|
||||
groups: [everybody]
|
||||
users: []
|
||||
allowed_permissions: [read]
|
||||
uri: /v1.0/process-instances/*
|
||||
uri: /v1.0/process-instances/for-me/*
|
||||
read-process-instance-reports:
|
||||
groups: [everybody]
|
||||
users: []
|
||||
|
|
|
@ -848,6 +848,37 @@ def message_start(
|
|||
)
|
||||
|
||||
|
||||
def process_instance_list_for_me(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
start_from: Optional[int] = None,
|
||||
start_to: Optional[int] = None,
|
||||
end_from: Optional[int] = None,
|
||||
end_to: Optional[int] = None,
|
||||
process_status: Optional[str] = None,
|
||||
user_filter: Optional[bool] = False,
|
||||
report_identifier: Optional[str] = None,
|
||||
report_id: Optional[int] = None,
|
||||
group_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
return process_instance_list(
|
||||
process_model_identifier=process_model_identifier,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
process_status=process_status,
|
||||
user_filter=user_filter,
|
||||
report_identifier=report_identifier,
|
||||
report_id=report_id,
|
||||
group_identifier=group_identifier,
|
||||
with_relation_to_me=True,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_list(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
|
@ -951,7 +982,6 @@ def process_instance_list(
|
|||
ProcessInstanceModel.status.in_(report_filter.process_status) # type: ignore
|
||||
)
|
||||
|
||||
print(f"report_filter.with_relation_to_me: {report_filter.with_relation_to_me}")
|
||||
if report_filter.with_relation_to_me is True:
|
||||
process_instance_query = process_instance_query.outerjoin(
|
||||
ActiveTaskModel
|
||||
|
@ -1143,14 +1173,53 @@ def process_instance_report_column_list() -> flask.wrappers.Response:
|
|||
return make_response(jsonify(table_columns + columns_for_metadata_strings), 200)
|
||||
|
||||
|
||||
def process_instance_show_for_me(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
process_instance = ProcessInstanceModel.query.filter_by(id=process_instance_id).outerjoin(
|
||||
ActiveTaskModel
|
||||
).outerjoin(
|
||||
ActiveTaskUserModel,
|
||||
and_(
|
||||
ActiveTaskModel.id == ActiveTaskUserModel.active_task_id,
|
||||
ActiveTaskUserModel.user_id == g.user.id,
|
||||
),
|
||||
).filter(
|
||||
or_(
|
||||
ActiveTaskUserModel.id.is_not(None),
|
||||
ProcessInstanceModel.process_initiator_id == g.user.id,
|
||||
)
|
||||
).first()
|
||||
|
||||
if process_instance is None:
|
||||
raise (
|
||||
ApiError(
|
||||
error_code="process_instance_cannot_be_found",
|
||||
message=f"Process instance with id {process_instance_id} cannot be found that is associated with you.",
|
||||
status_code=400,
|
||||
)
|
||||
)
|
||||
|
||||
return _get_process_instance(process_instance=process_instance, modified_process_model_identifier=modified_process_model_identifier, process_identifier=process_identifier)
|
||||
|
||||
|
||||
def process_instance_show(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return _get_process_instance(process_instance=process_instance, modified_process_model_identifier=modified_process_model_identifier, process_identifier=process_identifier)
|
||||
|
||||
def _get_process_instance(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance: ProcessInstanceModel,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
current_version_control_revision = GitService.get_current_revision()
|
||||
|
||||
process_model_with_diagram = None
|
||||
|
|
|
@ -70,6 +70,7 @@ const REFRESH_INTERVAL = 5;
|
|||
const REFRESH_TIMEOUT = 600;
|
||||
|
||||
type OwnProps = {
|
||||
apiPath?: string;
|
||||
filtersEnabled?: boolean;
|
||||
processModelFullIdentifier?: string;
|
||||
paginationQueryParamPrefix?: string;
|
||||
|
@ -80,6 +81,7 @@ type OwnProps = {
|
|||
paginationClassName?: string;
|
||||
autoReload?: boolean;
|
||||
additionalParams?: string;
|
||||
variant?: string;
|
||||
};
|
||||
|
||||
interface dateParameters {
|
||||
|
@ -87,6 +89,7 @@ interface dateParameters {
|
|||
}
|
||||
|
||||
export default function ProcessInstanceListTable({
|
||||
apiPath = '/process-instances',
|
||||
filtersEnabled = true,
|
||||
processModelFullIdentifier,
|
||||
paginationQueryParamPrefix,
|
||||
|
@ -97,6 +100,7 @@ export default function ProcessInstanceListTable({
|
|||
textToShowIfEmpty,
|
||||
paginationClassName,
|
||||
autoReload = false,
|
||||
variant = 'for-me',
|
||||
}: OwnProps) {
|
||||
const params = useParams();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
@ -126,6 +130,11 @@ export default function ProcessInstanceListTable({
|
|||
|
||||
const setErrorMessage = (useContext as any)(ErrorContext)[1];
|
||||
|
||||
const processInstancePathPrefix =
|
||||
variant === 'all'
|
||||
? '/admin/process-instances'
|
||||
: '/admin/process-instances/for-me';
|
||||
|
||||
const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>(
|
||||
[]
|
||||
);
|
||||
|
@ -260,7 +269,7 @@ export default function ProcessInstanceListTable({
|
|||
}
|
||||
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-instances?${queryParamString}`,
|
||||
path: `${apiPath}?${queryParamString}`,
|
||||
successCallback: setProcessInstancesFromResult,
|
||||
});
|
||||
}
|
||||
|
@ -516,7 +525,7 @@ export default function ProcessInstanceListTable({
|
|||
|
||||
setErrorMessage(null);
|
||||
setProcessInstanceReportJustSaved(null);
|
||||
navigate(`/admin/process-instances?${queryParamString}`);
|
||||
navigate(`${processInstancePathPrefix}?${queryParamString}`);
|
||||
};
|
||||
|
||||
const dateComponent = (
|
||||
|
@ -615,7 +624,7 @@ export default function ProcessInstanceListTable({
|
|||
|
||||
setErrorMessage(null);
|
||||
setProcessInstanceReportJustSaved(mode || null);
|
||||
navigate(`/admin/process-instances${queryParamString}`);
|
||||
navigate(`${processInstancePathPrefix}${queryParamString}`);
|
||||
};
|
||||
|
||||
const reportColumns = () => {
|
||||
|
@ -1081,7 +1090,7 @@ export default function ProcessInstanceListTable({
|
|||
return (
|
||||
<Link
|
||||
data-qa="process-instance-show-link"
|
||||
to={`/admin/process-instances/${modifiedProcessModelId}/${id}`}
|
||||
to={`${processInstancePathPrefix}/${modifiedProcessModelId}/${id}`}
|
||||
title={`View process instance ${id}`}
|
||||
>
|
||||
{id}
|
||||
|
|
|
@ -9,16 +9,16 @@ export const useUriListForPermissions = () => {
|
|||
messageInstanceListPath: '/v1.0/messages',
|
||||
processGroupListPath: '/v1.0/process-groups',
|
||||
processGroupShowPath: `/v1.0/process-groups/${params.process_group_id}`,
|
||||
processInstanceCreatePath: `/v1.0/process-instances/${params.process_model_id}`,
|
||||
processInstanceActionPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceResumePath: `/v1.0/process-instance-resume/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceSuspendPath: `/v1.0/process-instance-suspend/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceTerminatePath: `/v1.0/process-instance-terminate/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceCreatePath: `/v1.0/process-instances/${params.process_model_id}`,
|
||||
processInstanceListPath: '/v1.0/process-instances',
|
||||
processInstanceLogListPath: `/v1.0/logs/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceReportListPath: '/v1.0/process-instances/reports',
|
||||
processInstanceTaskListPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}/task-info`,
|
||||
processInstanceResumePath: `/v1.0/process-instance-resume/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceSuspendPath: `/v1.0/process-instance-suspend/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceTaskListDataPath: `/v1.0/task-data/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processInstanceTaskListPath: `/v1.0/process-instances/${params.process_model_id}/${params.process_instance_id}/task-info`,
|
||||
processInstanceTerminatePath: `/v1.0/process-instance-terminate/${params.process_model_id}/${params.process_instance_id}`,
|
||||
processModelCreatePath: `/v1.0/process-models/${params.process_group_id}`,
|
||||
processModelFileCreatePath: `/v1.0/process-models/${params.process_model_id}/files`,
|
||||
processModelFileShowPath: `/v1.0/process-models/${params.process_model_id}/files/${params.file_name}`,
|
||||
|
|
|
@ -62,21 +62,25 @@ export default function AdminRoutes() {
|
|||
path="process-models/:process_model_id/files/:file_name"
|
||||
element={<ProcessModelEditDiagram />}
|
||||
/>
|
||||
<Route
|
||||
path="process-models/:process_model_id/process-instances"
|
||||
element={<ProcessInstanceList />}
|
||||
/>
|
||||
<Route
|
||||
path="process-models/:process_model_id/edit"
|
||||
element={<ProcessModelEdit />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/for-me/:process_model_id/:process_instance_id"
|
||||
element={<ProcessInstanceShow variant="for-me" />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/for-me/:process_model_id/:process_instance_id/:spiff_step"
|
||||
element={<ProcessInstanceShow variant="for-me" />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/:process_model_id/:process_instance_id"
|
||||
element={<ProcessInstanceShow />}
|
||||
element={<ProcessInstanceShow variant="all" />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/:process_model_id/:process_instance_id/:spiff_step"
|
||||
element={<ProcessInstanceShow />}
|
||||
element={<ProcessInstanceShow variant="all" />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/reports"
|
||||
|
@ -106,7 +110,18 @@ export default function AdminRoutes() {
|
|||
path="logs/:process_model_id/:process_instance_id"
|
||||
element={<ProcessInstanceLogList />}
|
||||
/>
|
||||
<Route path="process-instances" element={<ProcessInstanceList />} />
|
||||
<Route
|
||||
path="process-instances"
|
||||
element={<ProcessInstanceList variant="for-me" />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/for-me"
|
||||
element={<ProcessInstanceList variant="for-me" />}
|
||||
/>
|
||||
<Route
|
||||
path="process-instances/all"
|
||||
element={<ProcessInstanceList variant="all" />}
|
||||
/>
|
||||
<Route path="messages" element={<MessageInstanceList />} />
|
||||
<Route path="configuration/*" element={<Configuration />} />
|
||||
<Route
|
||||
|
|
|
@ -1,15 +1,33 @@
|
|||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import 'react-datepicker/dist/react-datepicker.css';
|
||||
|
||||
import 'react-bootstrap-typeahead/css/Typeahead.css';
|
||||
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
||||
// @ts-ignore
|
||||
import { Tabs, TabList, Tab } from '@carbon/react';
|
||||
import { Can } from '@casl/react';
|
||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||
import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
|
||||
import { getProcessModelFullIdentifierFromSearchParams } from '../helpers';
|
||||
import { useUriListForPermissions } from '../hooks/UriListForPermissions';
|
||||
import { PermissionsToCheck } from '../interfaces';
|
||||
import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||
|
||||
export default function ProcessInstanceList() {
|
||||
type OwnProps = {
|
||||
variant: string;
|
||||
};
|
||||
|
||||
export default function ProcessInstanceList({ variant }: OwnProps) {
|
||||
const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { targetUris } = useUriListForPermissions();
|
||||
const permissionRequestData: PermissionsToCheck = {
|
||||
[targetUris.processInstanceListPath]: ['GET'],
|
||||
};
|
||||
const { ability } = usePermissionFetcher(permissionRequestData);
|
||||
|
||||
const processInstanceBreadcrumbElement = () => {
|
||||
const processModelFullIdentifier =
|
||||
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
||||
|
@ -33,13 +51,46 @@ export default function ProcessInstanceList() {
|
|||
};
|
||||
|
||||
const processInstanceTitleElement = () => {
|
||||
return <h1>Process Instances</h1>;
|
||||
if (variant === 'all') {
|
||||
return <h1>All Process Instances</h1>;
|
||||
}
|
||||
return <h1>My Process Instances</h1>;
|
||||
};
|
||||
|
||||
let apiPath = '/process-instances/for-me';
|
||||
let selectedTabIndex = 0;
|
||||
if (variant === 'all') {
|
||||
apiPath = '/process-instances';
|
||||
selectedTabIndex = 1;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Tabs selectedIndex={selectedTabIndex}>
|
||||
<TabList aria-label="List of tabs">
|
||||
<Tab
|
||||
title="Only show process instances for the current user."
|
||||
onClick={() => {
|
||||
navigate('/admin/process-instances/for-me');
|
||||
}}
|
||||
>
|
||||
For Me
|
||||
</Tab>
|
||||
<Can I="GET" a={targetUris.processInstanceListPath} ability={ability}>
|
||||
<Tab
|
||||
title="Show all process instances for all users."
|
||||
onClick={() => {
|
||||
navigate('/admin/process-instances/all');
|
||||
}}
|
||||
>
|
||||
All
|
||||
</Tab>
|
||||
</Can>
|
||||
</TabList>
|
||||
</Tabs>
|
||||
<br />
|
||||
{processInstanceBreadcrumbElement()}
|
||||
{processInstanceTitleElement()}
|
||||
<ProcessInstanceListTable additionalParams="with_relation_to_me=true" />
|
||||
<ProcessInstanceListTable apiPath={apiPath} variant={variant} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,11 @@ import {
|
|||
import { usePermissionFetcher } from '../hooks/PermissionService';
|
||||
import ProcessInstanceClass from '../classes/ProcessInstanceClass';
|
||||
|
||||
export default function ProcessInstanceShow() {
|
||||
type OwnProps = {
|
||||
variant: string;
|
||||
};
|
||||
|
||||
export default function ProcessInstanceShow({ variant }: OwnProps) {
|
||||
const navigate = useNavigate();
|
||||
const params = useParams();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
@ -99,8 +103,12 @@ export default function ProcessInstanceShow() {
|
|||
if (processIdentifier) {
|
||||
queryParams = `?process_identifier=${processIdentifier}`;
|
||||
}
|
||||
let apiPath = '/process-instances/for-me';
|
||||
if (variant === 'all') {
|
||||
apiPath = '/process-instances';
|
||||
}
|
||||
HttpService.makeCallToBackend({
|
||||
path: `/process-instances/${modifiedProcessModelId}/${params.process_instance_id}${queryParams}`,
|
||||
path: `${apiPath}/${modifiedProcessModelId}/${params.process_instance_id}${queryParams}`,
|
||||
successCallback: setProcessInstance,
|
||||
});
|
||||
let taskParams = '?all_tasks=true';
|
||||
|
|
Loading…
Reference in New Issue