updated text on home page w/ burnettk

This commit is contained in:
jasquat 2023-04-13 16:36:46 -04:00
parent 700c2d9ef5
commit fd25bb64d7
7 changed files with 160 additions and 147 deletions

View File

@ -422,7 +422,7 @@ class ProcessInstanceReportService:
for process_instance_dict in process_instance_dicts: for process_instance_dict in process_instance_dicts:
assigned_user = aliased(UserModel) assigned_user = aliased(UserModel)
human_task_query = ( human_task_query = (
HumanTaskModel.query.filter_by(process_instance_id=process_instance_dict['id']) HumanTaskModel.query.filter_by(process_instance_id=process_instance_dict['id'], completed=False)
.group_by(HumanTaskModel.id) .group_by(HumanTaskModel.id)
.outerjoin( .outerjoin(
HumanTaskUserModel, HumanTaskUserModel,

View File

@ -1303,6 +1303,111 @@ export default function ProcessInstanceListTable({
); );
}; };
const getWaitingForTableCellComponent = (processInstanceTask: any) => {
let fullUsernameString = '';
let shortUsernameString = '';
if (processInstanceTask.potential_owner_usernames) {
fullUsernameString = processInstanceTask.potential_owner_usernames;
const usernames =
processInstanceTask.potential_owner_usernames.split(',');
const firstTwoUsernames = usernames.slice(0, 2);
if (usernames.length > 2) {
firstTwoUsernames.push('...');
}
shortUsernameString = firstTwoUsernames.join(',');
}
if (processInstanceTask.assigned_user_group_identifier) {
fullUsernameString = processInstanceTask.assigned_user_group_identifier;
shortUsernameString = processInstanceTask.assigned_user_group_identifier;
}
return <span title={fullUsernameString}>{shortUsernameString}</span>;
};
const formatProcessInstanceId = (row: ProcessInstance, id: number) => {
return <span data-qa="paginated-entity-id">{id}</span>;
};
const formatProcessModelIdentifier = (_row: any, identifier: any) => {
return <span>{identifier}</span>;
};
const formatProcessModelDisplayName = (_row: any, identifier: any) => {
return <span>{identifier}</span>;
};
const formatSecondsForDisplay = (_row: any, seconds: any) => {
return convertSecondsToFormattedDateTime(seconds) || '-';
};
const defaultFormatter = (_row: any, value: any) => {
return value;
};
const formattedColumn = (row: any, column: any) => {
const reportColumnFormatters: Record<string, any> = {
id: formatProcessInstanceId,
process_model_identifier: formatProcessModelIdentifier,
process_model_display_name: formatProcessModelDisplayName,
start_in_seconds: formatSecondsForDisplay,
end_in_seconds: formatSecondsForDisplay,
updated_at_in_seconds: formatSecondsForDisplay,
};
const formatter =
reportColumnFormatters[column.accessor] ?? defaultFormatter;
const value = row[column.accessor];
const modifiedModelId = modifyProcessIdentifierForPathParam(
row.process_model_identifier
);
const navigateToProcessInstance = () => {
navigate(`${processInstanceShowPathPrefix}/${modifiedModelId}/${row.id}`);
};
const navigateToProcessModel = () => {
navigate(`/admin/process-models/${modifiedModelId}`);
};
if (column.accessor === 'status') {
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<td
onClick={navigateToProcessInstance}
onKeyDown={navigateToProcessInstance}
data-qa={`process-instance-status-${value}`}
>
{formatter(row, value)}
</td>
);
}
if (column.accessor === 'process_model_display_name') {
const pmStyle = { background: 'rgba(0, 0, 0, .02)' };
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<td
style={pmStyle}
onClick={navigateToProcessModel}
onKeyDown={navigateToProcessModel}
>
{formatter(row, value)}
</td>
);
}
if (column.accessor === 'waiting_for') {
return <td>{getWaitingForTableCellComponent(row)}</td>;
}
if (column.accessor === 'updated_at_in_seconds') {
return (
<TableCellWithTimeAgoInWords
timeInSeconds={row.updated_at_in_seconds}
/>
);
}
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<td
data-qa={`process-instance-show-link-${column.accessor}`}
onKeyDown={navigateToProcessModel}
onClick={navigateToProcessInstance}
>
{formatter(row, value)}
</td>
);
};
const buildTable = () => { const buildTable = () => {
const headerLabels: Record<string, string> = { const headerLabels: Record<string, string> = {
id: 'Id', id: 'Id',
@ -1323,115 +1428,6 @@ export default function ProcessInstanceListTable({
headers.push('Actions'); headers.push('Actions');
} }
const formatProcessInstanceId = (row: ProcessInstance, id: number) => {
return <span data-qa="paginated-entity-id">{id}</span>;
};
const formatProcessModelIdentifier = (_row: any, identifier: any) => {
return <span>{identifier}</span>;
};
const formatProcessModelDisplayName = (_row: any, identifier: any) => {
return <span>{identifier}</span>;
};
const formatSecondsForDisplay = (_row: any, seconds: any) => {
return convertSecondsToFormattedDateTime(seconds) || '-';
};
const defaultFormatter = (_row: any, value: any) => {
return value;
};
const getWaitingForTableCellComponent = (processInstanceTask: any) => {
let fullUsernameString = '';
let shortUsernameString = '';
if (processInstanceTask.potential_owner_usernames) {
fullUsernameString = processInstanceTask.potential_owner_usernames;
const usernames =
processInstanceTask.potential_owner_usernames.split(',');
const firstTwoUsernames = usernames.slice(0, 2);
if (usernames.length > 2) {
firstTwoUsernames.push('...');
}
shortUsernameString = firstTwoUsernames.join(',');
}
if (processInstanceTask.assigned_user_group_identifier) {
fullUsernameString = processInstanceTask.assigned_user_group_identifier;
shortUsernameString =
processInstanceTask.assigned_user_group_identifier;
}
return <span title={fullUsernameString}>{shortUsernameString}</span>;
};
const reportColumnFormatters: Record<string, any> = {
id: formatProcessInstanceId,
process_model_identifier: formatProcessModelIdentifier,
process_model_display_name: formatProcessModelDisplayName,
start_in_seconds: formatSecondsForDisplay,
end_in_seconds: formatSecondsForDisplay,
updated_at_in_seconds: formatSecondsForDisplay,
};
const formattedColumn = (row: any, column: any) => {
const formatter =
reportColumnFormatters[column.accessor] ?? defaultFormatter;
const value = row[column.accessor];
const modifiedModelId = modifyProcessIdentifierForPathParam(
row.process_model_identifier
);
const navigateToProcessInstance = () => {
navigate(
`${processInstanceShowPathPrefix}/${modifiedModelId}/${row.id}`
);
};
const navigateToProcessModel = () => {
navigate(`/admin/process-models/${modifiedModelId}`);
};
if (column.accessor === 'status') {
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<td
onClick={navigateToProcessInstance}
onKeyDown={navigateToProcessInstance}
data-qa={`process-instance-status-${value}`}
>
{formatter(row, value)}
</td>
);
}
if (column.accessor === 'process_model_display_name') {
const pmStyle = { background: 'rgba(0, 0, 0, .02)' };
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<td
style={pmStyle}
onClick={navigateToProcessModel}
onKeyDown={navigateToProcessModel}
>
{formatter(row, value)}
</td>
);
}
if (column.accessor === 'waiting_for') {
return <td>{getWaitingForTableCellComponent(row)}</td>;
}
if (column.accessor === 'updated_at_in_seconds') {
return (
<TableCellWithTimeAgoInWords
timeInSeconds={row.updated_at_in_seconds}
/>
);
}
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<td
data-qa={`process-instance-show-link-${column.accessor}`}
onKeyDown={navigateToProcessModel}
onClick={navigateToProcessInstance}
>
{formatter(row, value)}
</td>
);
};
const rows = processInstances.map((row: any) => { const rows = processInstances.map((row: any) => {
const currentRow = reportColumns().map((column: any) => { const currentRow = reportColumns().map((column: any) => {
return formattedColumn(row, column); return formattedColumn(row, column);

View File

@ -332,10 +332,13 @@ td.actions-cell {
width: 1em; width: 1em;
} }
.process-instance-table-header {
margin-bottom: 1em;
}
.no-results-message { .no-results-message {
font-style: italic; font-style: italic;
margin-left: 2em; margin-left: 2em;
margin-top: 1em;
font-size: 14px; font-size: 14px;
} }

View File

@ -18,13 +18,12 @@ export default function CompletedInstances() {
} }
return userGroups.map((userGroup: string) => { return userGroups.map((userGroup: string) => {
const titleText = `This is a list of instances with tasks that were completed by the ${userGroup} group.`;
return ( return (
<> <>
<h2>With tasks completed by group: {userGroup}</h2> <h2 title={titleText} className="process-instance-table-header">
<p className="data-table-description"> With tasks completed by <strong>{userGroup}</strong>
This is a list of instances with tasks that were completed by the{' '} </h2>
{userGroup} group.
</p>
<ProcessInstanceListTable <ProcessInstanceListTable
filtersEnabled={false} filtersEnabled={false}
paginationQueryParamPrefix="group_completed_instances" paginationQueryParamPrefix="group_completed_instances"
@ -40,12 +39,19 @@ export default function CompletedInstances() {
}); });
}; };
const startedByMeTitleText =
'This is a list of instances you started that are now complete.';
const withTasksCompletedByMeTitleText =
'This is a list of instances where you have completed tasks.';
return ( return (
<> <>
<h2>My completed instances</h2> <h2
<p className="data-table-description"> title={startedByMeTitleText}
This is a list of instances you started that are now complete. className="process-instance-table-header"
</p> >
Started by me
</h2>
<ProcessInstanceListTable <ProcessInstanceListTable
filtersEnabled={false} filtersEnabled={false}
paginationQueryParamPrefix="my_completed_instances" paginationQueryParamPrefix="my_completed_instances"
@ -56,10 +62,12 @@ export default function CompletedInstances() {
paginationClassName="with-large-bottom-margin" paginationClassName="with-large-bottom-margin"
autoReload autoReload
/> />
<h2>With tasks completed by me</h2> <h2
<p className="data-table-description"> title={withTasksCompletedByMeTitleText}
This is a list of instances where you have completed tasks. className="process-instance-table-header"
</p> >
With tasks completed by me
</h2>
<ProcessInstanceListTable <ProcessInstanceListTable
filtersEnabled={false} filtersEnabled={false}
paginationQueryParamPrefix="my_completed_tasks" paginationQueryParamPrefix="my_completed_tasks"

View File

@ -4,7 +4,6 @@ import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import { Tabs, TabList, Tab } from '@carbon/react'; import { Tabs, TabList, Tab } from '@carbon/react';
import TaskShow from './TaskShow'; import TaskShow from './TaskShow';
import MyTasks from './MyTasks'; import MyTasks from './MyTasks';
import GroupedTasks from './GroupedTasks';
import CompletedInstances from './CompletedInstances'; import CompletedInstances from './CompletedInstances';
import CreateNewInstance from './CreateNewInstance'; import CreateNewInstance from './CreateNewInstance';
import InProgressInstances from './InProgressInstances'; import InProgressInstances from './InProgressInstances';

View File

@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import ProcessInstanceListTable from '../components/ProcessInstanceListTable'; import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
import { slugifyString } from '../helpers';
import HttpService from '../services/HttpService'; import HttpService from '../services/HttpService';
export default function InProgressInstances() { export default function InProgressInstances() {
@ -18,21 +19,22 @@ export default function InProgressInstances() {
} }
return userGroups.map((userGroup: string) => { return userGroups.map((userGroup: string) => {
const titleText = `This is a list of instances with tasks that are waiting for the ${userGroup} group.`;
return ( return (
<> <>
<h2>With tasks completed by group: {userGroup}</h2> <h2 title={titleText} className="process-instance-table-header">
<p className="data-table-description"> Waiting for <strong>{userGroup}</strong>
This is a list of instances with tasks that were completed by the{' '} </h2>
{userGroup} group.
</p>
<ProcessInstanceListTable <ProcessInstanceListTable
filtersEnabled={false} filtersEnabled={false}
paginationQueryParamPrefix="group_completed_instances" paginationQueryParamPrefix={`waiting_for_${slugifyString(
userGroup
).replace('-', '_')}`}
paginationClassName="with-large-bottom-margin" paginationClassName="with-large-bottom-margin"
perPageOptions={[2, 5, 25]} perPageOptions={[2, 5, 25]}
reportIdentifier="system_report_in_progress_instances_with_tasks_for_my_group" reportIdentifier="system_report_in_progress_instances_with_tasks_for_my_group"
showReports={false} showReports={false}
textToShowIfEmpty="This group has no completed instances at this time." textToShowIfEmpty="This group has no instances waiting on it at this time."
additionalParams={`user_group_identifier=${userGroup}`} additionalParams={`user_group_identifier=${userGroup}`}
canCompleteAllTasks canCompleteAllTasks
showActionsColumn showActionsColumn
@ -43,15 +45,21 @@ export default function InProgressInstances() {
}); });
}; };
const startedByMeTitleText =
'This is a list of open instances that you started.';
const waitingForMeTitleText =
'This is a list of instances that have tasks that you can complete.';
return ( return (
<> <>
<h2>My open instances</h2> <h2
<p className="data-table-description"> title={startedByMeTitleText}
This is a list of instances you started that are now complete. className="process-instance-table-header"
</p> >
Started by me
</h2>
<ProcessInstanceListTable <ProcessInstanceListTable
filtersEnabled={false} filtersEnabled={false}
paginationQueryParamPrefix="my_completed_instances" paginationQueryParamPrefix="open_instances_started_by_me"
perPageOptions={[2, 5, 25]} perPageOptions={[2, 5, 25]}
reportIdentifier="system_report_in_progress_instances_initiated_by_me" reportIdentifier="system_report_in_progress_instances_initiated_by_me"
showReports={false} showReports={false}
@ -60,17 +68,19 @@ export default function InProgressInstances() {
showActionsColumn showActionsColumn
autoReload={false} autoReload={false}
/> />
<h2>With tasks I can complete</h2> <h2
<p className="data-table-description"> title={waitingForMeTitleText}
This is a list of instances that have tasks that you can complete. className="process-instance-table-header"
</p> >
Waiting for me
</h2>
<ProcessInstanceListTable <ProcessInstanceListTable
filtersEnabled={false} filtersEnabled={false}
paginationQueryParamPrefix="my_completed_tasks" paginationQueryParamPrefix="waiting_for_me"
perPageOptions={[2, 5, 25]} perPageOptions={[2, 5, 25]}
reportIdentifier="system_report_in_progress_instances_with_tasks_for_me" reportIdentifier="system_report_in_progress_instances_with_tasks_for_me"
showReports={false} showReports={false}
textToShowIfEmpty="You have no completed instances at this time." textToShowIfEmpty="There are no instances waiting on you at this time."
paginationClassName="with-large-bottom-margin" paginationClassName="with-large-bottom-margin"
canCompleteAllTasks canCompleteAllTasks
showActionsColumn showActionsColumn

View File

@ -19,10 +19,7 @@ import MDEditor from '@uiw/react-md-editor';
import Form from '../themes/carbon'; import Form from '../themes/carbon';
import HttpService from '../services/HttpService'; import HttpService from '../services/HttpService';
import useAPIError from '../hooks/UseApiError'; import useAPIError from '../hooks/UseApiError';
import { import { modifyProcessIdentifierForPathParam } from '../helpers';
dateStringToYMDFormat,
modifyProcessIdentifierForPathParam,
} from '../helpers';
import { ProcessInstanceTask } from '../interfaces'; import { ProcessInstanceTask } from '../interfaces';
import ProcessBreadcrumb from '../components/ProcessBreadcrumb'; import ProcessBreadcrumb from '../components/ProcessBreadcrumb';