Skip to content

Commit

Permalink
Provide rich Chip component for displaying date range
Browse files Browse the repository at this point in the history
Time intervals in text format are truncated which hides the end date.

Signed-off-by: Radoslaw Szwajkowski <[email protected]>
  • Loading branch information
rszwajko committed Oct 12, 2023
1 parent d030b85 commit ee48822
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 5 deletions.
40 changes: 40 additions & 0 deletions packages/common/src/components/Filter/DateRangeChip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';

import { Flex, FlexItem } from '@patternfly/react-core';

export interface DateRangeChipProps {
// ISO time interval
interval: string;
fromLabel: string;
toLabel: string;
}

export const DateRangeChip = ({ interval, fromLabel, toLabel }: DateRangeChipProps) => {
const [from, to] = interval?.split('/') ?? '';
return (
<Flex direction={{ default: 'row' }}>
<Flex
direction={{ default: 'column' }}
spaceItems={{
default: 'spaceItemsNone',
}}
>
<FlexItem>
<b>{fromLabel}</b>
</FlexItem>
<FlexItem>
<b>{toLabel}</b>
</FlexItem>
</Flex>
<Flex
direction={{ default: 'column' }}
spaceItems={{
default: 'spaceItemsNone',
}}
>
<FlexItem>{from}</FlexItem>
<FlexItem>{to}</FlexItem>
</Flex>
</Flex>
);
};
18 changes: 13 additions & 5 deletions packages/common/src/components/Filter/DateRangeFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ import {
toISODateInterval,
} from '../../utils';

import { DateRangeChip } from './DateRangeChip';
import { FilterTypeProps } from './types';

/**
* This Filter type enables selecting an exclusive date range.
* Precisely given range [A,B) a date X in the range if A <= X < B.
*
* **FilterTypeProps are interpreted as follows**:<br>
* 1) selectedFilters - date range encoded as ISO 8601 time interval string ("dateFrom/dateTo").<br>
* 1) selectedFilters - date range encoded as ISO 8601 time interval string ("dateFrom/dateTo"). Only date part is used (no time).<br>
* 2) onFilterUpdate - accepts the list of ranges.<br>
*
* [<img src="static/media/src/components-stories/assets/github-logo.svg"><i class="fi fi-brands-github">
Expand All @@ -42,22 +43,29 @@ export const DateRangeFilter = ({
const [from, setFrom] = useState<Date>();
const [to, setTo] = useState<Date>();

const rangeToOption = (range: string): string => range.replace('/', ' - ');
const optionToRange = (option: string): string => option.replace(' - ', '/');
const rangeToOption = (range: string) => {
return {
key: range,
node: <DateRangeChip interval={range} fromLabel="From" toLabel="To" />,
};
};
const optionToRange = (option): string => option?.key;

const clearSingleRange = (option) => {
const target = optionToRange(option);
onFilterUpdate([...validFilters.filter((range) => range !== target)]);
};

const onFromDateChange = (even: FormEvent<HTMLInputElement>, value: string) => {
//see DateFilter onDateChange
if (value?.length === 10 && isValidDate(value)) {
setFrom(parseISOtoJSDate(value));
setTo(undefined);
}
};

const onToDateChange = (even: FormEvent<HTMLInputElement>, value: string) => {
//see DateFilter onDateChange
if (value?.length === 10 && isValidDate(value)) {
const newTo = parseISOtoJSDate(value);
setTo(newTo);
Expand All @@ -82,7 +90,7 @@ export const DateRangeFilter = ({
dateFormat={(date) => DateTime.fromJSDate(date).toISODate()}
dateParse={(str) => DateTime.fromISO(str).toJSDate()}
onChange={onFromDateChange}
aria-label={'Interval start'}
aria-label="Interval start"
placeholder={placeholderLabel}
invalidFormatText={placeholderLabel}
// default value ("parent") creates collision with sticky table header
Expand All @@ -91,7 +99,7 @@ export const DateRangeFilter = ({
<DatePicker
value={toISODate(to)}
onChange={onToDateChange}
isDisabled={isValidJSDate(from)}
isDisabled={!isValidJSDate(from)}
rangeStart={from}
aria-label="Interval end"
placeholder={placeholderLabel}
Expand Down

0 comments on commit ee48822

Please sign in to comment.