mirror of
https://github.com/sartography/spiff-arena.git
synced 2025-02-28 00:50:35 +00:00
turned the table list route into a table component w/ burnettk
This commit is contained in:
parent
e6db091ba1
commit
0499a3970e
@ -1,4 +1,4 @@
|
|||||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { Pagination } from '@carbon/react';
|
import { Pagination } from '@carbon/react';
|
||||||
|
@ -41,9 +41,18 @@ import 'react-bootstrap-typeahead/css/Typeahead.css';
|
|||||||
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
||||||
import { PaginationObject, ProcessModel } from '../interfaces';
|
import { PaginationObject, ProcessModel } from '../interfaces';
|
||||||
import ProcessModelSearch from './ProcessModelSearch';
|
import ProcessModelSearch from './ProcessModelSearch';
|
||||||
import ProcessBreadcrumb from './ProcessBreadcrumb';
|
|
||||||
|
|
||||||
export default function ProcessInstanceList() {
|
type OwnProps = {
|
||||||
|
filtersEnabled?: boolean;
|
||||||
|
processModelFullIdentifier?: string;
|
||||||
|
paginationQueryParamPrefix?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function ProcessInstanceListTable({
|
||||||
|
filtersEnabled = true,
|
||||||
|
processModelFullIdentifier,
|
||||||
|
paginationQueryParamPrefix,
|
||||||
|
}: OwnProps) {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -99,7 +108,12 @@ export default function ProcessInstanceList() {
|
|||||||
setPagination(result.pagination);
|
setPagination(result.pagination);
|
||||||
}
|
}
|
||||||
function getProcessInstances() {
|
function getProcessInstances() {
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
const { page, perPage } = getPageInfoFromSearchParams(
|
||||||
|
searchParams,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
paginationQueryParamPrefix
|
||||||
|
);
|
||||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
let queryParamString = `per_page=${perPage}&page=${page}`;
|
||||||
|
|
||||||
Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => {
|
Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => {
|
||||||
@ -118,7 +132,12 @@ export default function ProcessInstanceList() {
|
|||||||
|
|
||||||
Object.keys(parametersToGetFromSearchParams).forEach(
|
Object.keys(parametersToGetFromSearchParams).forEach(
|
||||||
(paramName: string) => {
|
(paramName: string) => {
|
||||||
if (searchParams.get(paramName)) {
|
if (
|
||||||
|
paramName === 'process_model_identifier' &&
|
||||||
|
processModelFullIdentifier
|
||||||
|
) {
|
||||||
|
queryParamString += `&process_model_identifier=${processModelFullIdentifier}`;
|
||||||
|
} else if (searchParams.get(paramName)) {
|
||||||
// @ts-expect-error TS(7053) FIXME:
|
// @ts-expect-error TS(7053) FIXME:
|
||||||
const functionToCall = parametersToGetFromSearchParams[paramName];
|
const functionToCall = parametersToGetFromSearchParams[paramName];
|
||||||
queryParamString += `&${paramName}=${searchParams.get(paramName)}`;
|
queryParamString += `&${paramName}=${searchParams.get(paramName)}`;
|
||||||
@ -129,18 +148,19 @@ export default function ProcessInstanceList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
HttpService.makeCallToBackend({
|
HttpService.makeCallToBackend({
|
||||||
path: `/process-instances?${queryParamString}`,
|
path: `/process-instances?${queryParamString}`,
|
||||||
successCallback: setProcessInstancesFromResult,
|
successCallback: setProcessInstancesFromResult,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function processResultForProcessModels(result: any) {
|
function processResultForProcessModels(result: any) {
|
||||||
const processModelFullIdentifier =
|
const processModelFullIdentifierFromSearchParams =
|
||||||
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
||||||
const selectionArray = result.results.map((item: any) => {
|
const selectionArray = result.results.map((item: any) => {
|
||||||
const label = `${item.id}`;
|
const label = `${item.id}`;
|
||||||
Object.assign(item, { label });
|
Object.assign(item, { label });
|
||||||
if (label === processModelFullIdentifier) {
|
if (label === processModelFullIdentifierFromSearchParams) {
|
||||||
setProcessModelSelection(item);
|
setProcessModelSelection(item);
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
@ -163,11 +183,15 @@ export default function ProcessInstanceList() {
|
|||||||
getProcessInstances();
|
getProcessInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate process model selection
|
if (filtersEnabled) {
|
||||||
HttpService.makeCallToBackend({
|
// populate process model selection
|
||||||
path: `/process-models?per_page=1000`,
|
HttpService.makeCallToBackend({
|
||||||
successCallback: processResultForProcessModels,
|
path: `/process-models?per_page=1000`,
|
||||||
});
|
successCallback: processResultForProcessModels,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
getProcessInstances();
|
||||||
|
}
|
||||||
}, [
|
}, [
|
||||||
searchParams,
|
searchParams,
|
||||||
params,
|
params,
|
||||||
@ -175,6 +199,7 @@ export default function ProcessInstanceList() {
|
|||||||
oneHourInSeconds,
|
oneHourInSeconds,
|
||||||
parametersToAlwaysFilterBy,
|
parametersToAlwaysFilterBy,
|
||||||
parametersToGetFromSearchParams,
|
parametersToGetFromSearchParams,
|
||||||
|
filtersEnabled,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// does the comparison, but also returns false if either argument
|
// does the comparison, but also returns false if either argument
|
||||||
@ -196,7 +221,12 @@ export default function ProcessInstanceList() {
|
|||||||
|
|
||||||
const applyFilter = (event: any) => {
|
const applyFilter = (event: any) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
const { page, perPage } = getPageInfoFromSearchParams(
|
||||||
|
searchParams,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
paginationQueryParamPrefix
|
||||||
|
);
|
||||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
let queryParamString = `per_page=${perPage}&page=${page}`;
|
||||||
|
|
||||||
const startFromSeconds = convertDateStringToSeconds(startFrom);
|
const startFromSeconds = convertDateStringToSeconds(startFrom);
|
||||||
@ -472,41 +502,16 @@ export default function ProcessInstanceList() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const processInstanceBreadcrumbElement = () => {
|
|
||||||
const processModelFullIdentifier =
|
|
||||||
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
|
||||||
if (processModelFullIdentifier === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ProcessBreadcrumb
|
|
||||||
hotCrumbs={[
|
|
||||||
['Process Groups', '/admin'],
|
|
||||||
[
|
|
||||||
`Process Model: ${processModelFullIdentifier}`,
|
|
||||||
`process_model:${processModelFullIdentifier}:link`,
|
|
||||||
],
|
|
||||||
['Process Instances'],
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const processInstanceTitleElement = () => {
|
|
||||||
return <h1>Process Instances</h1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleShowFilterOptions = () => {
|
const toggleShowFilterOptions = () => {
|
||||||
setShowFilterOptions(!showFilterOptions);
|
setShowFilterOptions(!showFilterOptions);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (pagination) {
|
const filterComponent = () => {
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
if (!filtersEnabled) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{processInstanceBreadcrumbElement()}
|
|
||||||
{processInstanceTitleElement()}
|
|
||||||
<Grid fullWidth>
|
<Grid fullWidth>
|
||||||
<Column
|
<Column
|
||||||
sm={{ span: 1, offset: 3 }}
|
sm={{ span: 1, offset: 3 }}
|
||||||
@ -525,6 +530,20 @@ export default function ProcessInstanceList() {
|
|||||||
</Column>
|
</Column>
|
||||||
</Grid>
|
</Grid>
|
||||||
{filterOptions()}
|
{filterOptions()}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pagination) {
|
||||||
|
const { page, perPage } = getPageInfoFromSearchParams(
|
||||||
|
searchParams,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
paginationQueryParamPrefix
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{filterComponent()}
|
||||||
<br />
|
<br />
|
||||||
<PaginationForTable
|
<PaginationForTable
|
||||||
page={page}
|
page={page}
|
||||||
@ -532,6 +551,7 @@ export default function ProcessInstanceList() {
|
|||||||
pagination={pagination}
|
pagination={pagination}
|
||||||
tableToDisplay={buildTable()}
|
tableToDisplay={buildTable()}
|
||||||
queryParamString={getSearchParamsAsQueryString()}
|
queryParamString={getSearchParamsAsQueryString()}
|
||||||
|
paginationQueryParamPrefix={paginationQueryParamPrefix}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,482 +1,15 @@
|
|||||||
import { useContext, useEffect, useMemo, useState } from 'react';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import {
|
|
||||||
Link,
|
|
||||||
useNavigate,
|
|
||||||
useParams,
|
|
||||||
useSearchParams,
|
|
||||||
} from 'react-router-dom';
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import { Filter } from '@carbon/icons-react';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
ButtonSet,
|
|
||||||
DatePicker,
|
|
||||||
DatePickerInput,
|
|
||||||
Table,
|
|
||||||
Grid,
|
|
||||||
Column,
|
|
||||||
MultiSelect,
|
|
||||||
TableHeader,
|
|
||||||
TableHead,
|
|
||||||
TableRow,
|
|
||||||
// @ts-ignore
|
|
||||||
} from '@carbon/react';
|
|
||||||
import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config';
|
|
||||||
import {
|
|
||||||
convertDateStringToSeconds,
|
|
||||||
convertSecondsToFormattedDate,
|
|
||||||
getPageInfoFromSearchParams,
|
|
||||||
getProcessModelFullIdentifierFromSearchParams,
|
|
||||||
modifyProcessModelPath,
|
|
||||||
} from '../helpers';
|
|
||||||
|
|
||||||
import PaginationForTable from '../components/PaginationForTable';
|
|
||||||
import 'react-datepicker/dist/react-datepicker.css';
|
import 'react-datepicker/dist/react-datepicker.css';
|
||||||
|
|
||||||
import ErrorContext from '../contexts/ErrorContext';
|
|
||||||
import HttpService from '../services/HttpService';
|
|
||||||
|
|
||||||
import 'react-bootstrap-typeahead/css/Typeahead.css';
|
import 'react-bootstrap-typeahead/css/Typeahead.css';
|
||||||
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
import 'react-bootstrap-typeahead/css/Typeahead.bs5.css';
|
||||||
import { PaginationObject, ProcessModel } from '../interfaces';
|
|
||||||
import ProcessModelSearch from '../components/ProcessModelSearch';
|
|
||||||
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
import ProcessBreadcrumb from '../components/ProcessBreadcrumb';
|
||||||
|
import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
|
||||||
|
import { getProcessModelFullIdentifierFromSearchParams } from '../helpers';
|
||||||
|
|
||||||
export default function ProcessInstanceList() {
|
export default function ProcessInstanceList() {
|
||||||
const params = useParams();
|
|
||||||
const [searchParams] = useSearchParams();
|
const [searchParams] = useSearchParams();
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const [processInstances, setProcessInstances] = useState([]);
|
|
||||||
const [reportMetadata, setReportMetadata] = useState({});
|
|
||||||
const [pagination, setPagination] = useState<PaginationObject | null>(null);
|
|
||||||
|
|
||||||
const oneHourInSeconds = 3600;
|
|
||||||
const oneMonthInSeconds = oneHourInSeconds * 24 * 30;
|
|
||||||
const [startFrom, setStartFrom] = useState<string>('');
|
|
||||||
const [startTo, setStartTo] = useState<string>('');
|
|
||||||
const [endFrom, setEndFrom] = useState<string>('');
|
|
||||||
const [endTo, setEndTo] = useState<string>('');
|
|
||||||
const [showFilterOptions, setShowFilterOptions] = useState<boolean>(false);
|
|
||||||
|
|
||||||
const setErrorMessage = (useContext as any)(ErrorContext)[1];
|
|
||||||
|
|
||||||
const [processStatusAllOptions, setProcessStatusAllOptions] = useState<any[]>(
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
const [processStatusSelection, setProcessStatusSelection] = useState<
|
|
||||||
string[]
|
|
||||||
>([]);
|
|
||||||
const [processModelAvailableItems, setProcessModelAvailableItems] = useState<
|
|
||||||
ProcessModel[]
|
|
||||||
>([]);
|
|
||||||
const [processModelSelection, setProcessModelSelection] =
|
|
||||||
useState<ProcessModel | null>(null);
|
|
||||||
|
|
||||||
const parametersToAlwaysFilterBy = useMemo(() => {
|
|
||||||
return {
|
|
||||||
start_from: setStartFrom,
|
|
||||||
start_to: setStartTo,
|
|
||||||
end_from: setEndFrom,
|
|
||||||
end_to: setEndTo,
|
|
||||||
};
|
|
||||||
}, [setStartFrom, setStartTo, setEndFrom, setEndTo]);
|
|
||||||
|
|
||||||
const parametersToGetFromSearchParams = useMemo(() => {
|
|
||||||
return {
|
|
||||||
process_model_identifier: null,
|
|
||||||
process_status: null,
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
||||||
useEffect(() => {
|
|
||||||
function setProcessInstancesFromResult(result: any) {
|
|
||||||
const processInstancesFromApi = result.results;
|
|
||||||
setProcessInstances(processInstancesFromApi);
|
|
||||||
setReportMetadata(result.report_metadata);
|
|
||||||
setPagination(result.pagination);
|
|
||||||
}
|
|
||||||
function getProcessInstances() {
|
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
|
||||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
|
||||||
|
|
||||||
Object.keys(parametersToAlwaysFilterBy).forEach((paramName: string) => {
|
|
||||||
// @ts-expect-error TS(7053) FIXME:
|
|
||||||
const functionToCall = parametersToAlwaysFilterBy[paramName];
|
|
||||||
const searchParamValue = searchParams.get(paramName);
|
|
||||||
if (searchParamValue) {
|
|
||||||
queryParamString += `&${paramName}=${searchParamValue}`;
|
|
||||||
const dateString = convertSecondsToFormattedDate(
|
|
||||||
searchParamValue as any
|
|
||||||
);
|
|
||||||
functionToCall(dateString);
|
|
||||||
setShowFilterOptions(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(parametersToGetFromSearchParams).forEach(
|
|
||||||
(paramName: string) => {
|
|
||||||
if (searchParams.get(paramName)) {
|
|
||||||
// @ts-expect-error TS(7053) FIXME:
|
|
||||||
const functionToCall = parametersToGetFromSearchParams[paramName];
|
|
||||||
queryParamString += `&${paramName}=${searchParams.get(paramName)}`;
|
|
||||||
if (functionToCall !== null) {
|
|
||||||
functionToCall(searchParams.get(paramName) || '');
|
|
||||||
}
|
|
||||||
setShowFilterOptions(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
HttpService.makeCallToBackend({
|
|
||||||
path: `/process-instances?${queryParamString}`,
|
|
||||||
successCallback: setProcessInstancesFromResult,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function processResultForProcessModels(result: any) {
|
|
||||||
const processModelFullIdentifier =
|
|
||||||
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
|
||||||
const selectionArray = result.results.map((item: any) => {
|
|
||||||
const label = `${item.id}`;
|
|
||||||
Object.assign(item, { label });
|
|
||||||
if (label === processModelFullIdentifier) {
|
|
||||||
setProcessModelSelection(item);
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
setProcessModelAvailableItems(selectionArray);
|
|
||||||
|
|
||||||
const processStatusSelectedArray: string[] = [];
|
|
||||||
const processStatusAllOptionsArray = PROCESS_STATUSES.map(
|
|
||||||
(processStatusOption: any) => {
|
|
||||||
const regex = new RegExp(`\\b${processStatusOption}\\b`);
|
|
||||||
if ((searchParams.get('process_status') || '').match(regex)) {
|
|
||||||
processStatusSelectedArray.push(processStatusOption);
|
|
||||||
}
|
|
||||||
return processStatusOption;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
setProcessStatusSelection(processStatusSelectedArray);
|
|
||||||
setProcessStatusAllOptions(processStatusAllOptionsArray);
|
|
||||||
|
|
||||||
getProcessInstances();
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate process model selection
|
|
||||||
HttpService.makeCallToBackend({
|
|
||||||
path: `/process-models?per_page=1000`,
|
|
||||||
successCallback: processResultForProcessModels,
|
|
||||||
});
|
|
||||||
}, [
|
|
||||||
searchParams,
|
|
||||||
params,
|
|
||||||
oneMonthInSeconds,
|
|
||||||
oneHourInSeconds,
|
|
||||||
parametersToAlwaysFilterBy,
|
|
||||||
parametersToGetFromSearchParams,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// does the comparison, but also returns false if either argument
|
|
||||||
// is not truthy and therefore not comparable.
|
|
||||||
const isTrueComparison = (param1: any, operation: any, param2: any) => {
|
|
||||||
if (param1 && param2) {
|
|
||||||
switch (operation) {
|
|
||||||
case '<':
|
|
||||||
return param1 < param2;
|
|
||||||
case '>':
|
|
||||||
return param1 > param2;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const applyFilter = (event: any) => {
|
|
||||||
event.preventDefault();
|
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
|
||||||
let queryParamString = `per_page=${perPage}&page=${page}`;
|
|
||||||
|
|
||||||
const startFromSeconds = convertDateStringToSeconds(startFrom);
|
|
||||||
const endFromSeconds = convertDateStringToSeconds(endFrom);
|
|
||||||
const startToSeconds = convertDateStringToSeconds(startTo);
|
|
||||||
const endToSeconds = convertDateStringToSeconds(endTo);
|
|
||||||
if (isTrueComparison(startFromSeconds, '>', startToSeconds)) {
|
|
||||||
setErrorMessage({
|
|
||||||
message: '"Start date from" cannot be after "start date to"',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isTrueComparison(endFromSeconds, '>', endToSeconds)) {
|
|
||||||
setErrorMessage({
|
|
||||||
message: '"End date from" cannot be after "end date to"',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) {
|
|
||||||
setErrorMessage({
|
|
||||||
message: '"Start date from" cannot be after "end date from"',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isTrueComparison(startToSeconds, '>', endToSeconds)) {
|
|
||||||
setErrorMessage({
|
|
||||||
message: '"Start date to" cannot be after "end date to"',
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startFromSeconds) {
|
|
||||||
queryParamString += `&start_from=${startFromSeconds}`;
|
|
||||||
}
|
|
||||||
if (startToSeconds) {
|
|
||||||
queryParamString += `&start_to=${startToSeconds}`;
|
|
||||||
}
|
|
||||||
if (endFromSeconds) {
|
|
||||||
queryParamString += `&end_from=${endFromSeconds}`;
|
|
||||||
}
|
|
||||||
if (endToSeconds) {
|
|
||||||
queryParamString += `&end_to=${endToSeconds}`;
|
|
||||||
}
|
|
||||||
if (processStatusSelection.length > 0) {
|
|
||||||
queryParamString += `&process_status=${processStatusSelection}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (processModelSelection) {
|
|
||||||
queryParamString += `&process_model_identifier=${processModelSelection.id}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setErrorMessage(null);
|
|
||||||
navigate(`/admin/process-instances?${queryParamString}`);
|
|
||||||
};
|
|
||||||
|
|
||||||
const dateComponent = (
|
|
||||||
labelString: any,
|
|
||||||
name: any,
|
|
||||||
initialDate: any,
|
|
||||||
onChangeFunction: any
|
|
||||||
) => {
|
|
||||||
return (
|
|
||||||
<DatePicker dateFormat={DATE_FORMAT_CARBON} datePickerType="single">
|
|
||||||
<DatePickerInput
|
|
||||||
id={`date-picker-${name}`}
|
|
||||||
placeholder={DATE_FORMAT}
|
|
||||||
labelText={labelString}
|
|
||||||
type="text"
|
|
||||||
size="md"
|
|
||||||
autocomplete="off"
|
|
||||||
allowInput={false}
|
|
||||||
onChange={(dateChangeEvent: any) => {
|
|
||||||
onChangeFunction(dateChangeEvent.srcElement.value);
|
|
||||||
}}
|
|
||||||
value={initialDate}
|
|
||||||
/>
|
|
||||||
</DatePicker>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const processStatusSearch = () => {
|
|
||||||
return (
|
|
||||||
<MultiSelect
|
|
||||||
label="Choose Status"
|
|
||||||
className="our-class"
|
|
||||||
id="process-instance-status-select"
|
|
||||||
titleText="Status"
|
|
||||||
items={processStatusAllOptions}
|
|
||||||
onChange={(selection: any) => {
|
|
||||||
setProcessStatusSelection(selection.selectedItems);
|
|
||||||
}}
|
|
||||||
itemToString={(item: any) => {
|
|
||||||
return item || '';
|
|
||||||
}}
|
|
||||||
selectionFeedback="top-after-reopen"
|
|
||||||
selectedItems={processStatusSelection}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const clearFilters = () => {
|
|
||||||
setProcessModelSelection(null);
|
|
||||||
setProcessStatusSelection([]);
|
|
||||||
setStartFrom('');
|
|
||||||
setStartTo('');
|
|
||||||
setEndFrom('');
|
|
||||||
setEndTo('');
|
|
||||||
};
|
|
||||||
const filterOptions = () => {
|
|
||||||
if (!showFilterOptions) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Grid fullWidth className="with-bottom-margin">
|
|
||||||
<Column md={8}>
|
|
||||||
<ProcessModelSearch
|
|
||||||
onChange={(selection: any) =>
|
|
||||||
setProcessModelSelection(selection.selectedItem)
|
|
||||||
}
|
|
||||||
processModels={processModelAvailableItems}
|
|
||||||
selectedItem={processModelSelection}
|
|
||||||
/>
|
|
||||||
</Column>
|
|
||||||
<Column md={8}>{processStatusSearch()}</Column>
|
|
||||||
</Grid>
|
|
||||||
<Grid fullWidth className="with-bottom-margin">
|
|
||||||
<Column md={4}>
|
|
||||||
{dateComponent(
|
|
||||||
'Start date from',
|
|
||||||
'start-from',
|
|
||||||
startFrom,
|
|
||||||
setStartFrom
|
|
||||||
)}
|
|
||||||
</Column>
|
|
||||||
<Column md={4}>
|
|
||||||
{dateComponent('Start date to', 'start-to', startTo, setStartTo)}
|
|
||||||
</Column>
|
|
||||||
<Column md={4}>
|
|
||||||
{dateComponent('End date from', 'end-from', endFrom, setEndFrom)}
|
|
||||||
</Column>
|
|
||||||
<Column md={4}>
|
|
||||||
{dateComponent('End date to', 'end-to', endTo, setEndTo)}
|
|
||||||
</Column>
|
|
||||||
</Grid>
|
|
||||||
<Grid fullWidth className="with-bottom-margin">
|
|
||||||
<Column md={4}>
|
|
||||||
<ButtonSet>
|
|
||||||
<Button
|
|
||||||
kind=""
|
|
||||||
className="button-white-background"
|
|
||||||
onClick={clearFilters}
|
|
||||||
>
|
|
||||||
Clear
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
kind="secondary"
|
|
||||||
onClick={applyFilter}
|
|
||||||
data-qa="filter-button"
|
|
||||||
>
|
|
||||||
Filter
|
|
||||||
</Button>
|
|
||||||
</ButtonSet>
|
|
||||||
</Column>
|
|
||||||
</Grid>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const toggleShowFilterOptions = () => {
|
|
||||||
setShowFilterOptions(!showFilterOptions);
|
|
||||||
};
|
|
||||||
const filterComponent = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Grid fullWidth>
|
|
||||||
<Column
|
|
||||||
sm={{ span: 1, offset: 3 }}
|
|
||||||
md={{ span: 1, offset: 7 }}
|
|
||||||
lg={{ span: 1, offset: 15 }}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
data-qa="filter-section-expand-toggle"
|
|
||||||
kind="ghost"
|
|
||||||
renderIcon={Filter}
|
|
||||||
iconDescription="Filter Options"
|
|
||||||
hasIconOnly
|
|
||||||
size="lg"
|
|
||||||
onClick={toggleShowFilterOptions}
|
|
||||||
/>
|
|
||||||
</Column>
|
|
||||||
</Grid>
|
|
||||||
{filterOptions()}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const buildTable = () => {
|
|
||||||
const headerLabels: Record<string, string> = {
|
|
||||||
id: 'Process Instance Id',
|
|
||||||
process_model_identifier: 'Process Model',
|
|
||||||
start_in_seconds: 'Start Time',
|
|
||||||
end_in_seconds: 'End Time',
|
|
||||||
status: 'Status',
|
|
||||||
spiff_step: 'SpiffWorkflow Step',
|
|
||||||
};
|
|
||||||
const getHeaderLabel = (header: string) => {
|
|
||||||
return headerLabels[header] ?? header;
|
|
||||||
};
|
|
||||||
const headers = (reportMetadata as any).columns.map((column: any) => {
|
|
||||||
// return <th>{getHeaderLabel((column as any).Header)}</th>;
|
|
||||||
return getHeaderLabel((column as any).Header);
|
|
||||||
});
|
|
||||||
|
|
||||||
const formatProcessInstanceId = (row: any, id: any) => {
|
|
||||||
const modifiedProcessModelId: String = modifyProcessModelPath(
|
|
||||||
row.process_model_identifier
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
data-qa="process-instance-show-link"
|
|
||||||
to={`/admin/process-models/${modifiedProcessModelId}/process-instances/${row.id}`}
|
|
||||||
>
|
|
||||||
{id}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const formatProcessModelIdentifier = (_row: any, identifier: any) => {
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
to={`/admin/process-models/${modifyProcessModelPath(identifier)}`}
|
|
||||||
>
|
|
||||||
{identifier}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const formatSecondsForDisplay = (_row: any, seconds: any) => {
|
|
||||||
return convertSecondsToFormattedDate(seconds) || '-';
|
|
||||||
};
|
|
||||||
const defaultFormatter = (_row: any, value: any) => {
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
const columnFormatters: Record<string, any> = {
|
|
||||||
id: formatProcessInstanceId,
|
|
||||||
process_model_identifier: formatProcessModelIdentifier,
|
|
||||||
start_in_seconds: formatSecondsForDisplay,
|
|
||||||
end_in_seconds: formatSecondsForDisplay,
|
|
||||||
};
|
|
||||||
const formattedColumn = (row: any, column: any) => {
|
|
||||||
const formatter = columnFormatters[column.accessor] ?? defaultFormatter;
|
|
||||||
const value = row[column.accessor];
|
|
||||||
if (column.accessor === 'status') {
|
|
||||||
return (
|
|
||||||
<td data-qa={`process-instance-status-${value}`}>
|
|
||||||
{formatter(row, value)}
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return <td>{formatter(row, value)}</td>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const rows = processInstances.map((row: any) => {
|
|
||||||
const currentRow = (reportMetadata as any).columns.map((column: any) => {
|
|
||||||
return formattedColumn(row, column);
|
|
||||||
});
|
|
||||||
return <tr key={row.id}>{currentRow}</tr>;
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Table size="lg">
|
|
||||||
<TableHead>
|
|
||||||
<TableRow>
|
|
||||||
{headers.map((header: any) => (
|
|
||||||
<TableHeader key={header}>{header}</TableHeader>
|
|
||||||
))}
|
|
||||||
</TableRow>
|
|
||||||
</TableHead>
|
|
||||||
<tbody>{rows}</tbody>
|
|
||||||
</Table>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const processInstanceBreadcrumbElement = () => {
|
const processInstanceBreadcrumbElement = () => {
|
||||||
const processModelFullIdentifier =
|
const processModelFullIdentifier =
|
||||||
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
getProcessModelFullIdentifierFromSearchParams(searchParams);
|
||||||
@ -498,47 +31,14 @@ export default function ProcessInstanceList() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSearchParamsAsQueryString = () => {
|
|
||||||
let queryParamString = '';
|
|
||||||
Object.keys(parametersToAlwaysFilterBy).forEach((paramName) => {
|
|
||||||
const searchParamValue = searchParams.get(paramName);
|
|
||||||
if (searchParamValue) {
|
|
||||||
queryParamString += `&${paramName}=${searchParamValue}`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.keys(parametersToGetFromSearchParams).forEach(
|
|
||||||
(paramName: string) => {
|
|
||||||
if (searchParams.get(paramName)) {
|
|
||||||
queryParamString += `&${paramName}=${searchParams.get(paramName)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
return queryParamString;
|
|
||||||
};
|
|
||||||
|
|
||||||
const processInstanceTitleElement = () => {
|
const processInstanceTitleElement = () => {
|
||||||
return <h1>Process Instances</h1>;
|
return <h1>Process Instances</h1>;
|
||||||
};
|
};
|
||||||
|
return (
|
||||||
if (pagination) {
|
<>
|
||||||
const { page, perPage } = getPageInfoFromSearchParams(searchParams);
|
{processInstanceBreadcrumbElement()}
|
||||||
return (
|
{processInstanceTitleElement()}
|
||||||
<>
|
<ProcessInstanceListTable />
|
||||||
{processInstanceBreadcrumbElement()}
|
</>
|
||||||
{processInstanceTitleElement()}
|
);
|
||||||
{filterComponent()}
|
|
||||||
<br />
|
|
||||||
<PaginationForTable
|
|
||||||
page={page}
|
|
||||||
perPage={perPage}
|
|
||||||
pagination={pagination}
|
|
||||||
tableToDisplay={buildTable()}
|
|
||||||
queryParamString={getSearchParamsAsQueryString()}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import ErrorContext from '../contexts/ErrorContext';
|
|||||||
import { modifyProcessModelPath, unModifyProcessModelPath } from '../helpers';
|
import { modifyProcessModelPath, unModifyProcessModelPath } from '../helpers';
|
||||||
import { ProcessFile, ProcessModel, RecentProcessModel } from '../interfaces';
|
import { ProcessFile, ProcessModel, RecentProcessModel } from '../interfaces';
|
||||||
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
import ButtonWithConfirmation from '../components/ButtonWithConfirmation';
|
||||||
|
import ProcessInstanceListTable from '../components/ProcessInstanceListTable';
|
||||||
|
|
||||||
const storeRecentProcessModelInLocalStorage = (
|
const storeRecentProcessModelInLocalStorage = (
|
||||||
processModelForStorage: ProcessModel
|
processModelForStorage: ProcessModel
|
||||||
@ -538,6 +539,11 @@ export default function ProcessModelShow() {
|
|||||||
{processInstancesUl()}
|
{processInstancesUl()}
|
||||||
<br />
|
<br />
|
||||||
{processModelButtons()}
|
{processModelButtons()}
|
||||||
|
<br />
|
||||||
|
<ProcessInstanceListTable
|
||||||
|
filtersEnabled={false}
|
||||||
|
processModelFullIdentifier={processModel.id}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user