add date ranges for process instances search w/ burnettk

This commit is contained in:
jasquat 2022-11-02 12:42:49 -04:00
parent d0e56a2ea1
commit 74976ec6df
5 changed files with 110 additions and 126 deletions

View File

@ -429,7 +429,7 @@ paths:
description: For filtering - beginning of start window - in seconds since epoch description: For filtering - beginning of start window - in seconds since epoch
schema: schema:
type: integer type: integer
- name: start_till - name: start_to
in: query in: query
required: false required: false
description: For filtering - end of start window - in seconds since epoch description: For filtering - end of start window - in seconds since epoch
@ -441,7 +441,7 @@ paths:
description: For filtering - beginning of end window - in seconds since epoch description: For filtering - beginning of end window - in seconds since epoch
schema: schema:
type: integer type: integer
- name: end_till - name: end_to
in: query in: query
required: false required: false
description: For filtering - end of end window - in seconds since epoch description: For filtering - end of end window - in seconds since epoch

View File

@ -651,9 +651,9 @@ def process_instance_list(
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
start_from: Optional[int] = None, start_from: Optional[int] = None,
start_till: Optional[int] = None, start_to: Optional[int] = None,
end_from: Optional[int] = None, end_from: Optional[int] = None,
end_till: Optional[int] = None, end_to: Optional[int] = None,
process_status: Optional[str] = None, process_status: Optional[str] = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_instance_list.""" """Process_instance_list."""
@ -684,17 +684,17 @@ def process_instance_list(
process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
ProcessInstanceModel.start_in_seconds >= start_from ProcessInstanceModel.start_in_seconds >= start_from
) )
if start_till is not None: if start_to is not None:
process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
ProcessInstanceModel.start_in_seconds <= start_till ProcessInstanceModel.start_in_seconds <= start_to
) )
if end_from is not None: if end_from is not None:
process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
ProcessInstanceModel.end_in_seconds >= end_from ProcessInstanceModel.end_in_seconds >= end_from
) )
if end_till is not None: if end_to is not None:
process_instance_query = process_instance_query.filter( process_instance_query = process_instance_query.filter(
ProcessInstanceModel.end_in_seconds <= end_till ProcessInstanceModel.end_in_seconds <= end_to
) )
if process_status is not None: if process_status is not None:
process_status_array = process_status.split(",") process_status_array = process_status.split(",")

View File

@ -16,4 +16,6 @@ export const PROCESS_STATUSES = [
'suspended', 'suspended',
]; ];
export const DATE_FORMAT = 'Y-m-d'; // with time: yyyy-MM-dd HH:mm:ss
export const DATE_FORMAT = 'yyyy-MM-dd';
export const DATE_FORMAT_CARBON = 'Y-m-d';

View File

@ -20,7 +20,10 @@ export const capitalizeFirstLetter = (string: any) => {
return string.charAt(0).toUpperCase() + string.slice(1); return string.charAt(0).toUpperCase() + string.slice(1);
}; };
export const convertDateToSeconds = (date: any, onChangeFunction: any) => { export const convertDateToSeconds = (
date: any,
onChangeFunction: any = null
) => {
let dateInSeconds = date; let dateInSeconds = date;
if (date !== null) { if (date !== null) {
let dateInMilliseconds = date; let dateInMilliseconds = date;
@ -39,14 +42,26 @@ export const convertDateToSeconds = (date: any, onChangeFunction: any) => {
return null; return null;
}; };
export const convertSecondsToFormattedDate = (seconds: number) => { export const convertStringToDate = (dateString: string) => {
if (seconds) { if (dateString) {
const startDate = new Date(seconds * 1000); return new Date(dateString);
return format(startDate, DATE_FORMAT);
} }
return null; return null;
}; };
export const convertSecondsToFormattedDate = (seconds: number) => {
if (seconds) {
const dateObject = new Date(seconds * 1000);
return format(dateObject, DATE_FORMAT);
}
return null;
};
export const convertDateStringToSeconds = (dateString: string) => {
const dateObject = convertStringToDate(dateString);
return convertDateToSeconds(dateObject);
};
export const objectIsEmpty = (obj: object) => { export const objectIsEmpty = (obj: object) => {
return Object.keys(obj).length === 0; return Object.keys(obj).length === 0;
}; };

View File

@ -24,9 +24,9 @@ import {
} from '@carbon/react'; } from '@carbon/react';
import { InputGroup } from 'react-bootstrap'; import { InputGroup } from 'react-bootstrap';
import { Typeahead } from 'react-bootstrap-typeahead'; import { Typeahead } from 'react-bootstrap-typeahead';
import { PROCESS_STATUSES, DATE_FORMAT } from '../config'; import { PROCESS_STATUSES, DATE_FORMAT, DATE_FORMAT_CARBON } from '../config';
import { import {
convertDateToSeconds, convertDateStringToSeconds,
convertSecondsToFormattedDate, convertSecondsToFormattedDate,
getPageInfoFromSearchParams, getPageInfoFromSearchParams,
getProcessModelFullIdentifierFromSearchParams, getProcessModelFullIdentifierFromSearchParams,
@ -53,10 +53,10 @@ export default function ProcessInstanceList() {
const oneHourInSeconds = 3600; const oneHourInSeconds = 3600;
const oneMonthInSeconds = oneHourInSeconds * 24 * 30; const oneMonthInSeconds = oneHourInSeconds * 24 * 30;
const [startFrom, setStartFrom] = useState(null); const [startFrom, setStartFrom] = useState<string>('');
const [startTill, setStartTill] = useState(null); const [startTo, setStartTo] = useState<string>('');
const [endFrom, setEndFrom] = useState(null); const [endFrom, setEndFrom] = useState<string>('');
const [endTill, setEndTill] = useState(null); const [endTo, setEndTo] = useState<string>('');
const setErrorMessage = (useContext as any)(ErrorContext)[1]; const setErrorMessage = (useContext as any)(ErrorContext)[1];
@ -69,20 +69,17 @@ export default function ProcessInstanceList() {
const [processModelAvailableItems, setProcessModelAvailableItems] = useState< const [processModelAvailableItems, setProcessModelAvailableItems] = useState<
ProcessModel[] ProcessModel[]
>([]); >([]);
const [processModelFilteredItems, setProcessModelFilteredItems] = useState<
ProcessModel[]
>([]);
const [processModelSelection, setProcessModelSelection] = const [processModelSelection, setProcessModelSelection] =
useState<ProcessModel | null>(null); useState<ProcessModel | null>(null);
const parametersToAlwaysFilterBy = useMemo(() => { const parametersToAlwaysFilterBy = useMemo(() => {
return { return {
start_from: setStartFrom, start_from: setStartFrom,
start_till: setStartTill, start_to: setStartTo,
end_from: setEndFrom, end_from: setEndFrom,
end_till: setEndTill, end_to: setEndTo,
}; };
}, [setStartFrom, setStartTill, setEndFrom, setEndTill]); }, [setStartFrom, setStartTo, setEndFrom, setEndTo]);
const parametersToGetFromSearchParams = useMemo(() => { const parametersToGetFromSearchParams = useMemo(() => {
return { return {
@ -109,7 +106,10 @@ export default function ProcessInstanceList() {
const searchParamValue = searchParams.get(paramName); const searchParamValue = searchParams.get(paramName);
if (searchParamValue) { if (searchParamValue) {
queryParamString += `&${paramName}=${searchParamValue}`; queryParamString += `&${paramName}=${searchParamValue}`;
functionToCall(searchParamValue); const dateString = convertSecondsToFormattedDate(
searchParamValue as any
);
functionToCall(dateString);
} }
}); });
@ -142,7 +142,6 @@ export default function ProcessInstanceList() {
return item; return item;
}); });
setProcessModelAvailableItems(selectionArray); setProcessModelAvailableItems(selectionArray);
setProcessModelFilteredItems(selectionArray);
const processStatusSelectedArray: string[] = []; const processStatusSelectedArray: string[] = [];
const processStatusAllOptionsArray = PROCESS_STATUSES.map( const processStatusAllOptionsArray = PROCESS_STATUSES.map(
@ -195,34 +194,46 @@ export default function ProcessInstanceList() {
const { page, perPage } = getPageInfoFromSearchParams(searchParams); const { page, perPage } = getPageInfoFromSearchParams(searchParams);
let queryParamString = `per_page=${perPage}&page=${page}`; let queryParamString = `per_page=${perPage}&page=${page}`;
if (isTrueComparison(startFrom, '>', startTill)) { const startFromSeconds = convertDateStringToSeconds(startFrom);
setErrorMessage({ message: 'startFrom cannot be after startTill' }); 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; return;
} }
if (isTrueComparison(endFrom, '>', endTill)) { if (isTrueComparison(endFromSeconds, '>', endToSeconds)) {
setErrorMessage({ message: 'endFrom cannot be after endTill' }); setErrorMessage({
message: '"End date from" cannot be after "end date to"',
});
return; return;
} }
if (isTrueComparison(startFrom, '>', endFrom)) { if (isTrueComparison(startFromSeconds, '>', endFromSeconds)) {
setErrorMessage({ message: 'startFrom cannot be after endFrom' }); setErrorMessage({
message: '"Start date from" cannot be after "end date from"',
});
return; return;
} }
if (isTrueComparison(startTill, '>', endTill)) { if (isTrueComparison(startToSeconds, '>', endToSeconds)) {
setErrorMessage({ message: 'startTill cannot be after endTill' }); setErrorMessage({
message: '"Start date to" cannot be after "end date to"',
});
return; return;
} }
if (startFrom) { if (startFromSeconds) {
queryParamString += `&start_from=${startFrom}`; queryParamString += `&start_from=${startFromSeconds}`;
} }
if (startTill) { if (startToSeconds) {
queryParamString += `&start_till=${startTill}`; queryParamString += `&start_to=${startToSeconds}`;
} }
if (endFrom) { if (endFromSeconds) {
queryParamString += `&end_from=${endFrom}`; queryParamString += `&end_from=${endFromSeconds}`;
} }
if (endTill) { if (endToSeconds) {
queryParamString += `&end_till=${endTill}`; queryParamString += `&end_to=${endToSeconds}`;
} }
if (processStatusSelection.length > 0) { if (processStatusSelection.length > 0) {
queryParamString += `&process_status=${processStatusSelection}`; queryParamString += `&process_status=${processStatusSelection}`;
@ -242,30 +253,22 @@ export default function ProcessInstanceList() {
initialDate: any, initialDate: any,
onChangeFunction: any onChangeFunction: any
) => { ) => {
let selectedDate = null;
if (initialDate) {
selectedDate = new Date(initialDate * 1000);
}
return ( return (
<Form.Group> <DatePicker dateFormat={DATE_FORMAT_CARBON} datePickerType="single">
<InputGroup> <DatePickerInput
<Stack className="ms-auto" direction="horizontal" gap={3}> id={`date-picker-${name}`}
<InputGroup.Text className="text-nowrap"> placeholder={DATE_FORMAT}
{labelString} labelText={labelString}
{'\u00A0'} type="text"
</InputGroup.Text> size="md"
<DatePicker autocomplete="off"
id={`date-picker-${name}`} allowInput={false}
selected={selectedDate} onChange={(dateChangeEvent: any) => {
onChange={(date: any) => onChangeFunction(dateChangeEvent.srcElement.value);
convertDateToSeconds(date, onChangeFunction) }}
} value={initialDate}
showTimeSelect />
dateFormat={DATE_FORMAT} </DatePicker>
/>
</Stack>
</InputGroup>
</Form.Group>
); );
}; };
@ -291,10 +294,8 @@ export default function ProcessInstanceList() {
const shouldFilterProcessModel = (options: any) => { const shouldFilterProcessModel = (options: any) => {
const processModel: ProcessModel = options.item; const processModel: ProcessModel = options.item;
const { inputValue } = options; const { inputValue } = options;
return ( return `${processModel.process_group_id}/${processModel.id} (${processModel.display_name})`.includes(
processModel.process_group_id.match(inputValue) || inputValue
processModel.id.match(inputValue) ||
processModel.display_name.match(inputValue)
); );
}; };
@ -305,7 +306,7 @@ export default function ProcessInstanceList() {
setProcessModelSelection(selection.selectedItem) setProcessModelSelection(selection.selectedItem)
} }
id="process-model-select" id="process-model-select"
items={processModelFilteredItems} items={processModelAvailableItems}
itemToString={(processModel: ProcessModel) => { itemToString={(processModel: ProcessModel) => {
if (processModel) { if (processModel) {
return `${processModel.process_group_id}/${ return `${processModel.process_group_id}/${
@ -344,53 +345,14 @@ export default function ProcessInstanceList() {
const clearFilters = () => { const clearFilters = () => {
setProcessModelSelection(null); setProcessModelSelection(null);
setProcessStatusSelection([]); setProcessStatusSelection([]);
setStartFrom('');
setStartTo('');
setEndFrom('');
setEndTo('');
}; };
const filterOptions = () => { const filterOptions = () => {
const { page, perPage } = getPageInfoFromSearchParams(searchParams); const { page, perPage } = getPageInfoFromSearchParams(searchParams);
// return (
// <div className="container">
// <div className="row">
// <div className="col">
// <form onSubmit={handleFilter}>
// <Stack direction="horizontal" gap={3}>
// {processModelSearch()}
// </Stack>
// <br />
// <Stack direction="horizontal" gap={3}>
// {dateComponent(
// 'Start Range: ',
// 'start-from',
// startFrom,
// setStartFrom
// )}
// {dateComponent('-', 'start-till', startTill, setStartTill)}
// </Stack>
// <br />
// <Stack direction="horizontal" gap={3}>
// {dateComponent(
// 'End Range: \u00A0\u00A0',
// 'end-from',
// endFrom,
// setEndFrom
// )}
// {dateComponent('-', 'end-till', endTill, setEndTill)}
// </Stack>
// <br />
// <Stack direction="horizontal" gap={3}>
// {processStatusSearch()}
// </Stack>
// <Stack direction="horizontal" gap={3}>
// <Button className="ms-auto" variant="secondary" type="submit">
// Filter
// </Button>
// </Stack>
// </form>
// </div>
// <div className="col" />
// </div>
// </div>
// );
return ( return (
<> <>
<Grid fullWidth className="with-bottom-margin"> <Grid fullWidth className="with-bottom-margin">
@ -398,17 +360,22 @@ export default function ProcessInstanceList() {
<Column md={8}>{processStatusSearch()}</Column> <Column md={8}>{processStatusSearch()}</Column>
</Grid> </Grid>
<Grid fullWidth className="with-bottom-margin"> <Grid fullWidth className="with-bottom-margin">
<Column md={8}> <Column md={4}>
{' '} {dateComponent(
<DatePicker dateFormat={DATE_FORMAT} datePickerType="single"> 'Start date from',
<DatePickerInput 'start-from',
id="date-picker-default-id" startFrom,
placeholder={DATE_FORMAT} setStartFrom
labelText="Date picker label" )}
type="text" </Column>
size="md" <Column md={4}>
/> {dateComponent('Start date to', 'start-to', startTo, setStartTo)}
</DatePicker> </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> </Column>
</Grid> </Grid>
<Grid fullWidth className="with-bottom-margin"> <Grid fullWidth className="with-bottom-margin">