UNPKG

@kelvininc/ui-components

Version:
558 lines (553 loc) 22.3 kB
'use strict'; var wizard_types = require('./wizard.types-C9Yhv1tt.js'); var date_helper = require('./date.helper-C8Apy5Qj.js'); /** * Configuration mapping for all relative time range keys. * * @remarks * Defines how each `ERelativeTimeRangeKey` should be calculated: * - Simple offsets add/subtract units from current time * - Unit reference offsets align to start/end of time units * * @see {RelativeTimeOffsetConfig} * @see {getRelativeTimeCalculation} */ const RELATIVE_TIME_OFFSETS = { [wizard_types.ERelativeTimeRangeKey.Last_5_m]: { offset: -5, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Last_10_m]: { offset: -10, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Last_15_m]: { offset: -15, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Last_30_m]: { offset: -30, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Last_1_H]: { offset: -1, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_3_H]: { offset: -3, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_6_H]: { offset: -6, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_12_H]: { offset: -12, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_24_H]: { offset: -24, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_48_H]: { offset: -48, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_72_H]: { offset: -72, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Last_3_D]: { offset: -3, unit: 'days' }, [wizard_types.ERelativeTimeRangeKey.Last_7_D]: { offset: -7, unit: 'days' }, [wizard_types.ERelativeTimeRangeKey.Last_14_D]: { offset: -14, unit: 'days' }, [wizard_types.ERelativeTimeRangeKey.Last_30_D]: { offset: -30, unit: 'days' }, [wizard_types.ERelativeTimeRangeKey.Last_90_D]: { offset: -90, unit: 'days' }, [wizard_types.ERelativeTimeRangeKey.Last_1_M]: { offset: -1, unit: 'months' }, [wizard_types.ERelativeTimeRangeKey.Last_6_M]: { offset: -6, unit: 'months' }, [wizard_types.ERelativeTimeRangeKey.Last_1_Y]: { offset: -1, unit: 'years' }, [wizard_types.ERelativeTimeRangeKey.Last_2_Y]: { offset: -2, unit: 'years' }, [wizard_types.ERelativeTimeRangeKey.Last_5_Y]: { offset: -5, unit: 'years' }, [wizard_types.ERelativeTimeRangeKey.Last_365_D]: { offset: -365, unit: 'days' }, // Special - Unit-based references [wizard_types.ERelativeTimeRangeKey.Today]: { offset: 0, unit: 'day', unitReference: wizard_types.EUnitReference.StartOfUnit }, [wizard_types.ERelativeTimeRangeKey.Yesterday]: { offset: -1, unit: 'day', unitReference: wizard_types.EUnitReference.StartOfUnit }, [wizard_types.ERelativeTimeRangeKey.Yesterday_End]: { offset: -1, unit: 'day', unitReference: wizard_types.EUnitReference.EndOfUnit }, // "So far" ranges (from start of unit to now) [wizard_types.ERelativeTimeRangeKey.This_Week_So_Far]: { offset: 0, unit: 'week', unitReference: wizard_types.EUnitReference.StartOfUnit }, [wizard_types.ERelativeTimeRangeKey.This_Month_So_Far]: { offset: 0, unit: 'month', unitReference: wizard_types.EUnitReference.StartOfUnit }, [wizard_types.ERelativeTimeRangeKey.This_Quarter_So_Far]: { offset: 0, unit: 'quarter', unitReference: wizard_types.EUnitReference.StartOfUnit }, [wizard_types.ERelativeTimeRangeKey.This_Year_So_Far]: { offset: 0, unit: 'year', unitReference: wizard_types.EUnitReference.StartOfUnit }, [wizard_types.ERelativeTimeRangeKey.Next_5_M]: { offset: 5, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Next_10_M]: { offset: 10, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Next_15_M]: { offset: 15, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Next_30_M]: { offset: 30, unit: 'minutes' }, [wizard_types.ERelativeTimeRangeKey.Next_1_H]: { offset: 1, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Next_6_H]: { offset: 6, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Next_12_H]: { offset: 12, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Next_24_H]: { offset: 24, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Next_48_H]: { offset: 48, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Next_72_H]: { offset: 72, unit: 'hours' }, [wizard_types.ERelativeTimeRangeKey.Next_7_D]: { offset: 7, unit: 'days' }, [wizard_types.ERelativeTimeRangeKey.Next_2_W]: { offset: 2, unit: 'weeks' }, [wizard_types.ERelativeTimeRangeKey.Next_1_M]: { offset: 1, unit: 'months' } }; /** Date range builders */ const buildOptionRange = (option, timeZone) => { switch (option.comparisonConfig) { case wizard_types.ERelativeTimeComparisonConfig.StartDateEndDate: return buildStartDateEndDateConfigRange(option, timeZone); case wizard_types.ERelativeTimeComparisonConfig.StartDate || wizard_types.ERelativeTimeComparisonConfig.EndDate: return buildSingleDateConfigRange(option, timeZone); case wizard_types.ERelativeTimeComparisonConfig.AbsoluteAmountOfUnits: return buildAbsoluteAmountOfUnitsConfigRange(option, timeZone); default: return buildRelativeAmountOfUnitsConfigRange(option, timeZone); } }; // Build date from config with start and end date const buildStartDateEndDateConfigRange = (option, timeZone) => { const startDateTime = date_helper.newTimezoneDateFromFormat(timeZone, option.startDate.dateFormat, option.startDate.date); const endDateTime = date_helper.newTimezoneDateFromFormat(timeZone, option.endDate.dateFormat, option.endDate.date); return buildDayjsRange(startDateTime, endDateTime); }; // Build date from config with start or end date const buildSingleDateConfigRange = (option, timeZone) => { const nowDateTime = date_helper.newTimezoneDate(timeZone); const calculatedDate = date_helper.newTimezoneDateFromFormat(timeZone, option.startDate.dateFormat, option.startDate.date); return buildDayjsRange(nowDateTime, calculatedDate); }; // Build date with both start and end date relative to now timestamp const buildAbsoluteAmountOfUnitsConfigRange = (option, timeZone) => { const nowDateTime = date_helper.newTimezoneDate(timeZone); const { unit: startDateUnit, amount: startDateAmount, unitReference: startUnitReference } = option.startDate; const { unit: endDateUnit, amount: endDateAmount, unitReference: endUnitReference } = option.endDate; const startDateTime = calculateOffsetDateWithUnitReference(date_helper.calculateOffsetDate(nowDateTime, startDateAmount, startDateUnit), startDateUnit, startUnitReference); const endDateTime = calculateOffsetDateWithUnitReference(date_helper.calculateOffsetDate(nowDateTime, endDateAmount, endDateUnit), endDateUnit, endUnitReference); return buildDayjsRange(startDateTime, endDateTime); }; // Build date with start date relative to now timestamp const buildRelativeAmountOfUnitsConfigRange = (option, timeZone) => { const nowDateTime = date_helper.newTimezoneDate(timeZone); const { amount, unit, unitReference } = option.startDate; const calculatedDate = calculateOffsetDateWithUnitReference(date_helper.calculateOffsetDate(nowDateTime, amount, unit), unit, unitReference); return buildDayjsRange(nowDateTime, calculatedDate); }; const calculateOffsetDateWithUnitReference = (date, unit, unitReference) => { if (!unitReference) { return date; } return unitReference === wizard_types.EUnitReference.StartOfUnit ? date.startOf(unit) : date.endOf(unit); }; /** * Builds the range of the start and end date and returns the range array, ordering the dates if needed * @param dateA date (start or end) * @param dateB date (start or end) * @returns range containing start date and end date ordered */ const buildDayjsRange = (dateA, dateB) => { return date_helper.isDateTimeBefore(dateA, dateB) ? [dateA, dateB] : [dateB, dateA]; }; const buildTimestampRange = ([startDate, endDate]) => [startDate.valueOf(), endDate.valueOf()]; /** * Finds a relative time option by its key from the provided options groups. * * @param key - The option key to search for * @param options - Optional: The option groups to search in (defaults to DEFAULT_RELATIVE_TIME_OPTIONS_GROUPS) * @returns The matching option or undefined */ const getRelativeTimeOption = (key, options) => (options !== null && options !== void 0 ? options : DEFAULT_RELATIVE_TIME_OPTIONS_GROUPS).flat().find(option => option.value === key); /** * Derives DateTimeCalculation configuration from a relative time range key. * This eliminates manual duplication of offset data. * * @param key - The relative time range key * @returns DateTimeCalculation object ready for use in IRelativeTimePickerOption * * @example * ```typescript * // Simple offset * getRelativeTimeCalculation(ERelativeTimeRangeKey.Last_5_m) * // Returns: { amount: -5, unit: 'minutes' } * ``` * * @example * ```typescript * // Unit reference offset * getRelativeTimeCalculation(ERelativeTimeRangeKey.Today) * // Returns: { amount: 0, unit: 'day', unitReference: EUnitReference.StartOfUnit } * ``` * * @throws {Error} If no configuration is found for the provided key */ const getRelativeTimeCalculation = (key) => { const config = RELATIVE_TIME_OFFSETS[key]; if (config === undefined) { throw new Error(`No offset configuration found for key: ${key}`); } return Object.assign({ amount: config.offset, unit: config.unit }, (config.unitReference !== undefined && { unitReference: config.unitReference })); }; /** * Builder function to create IRelativeTimePickerOption with automatic * startDate/endDate derivation from RELATIVE_TIME_OFFSETS. * * @param label - Display label for the option * @param value - Relative time range key * @param comparisonConfig - How the time calculation should be performed * @param labelRangeFormatter - Optional formatter for date range display * @param endDateKey - Optional: If provided, derives endDate from this key * @returns Complete IRelativeTimePickerOption * * @example * ```typescript * // Simple option * buildRelativeTimeOption( * 'Last 5 minutes', * ERelativeTimeRangeKey.Last_5_m, * ERelativeTimeComparisonConfig.RelativeAmountOfUnits, * { * startDateFormatter: 'HH:mm', * separator: 'to', * endDateFormatter: 'HH:mm' * } * ) * ``` * * @example * ```typescript * // Option with endDate * buildRelativeTimeOption( * 'Yesterday', * ERelativeTimeRangeKey.Yesterday, * ERelativeTimeComparisonConfig.AbsoluteAmountOfUnits, * { startDateFormatter: 'D MMM' }, * ERelativeTimeRangeKey.Yesterday_End * ) * ``` */ const buildRelativeTimeOption = (label, value, comparisonConfig, labelRangeFormatter, endDateKey) => { const option = Object.assign({ label, value, comparisonConfig, startDate: getRelativeTimeCalculation(value) }, (labelRangeFormatter !== undefined && { labelRangeFormatter })); if (endDateKey !== undefined) { option.endDate = getRelativeTimeCalculation(endDateKey); } return option; }; /** * Validates that all keys in RELATIVE_TIME_OFFSETS are valid enum values. * Useful for development/testing to ensure consistency. * * @returns true if all keys are valid * @throws {Error} If any invalid keys are found * * @example * ```typescript * // In tests or development * validateRelativeTimeOffsets(); // throws if config is invalid * ``` */ const validateRelativeTimeOffsets = () => { const enumValues = Object.values(wizard_types.ERelativeTimeRangeKey); const offsetKeys = Object.keys(RELATIVE_TIME_OFFSETS); const invalidKeys = offsetKeys.filter(key => !enumValues.includes(key)); if (invalidKeys.length > 0) { throw new Error(`Invalid keys in RELATIVE_TIME_OFFSETS: ${invalidKeys.join(', ')}`); } return true; }; /** * Default relative time option groups for the time picker component. * * @remarks * This configuration is built using the `buildRelativeTimeOption` helper to ensure * consistency with `RELATIVE_TIME_OFFSETS` and avoid data duplication. * * Organized into 5 groups: * 1. Today/Yesterday * 2. Day/Month ranges (24h, 48h, 7d, 30d, 90d, 6M) * 3. Minute/Hour ranges (5m, 15m, 30m, 1h, 3h, 6h, 12h) * 4. Long-term ranges (365d, 2y) * 5. "So far" ranges (week, month, quarter, year) */ const DEFAULT_RELATIVE_TIME_OPTIONS_GROUPS = [ [ buildRelativeTimeOption('Today', wizard_types.ERelativeTimeRangeKey.Today, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM', separator: 'until', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Yesterday', wizard_types.ERelativeTimeRangeKey.Yesterday, wizard_types.ERelativeTimeComparisonConfig.AbsoluteAmountOfUnits, { startDateFormatter: 'D MMM' }, wizard_types.ERelativeTimeRangeKey.Yesterday_End) ], [ buildRelativeTimeOption('Last 24 hours', wizard_types.ERelativeTimeRangeKey.Last_24_H, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM HH:mm', separator: 'to', endDateFormatter: 'D MMM HH:mm' }), buildRelativeTimeOption('Last 48 hours', wizard_types.ERelativeTimeRangeKey.Last_48_H, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM HH:mm', separator: 'to', endDateFormatter: 'D MMM HH:mm' }), buildRelativeTimeOption('Last 7 days', wizard_types.ERelativeTimeRangeKey.Last_7_D, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM', separator: 'to', endDateFormatter: 'D MMM' }), buildRelativeTimeOption('Last 30 days', wizard_types.ERelativeTimeRangeKey.Last_30_D, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM', separator: 'to', endDateFormatter: 'D MMM' }), buildRelativeTimeOption('Last 90 days', wizard_types.ERelativeTimeRangeKey.Last_90_D, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM', separator: 'to', endDateFormatter: 'D MMM' }), buildRelativeTimeOption('Last 6 months', wizard_types.ERelativeTimeRangeKey.Last_6_M, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM', separator: 'to', endDateFormatter: 'D MMM' }) ], [ buildRelativeTimeOption('Last 5 minutes', wizard_types.ERelativeTimeRangeKey.Last_5_m, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Last 15 minutes', wizard_types.ERelativeTimeRangeKey.Last_15_m, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Last 30 minutes', wizard_types.ERelativeTimeRangeKey.Last_30_m, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Last 1 hour', wizard_types.ERelativeTimeRangeKey.Last_1_H, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Last 3 hours', wizard_types.ERelativeTimeRangeKey.Last_3_H, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Last 6 hours', wizard_types.ERelativeTimeRangeKey.Last_6_H, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }), buildRelativeTimeOption('Last 12 hours', wizard_types.ERelativeTimeRangeKey.Last_12_H, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'HH:mm', separator: 'to', endDateFormatter: 'HH:mm' }) ], [ buildRelativeTimeOption('Last 365 days', wizard_types.ERelativeTimeRangeKey.Last_365_D, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM YYYY', separator: 'to', endDateFormatter: 'D MMM YYYY' }), buildRelativeTimeOption('Last 2 years', wizard_types.ERelativeTimeRangeKey.Last_2_Y, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM YYYY', separator: 'to', endDateFormatter: 'D MMM YYYY' }) ], [ buildRelativeTimeOption('This week so far', wizard_types.ERelativeTimeRangeKey.This_Week_So_Far, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM HH:mm', separator: 'to', endDateFormatter: 'D MMM HH:mm' }), buildRelativeTimeOption('This month so far', wizard_types.ERelativeTimeRangeKey.This_Month_So_Far, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM HH:mm', separator: 'to', endDateFormatter: 'D MMM HH:mm' }), buildRelativeTimeOption('This quarter so far', wizard_types.ERelativeTimeRangeKey.This_Quarter_So_Far, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM HH:mm', separator: 'to', endDateFormatter: 'D MMM HH:mm' }), buildRelativeTimeOption('This year so far', wizard_types.ERelativeTimeRangeKey.This_Year_So_Far, wizard_types.ERelativeTimeComparisonConfig.RelativeAmountOfUnits, { startDateFormatter: 'D MMM HH:mm', separator: 'to', endDateFormatter: 'D MMM HH:mm' }) ] ]; /** * Base helper function to calculate relative time range. * @param key the relative time key * @param cursor the relative timestamp cursor (as dayjs instance) * @returns DayjsTimeRange with start and end dates * @private */ const getRelativeTimeRange = (key, cursor) => { const { offset, unit } = RELATIVE_TIME_OFFSETS[key]; let startDate; let endDate; if (offset < 0) { startDate = date_helper.calculateOffsetDate(cursor, offset, unit); endDate = cursor; } else { endDate = date_helper.calculateOffsetDate(cursor, offset, unit); startDate = cursor; } return [startDate, endDate]; }; /** * Returns a start and end time according to a relative time range in utc. * @param key the relative time key * @param cursor the relative timestamp cursor * @returns an array with datetime strings */ const getRelativeTimeRangeISO = (key, cursor = date_helper.newDate().toISOString()) => { const cursorDate = date_helper.newDate(cursor); const [startDate, endDate] = getRelativeTimeRange(key, cursorDate); return [startDate.toISOString(), endDate.toISOString()]; }; /** * Returns a start and end time according to a relative time range as timestamps. * @param key the relative time key * @param cursor the relative timestamp cursor * @returns an array with timestamps */ const getRelativeTimeRangeTimestamp = (key, cursor = date_helper.newDate()) => { const [startDate, endDate] = getRelativeTimeRange(key, cursor); return [startDate.valueOf(), endDate.valueOf()]; }; /** * Returns the provided range in utc. * @range the absolute time range * @offset the timezone offset * @returns an array with datetime strings */ const getAbsoluteTimeRange = (range, offset = 0) => { return range.map(date => date_helper.calculateOffsetDate(date, offset, 'minutes').toISOString()); }; exports.DEFAULT_RELATIVE_TIME_OPTIONS_GROUPS = DEFAULT_RELATIVE_TIME_OPTIONS_GROUPS; exports.RELATIVE_TIME_OFFSETS = RELATIVE_TIME_OFFSETS; exports.buildAbsoluteAmountOfUnitsConfigRange = buildAbsoluteAmountOfUnitsConfigRange; exports.buildDayjsRange = buildDayjsRange; exports.buildOptionRange = buildOptionRange; exports.buildRelativeAmountOfUnitsConfigRange = buildRelativeAmountOfUnitsConfigRange; exports.buildRelativeTimeOption = buildRelativeTimeOption; exports.buildSingleDateConfigRange = buildSingleDateConfigRange; exports.buildStartDateEndDateConfigRange = buildStartDateEndDateConfigRange; exports.buildTimestampRange = buildTimestampRange; exports.getAbsoluteTimeRange = getAbsoluteTimeRange; exports.getRelativeTimeCalculation = getRelativeTimeCalculation; exports.getRelativeTimeOption = getRelativeTimeOption; exports.getRelativeTimeRangeISO = getRelativeTimeRangeISO; exports.getRelativeTimeRangeTimestamp = getRelativeTimeRangeTimestamp; exports.validateRelativeTimeOffsets = validateRelativeTimeOffsets;