Skip to content

Commit

Permalink
fix(viewports): format relative viewports properly
Browse files Browse the repository at this point in the history
  • Loading branch information
corteggiano committed Oct 4, 2024
1 parent 92c0bfc commit 1053666
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 12 deletions.
22 changes: 11 additions & 11 deletions packages/core-util/src/sdks/viewportAdapters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,39 @@ import {
describe('dateRangeToViewport', () => {
it('can convert a relative date range option to the correct viewport', () => {
expect(dateRangeToViewport(relativeViewportOptions[0])).toEqual({
duration: '1 minute',
duration: '1m',
});

expect(dateRangeToViewport(relativeViewportOptions[1])).toEqual({
duration: '5 minute',
duration: '5m',
});

expect(dateRangeToViewport(relativeViewportOptions[2])).toEqual({
duration: '10 minute',
duration: '10m',
});

expect(dateRangeToViewport(relativeViewportOptions[3])).toEqual({
duration: '30 minute',
duration: '30m',
});

expect(dateRangeToViewport(relativeViewportOptions[4])).toEqual({
duration: '1 hour',
duration: '1h',
});

expect(dateRangeToViewport(relativeViewportOptions[5])).toEqual({
duration: '1 day',
duration: '24h',
});

expect(dateRangeToViewport(relativeViewportOptions[6])).toEqual({
duration: '7 day',
duration: '168h',
});

expect(dateRangeToViewport(relativeViewportOptions[7])).toEqual({
duration: '30 day',
duration: '720h',
});

expect(dateRangeToViewport(relativeViewportOptions[8])).toEqual({
duration: '90 day',
duration: '2160h',
});
});

Expand All @@ -51,15 +51,15 @@ describe('dateRangeToViewport', () => {
unit: 'minute',
type: 'relative',
})
).toEqual({ duration: '20 minute' });
).toEqual({ duration: '20m' });

expect(
dateRangeToViewport({
amount: 3,
unit: 'month',
type: 'relative',
})
).toEqual({ duration: '3 month' });
).toEqual({ duration: '2160h' });
});

it('can convert an absolute date range to the correct viewport', () => {
Expand Down
60 changes: 59 additions & 1 deletion packages/core-util/src/sdks/viewportAdapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import parse from 'parse-duration';
import type { DateRangePickerProps } from '@cloudscape-design/components';
import type { Viewport } from '@iot-app-kit/core';

const DAY_MULTIPLIER = 24;
const WEEK_MULTIPLIER = DAY_MULTIPLIER * 7;
const MONTH_MULTIPLIER = DAY_MULTIPLIER * 30;
const YEAR_MULTIPLIER = MONTH_MULTIPLIER * 12;

const relativeOptionKey = (
amount: number,
unit: DateRangePickerProps.TimeUnit
Expand Down Expand Up @@ -38,17 +43,50 @@ const durationUnits = [
'month',
'year',
] as const;

type DurationUnits = (typeof durationUnits)[number];
const durationUnitToCharacter: {
[key in DurationUnits]: string;
} = {
second: 's',
minute: 'm',
hour: 'h',
day: 'd',
week: 'w',
month: 'month',
year: 'y',
};
const parseDuration = (duration: string, unit: DurationUnits) => ({
amount: parse(duration, unit),
unit,
});

const convertDurationViewportToValidViewport = (
value: DateRangePickerProps.RelativeValue
) => {
const unitCharacter = durationUnitToCharacter[value.unit];

switch (value.unit) {
case 'second':
case 'minute':
case 'hour':
return { duration: `${value.amount}${unitCharacter}` };
case 'day':
return { duration: `${value.amount * DAY_MULTIPLIER}h` };
case 'week':
return { duration: `${value.amount * WEEK_MULTIPLIER}h` };
case 'month':
return { duration: `${value.amount * MONTH_MULTIPLIER}h` };
case 'year':
return { duration: `${value.amount * YEAR_MULTIPLIER}h` };
}
};

export const dateRangeToViewport = (
value: DateRangePickerProps.Value
): Viewport => {
if (value.type === 'relative')
return { duration: `${value.amount} ${value.unit}` };
return convertDurationViewportToValidViewport(value);
return {
start: new Date(value.startDate),
end: new Date(value.endDate),
Expand Down Expand Up @@ -100,6 +138,26 @@ export const viewportToDateRange = (
({ amount, unit } = parseDuration(duration, 'minute'));
} else if (d.match(hours)) {
({ amount, unit } = parseDuration(duration, 'hour'));
if (amount) {
// if time amount in hours is perfectly divisble by any multipliers
// then we use the converted amount and the appropriate unit
if (!(amount % DAY_MULTIPLIER)) {
amount = amount / DAY_MULTIPLIER;
unit = 'day';
}
if (!(amount % WEEK_MULTIPLIER)) {
amount = amount / WEEK_MULTIPLIER;
unit = 'week';
}
if (!(amount % MONTH_MULTIPLIER)) {
amount = amount / MONTH_MULTIPLIER;
unit = 'month';
}
if (!(amount % YEAR_MULTIPLIER)) {
amount = amount / YEAR_MULTIPLIER;
unit = 'year';
}
}
} else if (d.match(days)) {
({ amount, unit } = parseDuration(duration, 'day'));
} else if (d.match(weeks)) {
Expand Down

0 comments on commit 1053666

Please sign in to comment.