Feature/pi table ux tweaks (#1133)
* make only the pi id an link on the pi instance table and set up for a refresh button on the table title on the pi list page w/ burnettk * added refresh pi table button w/ burnettk * show the process model link in the pi table as well w/ burnettk --------- Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
parent
4cf70a8e9b
commit
87fd3ddf65
|
@ -1,16 +1,17 @@
|
||||||
import { ArrowRight } from '@carbon/icons-react';
|
import { ArrowRight, Renew } from '@carbon/icons-react';
|
||||||
import {
|
import {
|
||||||
Grid,
|
Grid,
|
||||||
Column,
|
Column,
|
||||||
TableRow,
|
TableRow,
|
||||||
Table,
|
Table,
|
||||||
TableHeader,
|
|
||||||
TableHead,
|
TableHead,
|
||||||
Button,
|
Button,
|
||||||
|
TableHeader,
|
||||||
|
Stack,
|
||||||
} from '@carbon/react';
|
} from '@carbon/react';
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import 'react-datepicker/dist/react-datepicker.css';
|
import 'react-datepicker/dist/react-datepicker.css';
|
||||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
import { Link, useNavigate, useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getLastMilestoneFromProcessInstance,
|
getLastMilestoneFromProcessInstance,
|
||||||
|
@ -43,6 +44,7 @@ type OwnProps = {
|
||||||
additionalReportFilters?: ReportFilter[];
|
additionalReportFilters?: ReportFilter[];
|
||||||
autoReload?: boolean;
|
autoReload?: boolean;
|
||||||
canCompleteAllTasks?: boolean;
|
canCompleteAllTasks?: boolean;
|
||||||
|
filterComponent?: Function;
|
||||||
header?: SpiffTableHeader;
|
header?: SpiffTableHeader;
|
||||||
onProcessInstanceTableListUpdate?: Function;
|
onProcessInstanceTableListUpdate?: Function;
|
||||||
paginationClassName?: string;
|
paginationClassName?: string;
|
||||||
|
@ -61,6 +63,7 @@ export default function ProcessInstanceListTable({
|
||||||
additionalReportFilters,
|
additionalReportFilters,
|
||||||
autoReload = false,
|
autoReload = false,
|
||||||
canCompleteAllTasks = false,
|
canCompleteAllTasks = false,
|
||||||
|
filterComponent,
|
||||||
header,
|
header,
|
||||||
onProcessInstanceTableListUpdate,
|
onProcessInstanceTableListUpdate,
|
||||||
paginationClassName,
|
paginationClassName,
|
||||||
|
@ -225,6 +228,20 @@ export default function ProcessInstanceListTable({
|
||||||
return [];
|
return [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getProcessModelSpanTag = (
|
||||||
|
processInstance: ProcessInstance,
|
||||||
|
identifier: string
|
||||||
|
) => {
|
||||||
|
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
||||||
|
processInstance.process_model_identifier
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<Link to={`/process-models/${modifiedModelId}`}>{identifier}</Link>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const getWaitingForTableCellComponent = (processInstanceTask: any) => {
|
const getWaitingForTableCellComponent = (processInstanceTask: any) => {
|
||||||
let fullUsernameString = '';
|
let fullUsernameString = '';
|
||||||
let shortUsernameString = '';
|
let shortUsernameString = '';
|
||||||
|
@ -244,20 +261,31 @@ export default function ProcessInstanceListTable({
|
||||||
}
|
}
|
||||||
return <span title={fullUsernameString}>{shortUsernameString}</span>;
|
return <span title={fullUsernameString}>{shortUsernameString}</span>;
|
||||||
};
|
};
|
||||||
const formatProcessInstanceId = (_row: ProcessInstance, id: number) => {
|
const formatProcessInstanceId = (
|
||||||
return <span data-qa="paginated-entity-id">{id}</span>;
|
processInstance: ProcessInstance,
|
||||||
|
id: number
|
||||||
|
) => {
|
||||||
|
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
||||||
|
processInstance.process_model_identifier
|
||||||
|
);
|
||||||
|
const piLink = `${processInstanceShowPathPrefix}/${modifiedModelId}/${processInstance.id}`;
|
||||||
|
return (
|
||||||
|
<span data-qa="paginated-entity-id">
|
||||||
|
<Link to={piLink}>{id}</Link>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
const formatProcessModelIdentifier = (
|
const formatProcessModelIdentifier = (
|
||||||
_row: ProcessInstance,
|
processInstance: ProcessInstance,
|
||||||
identifier: any
|
identifier: any
|
||||||
) => {
|
) => {
|
||||||
return <span>{identifier}</span>;
|
return getProcessModelSpanTag(processInstance, identifier);
|
||||||
};
|
};
|
||||||
const formatProcessModelDisplayName = (
|
const formatProcessModelDisplayName = (
|
||||||
_row: ProcessInstance,
|
processInstance: ProcessInstance,
|
||||||
identifier: any
|
identifier: any
|
||||||
) => {
|
) => {
|
||||||
return <span>{identifier}</span>;
|
return getProcessModelSpanTag(processInstance, identifier);
|
||||||
};
|
};
|
||||||
const formatLastMilestone = (
|
const formatLastMilestone = (
|
||||||
processInstance: ProcessInstance,
|
processInstance: ProcessInstance,
|
||||||
|
@ -337,6 +365,48 @@ export default function ProcessInstanceListTable({
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const tableTitle = () => {
|
||||||
|
let headerTextElement = null;
|
||||||
|
if (header) {
|
||||||
|
headerTextElement = header.text;
|
||||||
|
// poor man's markdown, just so we can allow bolded words in headers
|
||||||
|
if (header.text.includes('**')) {
|
||||||
|
const parts = header.text.split('**');
|
||||||
|
if (parts.length === 3) {
|
||||||
|
headerTextElement = (
|
||||||
|
<>
|
||||||
|
{parts[0]}
|
||||||
|
<strong>{parts[1]}</strong>
|
||||||
|
{parts[2]}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header) {
|
||||||
|
return (
|
||||||
|
<Stack orientation="horizontal" gap={1}>
|
||||||
|
<h2
|
||||||
|
title={header.tooltip_text}
|
||||||
|
className="process-instance-table-header with-icons"
|
||||||
|
>
|
||||||
|
{headerTextElement}
|
||||||
|
</h2>
|
||||||
|
<Button
|
||||||
|
kind="ghost"
|
||||||
|
data-qa="refresh-process-instance-table"
|
||||||
|
renderIcon={Renew}
|
||||||
|
iconDescription="Refresh data in the table"
|
||||||
|
hasIconOnly
|
||||||
|
onClick={() => getProcessInstances()}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
const tableTitleLine = () => {
|
const tableTitleLine = () => {
|
||||||
if (!showLinkToReport && !header) {
|
if (!showLinkToReport && !header) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -367,23 +437,6 @@ export default function ProcessInstanceListTable({
|
||||||
if (!header && !filterButtonLink) {
|
if (!header && !filterButtonLink) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let headerTextElement = null;
|
|
||||||
if (header) {
|
|
||||||
headerTextElement = header.text;
|
|
||||||
// poor man's markdown, just so we can allow bolded words in headers
|
|
||||||
if (header.text.includes('**')) {
|
|
||||||
const parts = header.text.split('**');
|
|
||||||
if (parts.length === 3) {
|
|
||||||
headerTextElement = (
|
|
||||||
<>
|
|
||||||
{parts[0]}
|
|
||||||
<strong>{parts[1]}</strong>
|
|
||||||
{parts[2]}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Column
|
<Column
|
||||||
|
@ -392,14 +445,7 @@ export default function ProcessInstanceListTable({
|
||||||
lg={{ span: 15 }}
|
lg={{ span: 15 }}
|
||||||
style={{ height: '48px' }}
|
style={{ height: '48px' }}
|
||||||
>
|
>
|
||||||
{header ? (
|
{tableTitle()}
|
||||||
<h2
|
|
||||||
title={header.tooltip_text}
|
|
||||||
className="process-instance-table-header"
|
|
||||||
>
|
|
||||||
{headerTextElement}
|
|
||||||
</h2>
|
|
||||||
) : null}
|
|
||||||
</Column>
|
</Column>
|
||||||
{filterButtonLink}
|
{filterButtonLink}
|
||||||
</>
|
</>
|
||||||
|
@ -455,15 +501,6 @@ export default function ProcessInstanceListTable({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const rowStyle = { cursor: 'pointer' };
|
|
||||||
const modifiedModelId = modifyProcessIdentifierForPathParam(
|
|
||||||
processInstance.process_model_identifier
|
|
||||||
);
|
|
||||||
const navigateToProcessInstance = () => {
|
|
||||||
navigate(
|
|
||||||
`${processInstanceShowPathPrefix}/${modifiedModelId}/${processInstance.id}`
|
|
||||||
);
|
|
||||||
};
|
|
||||||
let variantFromMetadata = 'all';
|
let variantFromMetadata = 'all';
|
||||||
if (reportMetadataFromProcessInstances) {
|
if (reportMetadataFromProcessInstances) {
|
||||||
reportMetadataFromProcessInstances.filter_by.forEach((filter: any) => {
|
reportMetadataFromProcessInstances.filter_by.forEach((filter: any) => {
|
||||||
|
@ -479,10 +516,7 @@ export default function ProcessInstanceListTable({
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
|
||||||
<tr
|
<tr
|
||||||
style={rowStyle}
|
|
||||||
key={processInstance.id}
|
key={processInstance.id}
|
||||||
onClick={navigateToProcessInstance}
|
|
||||||
onKeyDown={navigateToProcessInstance}
|
|
||||||
className={`process-instance-list-row-variant-${variantFromMetadata}`}
|
className={`process-instance-list-row-variant-${variantFromMetadata}`}
|
||||||
>
|
>
|
||||||
{currentRow}
|
{currentRow}
|
||||||
|
@ -573,11 +607,16 @@ export default function ProcessInstanceListTable({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Grid fullWidth condensed className="megacondensed">
|
<>
|
||||||
{tableTitleLine()}
|
<Grid fullWidth condensed className="megacondensed">
|
||||||
<Column sm={{ span: 4 }} md={{ span: 8 }} lg={{ span: 16 }}>
|
{tableTitleLine()}
|
||||||
{tableElement}
|
</Grid>
|
||||||
</Column>
|
{filterComponent ? filterComponent() : null}
|
||||||
</Grid>
|
<Grid fullWidth condensed className="megacondensed">
|
||||||
|
<Column sm={{ span: 4 }} md={{ span: 8 }} lg={{ span: 16 }}>
|
||||||
|
{tableElement}
|
||||||
|
</Column>
|
||||||
|
</Grid>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1539,6 +1539,23 @@ export default function ProcessInstanceListTableWithFilters({
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const filterComponent = () => {
|
||||||
|
return (
|
||||||
|
<Grid fullWidth condensed className="megacondensed">
|
||||||
|
<Column sm={{ span: 4 }} md={{ span: 8 }} lg={{ span: 16 }}>
|
||||||
|
<Filters
|
||||||
|
filterOptions={filterOptions}
|
||||||
|
showFilterOptions={showFilterOptions}
|
||||||
|
setShowFilterOptions={setShowFilterOptions}
|
||||||
|
reportSearchComponent={reportSearchComponent}
|
||||||
|
filtersEnabled={filtersEnabled}
|
||||||
|
reportHash={reportHash}
|
||||||
|
/>
|
||||||
|
</Column>
|
||||||
|
</Grid>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
let resultsTable = null;
|
let resultsTable = null;
|
||||||
if (reportMetadata) {
|
if (reportMetadata) {
|
||||||
const refilterTextComponent = null;
|
const refilterTextComponent = null;
|
||||||
|
@ -1559,6 +1576,7 @@ export default function ProcessInstanceListTableWithFilters({
|
||||||
tableHtmlId={tableHtmlId}
|
tableHtmlId={tableHtmlId}
|
||||||
textToShowIfEmpty={textToShowIfEmpty}
|
textToShowIfEmpty={textToShowIfEmpty}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
|
filterComponent={filterComponent}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1569,18 +1587,6 @@ export default function ProcessInstanceListTableWithFilters({
|
||||||
{reportColumnForm()}
|
{reportColumnForm()}
|
||||||
{advancedOptionsModal()}
|
{advancedOptionsModal()}
|
||||||
{processInstanceReportSaveTag()}
|
{processInstanceReportSaveTag()}
|
||||||
<Grid fullWidth condensed className="megacondensed">
|
|
||||||
<Column sm={{ span: 4 }} md={{ span: 8 }} lg={{ span: 16 }}>
|
|
||||||
<Filters
|
|
||||||
filterOptions={filterOptions}
|
|
||||||
showFilterOptions={showFilterOptions}
|
|
||||||
setShowFilterOptions={setShowFilterOptions}
|
|
||||||
reportSearchComponent={reportSearchComponent}
|
|
||||||
filtersEnabled={filtersEnabled}
|
|
||||||
reportHash={reportHash}
|
|
||||||
/>
|
|
||||||
</Column>
|
|
||||||
</Grid>
|
|
||||||
{resultsTable}
|
{resultsTable}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -493,6 +493,6 @@ export interface SpiffTab {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SpiffTableHeader {
|
export interface SpiffTableHeader {
|
||||||
tooltip_text: string;
|
tooltip_text?: string;
|
||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,10 +41,11 @@ export default function ProcessInstanceList({ variant }: OwnProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const processInstanceTitleElement = () => {
|
const processInstanceTitleElement = () => {
|
||||||
|
let headerText = 'My Process Instances';
|
||||||
if (variant === 'all') {
|
if (variant === 'all') {
|
||||||
return <h1>All Process Instances</h1>;
|
headerText = 'All Process Instances';
|
||||||
}
|
}
|
||||||
return <h1>My Process Instances</h1>;
|
return { text: headerText };
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -52,10 +53,10 @@ export default function ProcessInstanceList({ variant }: OwnProps) {
|
||||||
<ProcessInstanceListTabs variant={variant} />
|
<ProcessInstanceListTabs variant={variant} />
|
||||||
<br />
|
<br />
|
||||||
{processInstanceBreadcrumbElement()}
|
{processInstanceBreadcrumbElement()}
|
||||||
{processInstanceTitleElement()}
|
|
||||||
<ProcessInstanceListTableWithFilters
|
<ProcessInstanceListTableWithFilters
|
||||||
variant={variant}
|
variant={variant}
|
||||||
showActionsColumn
|
showActionsColumn
|
||||||
|
header={processInstanceTitleElement()}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue