feat: date picker v2 (#8886)

* feat: date picker v2

* feat: custom date time range history

* feat: light mode updates and interaction fixes

* fix: improve usability

* chore: add calendar, input and popover to transformIgnorePatterns

* chore: add date-fns to transformIgnorePatterns

* chore: add @signozhq/button to transformIgnorePatterns

* feat: update css variables
This commit is contained in:
Yunus M 2025-08-26 11:43:23 +05:30 committed by GitHub
parent 514bceca34
commit 2a5fb9fd6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 1538 additions and 157 deletions

View File

@ -26,7 +26,7 @@ const config: Config.InitialOptions = {
'^.+\\.(js|jsx)$': 'babel-jest', '^.+\\.(js|jsx)$': 'babel-jest',
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [
'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios|@signozhq/design-tokens|d3-interpolate|d3-color|api|@codemirror|@lezer|@marijn)/)', 'node_modules/(?!(lodash-es|react-dnd|core-dnd|@react-dnd|dnd-core|react-dnd-html5-backend|axios|@signozhq/design-tokens|@signozhq/calendar|@signozhq/input|@signozhq/popover|@signozhq/button|date-fns|d3-interpolate|d3-color|api|@codemirror|@lezer|@marijn)/)',
], ],
setupFilesAfterEnv: ['<rootDir>jest.setup.ts'], setupFilesAfterEnv: ['<rootDir>jest.setup.ts'],
testPathIgnorePatterns: ['/node_modules/', '/public/'], testPathIgnorePatterns: ['/node_modules/', '/public/'],

View File

@ -43,11 +43,14 @@
"@radix-ui/react-tooltip": "1.0.7", "@radix-ui/react-tooltip": "1.0.7",
"@sentry/react": "8.41.0", "@sentry/react": "8.41.0",
"@sentry/webpack-plugin": "2.22.6", "@sentry/webpack-plugin": "2.22.6",
"@signozhq/calendar": "0.0.0",
"@signozhq/design-tokens": "1.1.4", "@signozhq/design-tokens": "1.1.4",
"@signozhq/input": "0.0.2",
"@signozhq/popover": "0.0.0",
"@tanstack/react-table": "8.20.6", "@tanstack/react-table": "8.20.6",
"@tanstack/react-virtual": "3.11.2", "@tanstack/react-virtual": "3.11.2",
"@uiw/codemirror-theme-github": "4.24.1",
"@uiw/codemirror-theme-copilot": "4.23.11", "@uiw/codemirror-theme-copilot": "4.23.11",
"@uiw/codemirror-theme-github": "4.24.1",
"@uiw/react-codemirror": "4.23.10", "@uiw/react-codemirror": "4.23.10",
"@uiw/react-md-editor": "3.23.5", "@uiw/react-md-editor": "3.23.5",
"@visx/group": "3.3.0", "@visx/group": "3.3.0",

View File

@ -1,6 +1,16 @@
.custom-time-picker { .custom-time-picker {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.timeSelection-input {
&:hover {
border-color: #1d212d !important;
}
}
.time-input-suffix {
display: flex;
}
} }
.time-options-container { .time-options-container {
@ -135,6 +145,7 @@
align-items: center; align-items: center;
color: var(--bg-vanilla-400); color: var(--bg-vanilla-400);
gap: 6px; gap: 6px;
.timezone { .timezone {
display: flex; display: flex;
align-items: center; align-items: center;
@ -163,6 +174,27 @@
cursor: pointer; cursor: pointer;
} }
.time-input-suffix-icon-badge {
display: flex;
align-items: center;
justify-content: center;
padding: 0 4px;
border-radius: 2px;
background: rgba(171, 189, 255, 0.04);
color: var(--bg-vanilla-100);
font-size: 12px;
font-weight: 400;
line-height: 16px;
letter-spacing: -0.06px;
cursor: pointer;
height: 20px;
width: 20px;
&:hover {
background: rgba(171, 189, 255, 0.08);
}
}
.lightMode { .lightMode {
.date-time-popover__footer { .date-time-popover__footer {
border-color: var(--bg-vanilla-400); border-color: var(--bg-vanilla-400);
@ -180,8 +212,26 @@
} }
} }
} }
.custom-time-picker {
.timeSelection-input {
&:hover {
border-color: var(--bg-vanilla-300) !important;
}
}
}
.timezone-badge { .timezone-badge {
color: var(--bg-ink-100); color: var(--bg-ink-100);
background: rgb(179 179 179 / 15%); background: rgb(179 179 179 / 15%);
} }
.time-input-suffix-icon-badge {
color: var(--bg-ink-100);
background: rgb(179 179 179 / 15%);
&:hover {
background: rgb(179 179 179 / 20%);
}
}
} }

View File

@ -5,13 +5,12 @@ import './CustomTimePicker.styles.scss';
import { Input, Popover, Tooltip, Typography } from 'antd'; import { Input, Popover, Tooltip, Typography } from 'antd';
import logEvent from 'api/common/logEvent'; import logEvent from 'api/common/logEvent';
import cx from 'classnames'; import cx from 'classnames';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal'; import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { import {
CustomTimeType,
FixedDurationSuggestionOptions, FixedDurationSuggestionOptions,
Options, Options,
RelativeDurationSuggestionOptions, RelativeDurationSuggestionOptions,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config'; } from 'container/TopNav/DateTimeSelectionV2/config';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { isValidTimeFormat } from 'lib/getMinMax'; import { isValidTimeFormat } from 'lib/getMinMax';
@ -28,7 +27,10 @@ import {
useMemo, useMemo,
useState, useState,
} from 'react'; } from 'react';
import { useSelector } from 'react-redux';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
import { popupContainer } from 'utils/selectPopupContainer'; import { popupContainer } from 'utils/selectPopupContainer';
import CustomTimePickerPopoverContent from './CustomTimePickerPopoverContent'; import CustomTimePickerPopoverContent from './CustomTimePickerPopoverContent';
@ -58,10 +60,6 @@ interface CustomTimePickerProps {
setCustomDTPickerVisible?: Dispatch<SetStateAction<boolean>>; setCustomDTPickerVisible?: Dispatch<SetStateAction<boolean>>;
onCustomDateHandler?: (dateTimeRange: DateTimeRangeType) => void; onCustomDateHandler?: (dateTimeRange: DateTimeRangeType) => void;
handleGoLive?: () => void; handleGoLive?: () => void;
onTimeChange?: (
interval: Time | CustomTimeType,
dateTimeRange?: [number, number],
) => void;
} }
function CustomTimePicker({ function CustomTimePicker({
@ -79,13 +77,16 @@ function CustomTimePicker({
setCustomDTPickerVisible, setCustomDTPickerVisible,
onCustomDateHandler, onCustomDateHandler,
handleGoLive, handleGoLive,
onTimeChange,
}: CustomTimePickerProps): JSX.Element { }: CustomTimePickerProps): JSX.Element {
const [ const [
selectedTimePlaceholderValue, selectedTimePlaceholderValue,
setSelectedTimePlaceholderValue, setSelectedTimePlaceholderValue,
] = useState('Select / Enter Time Range'); ] = useState('Select / Enter Time Range');
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const [inputValue, setInputValue] = useState(''); const [inputValue, setInputValue] = useState('');
const [inputStatus, setInputStatus] = useState<'' | 'error' | 'success'>(''); const [inputStatus, setInputStatus] = useState<'' | 'error' | 'success'>('');
const [inputErrorMessage, setInputErrorMessage] = useState<string | null>( const [inputErrorMessage, setInputErrorMessage] = useState<string | null>(
@ -256,6 +257,11 @@ function CustomTimePicker({
}; };
const handleSelect = (label: string, value: string): void => { const handleSelect = (label: string, value: string): void => {
if (label === 'Custom') {
setCustomDTPickerVisible?.(true);
return;
}
onSelect(value); onSelect(value);
setSelectedTimePlaceholderValue(label); setSelectedTimePlaceholderValue(label);
setInputStatus(''); setInputStatus('');
@ -318,8 +324,23 @@ function CustomTimePicker({
); );
}; };
const getTooltipTitle = (): string => {
if (selectedTime === 'custom' && inputValue === '' && !open) {
return `${dayjs(minTime / 1000_000)
.tz(timezone.value)
.format(DATE_TIME_FORMATS.DD_MMM_YYYY_HH_MM_SS)} - ${dayjs(
maxTime / 1000_000,
)
.tz(timezone.value)
.format(DATE_TIME_FORMATS.DD_MMM_YYYY_HH_MM_SS)}`;
}
return '';
};
return ( return (
<div className="custom-time-picker"> <div className="custom-time-picker">
<Tooltip title={getTooltipTitle()} placement="top">
<Popover <Popover
className={cx( className={cx(
'timeSelection-input-container', 'timeSelection-input-container',
@ -343,7 +364,6 @@ function CustomTimePicker({
setActiveView={setActiveView} setActiveView={setActiveView}
setIsOpenedFromFooter={setIsOpenedFromFooter} setIsOpenedFromFooter={setIsOpenedFromFooter}
isOpenedFromFooter={isOpenedFromFooter} isOpenedFromFooter={isOpenedFromFooter}
onTimeChange={onTimeChange}
/> />
) : ( ) : (
content content
@ -368,20 +388,23 @@ function CustomTimePicker({
} }
value={inputValue} value={inputValue}
onFocus={handleFocus} onFocus={handleFocus}
onClick={handleFocus}
onBlur={handleBlur} onBlur={handleBlur}
onChange={handleInputChange} onChange={handleInputChange}
data-1p-ignore data-1p-ignore
prefix={ prefix={
inputValue && inputStatus === 'success' ? ( <div className="time-input-prefix">
{inputValue && inputStatus === 'success' ? (
<CheckCircle size={14} color="#51E7A8" /> <CheckCircle size={14} color="#51E7A8" />
) : ( ) : (
<Tooltip title="Enter time in format (e.g., 1m, 2h, 3d, 4w)"> <Tooltip title="Enter time in format (e.g., 1m, 2h, 3d, 4w)">
<Clock size={14} /> <Clock size={14} className="cursor-pointer" />
</Tooltip> </Tooltip>
) )}
</div>
} }
suffix={ suffix={
<> <div className="time-input-suffix">
{!!isTimezoneOverridden && activeTimezoneOffset && ( {!!isTimezoneOverridden && activeTimezoneOffset && (
<div className="timezone-badge" onClick={handleTimezoneHintClick}> <div className="timezone-badge" onClick={handleTimezoneHintClick}>
<span>{activeTimezoneOffset}</span> <span>{activeTimezoneOffset}</span>
@ -389,13 +412,17 @@ function CustomTimePicker({
)} )}
<ChevronDown <ChevronDown
size={14} size={14}
onClick={(): void => handleViewChange('datetime')} className="cursor-pointer time-input-suffix-icon-badge"
onClick={(e): void => {
e.stopPropagation();
handleViewChange('datetime');
}}
/> />
</> </div>
} }
/> />
</Popover> </Popover>
</Tooltip>
{inputStatus === 'error' && inputErrorMessage && ( {inputStatus === 'error' && inputErrorMessage && (
<Typography.Title level={5} className="valid-format-error"> <Typography.Title level={5} className="valid-format-error">
{inputErrorMessage} {inputErrorMessage}
@ -414,5 +441,4 @@ CustomTimePicker.defaultProps = {
onCustomDateHandler: noop, onCustomDateHandler: noop,
handleGoLive: noop, handleGoLive: noop,
onCustomTimeStatusUpdate: noop, onCustomTimeStatusUpdate: noop,
onTimeChange: undefined,
}; };

View File

@ -4,21 +4,22 @@ import { Color } from '@signozhq/design-tokens';
import { Button } from 'antd'; import { Button } from 'antd';
import logEvent from 'api/common/logEvent'; import logEvent from 'api/common/logEvent';
import cx from 'classnames'; import cx from 'classnames';
import DatePickerV2 from 'components/DatePickerV2/DatePickerV2';
import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal'; import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { import {
CustomTimeType,
LexicalContext, LexicalContext,
Option, Option,
RelativeDurationSuggestionOptions, RelativeDurationSuggestionOptions,
Time,
} from 'container/TopNav/DateTimeSelectionV2/config'; } from 'container/TopNav/DateTimeSelectionV2/config';
import dayjs from 'dayjs';
import { Clock, PenLine } from 'lucide-react'; import { Clock, PenLine } from 'lucide-react';
import { useTimezone } from 'providers/Timezone'; import { useTimezone } from 'providers/Timezone';
import { Dispatch, SetStateAction, useMemo } from 'react'; import { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
import { getCustomTimeRanges } from 'utils/customTimeRangeUtils';
import RangePickerModal from './RangePickerModal';
import TimezonePicker from './TimezonePicker'; import TimezonePicker from './TimezonePicker';
interface CustomTimePickerPopoverContentProps { interface CustomTimePickerPopoverContentProps {
@ -37,10 +38,14 @@ interface CustomTimePickerPopoverContentProps {
setActiveView: Dispatch<SetStateAction<'datetime' | 'timezone'>>; setActiveView: Dispatch<SetStateAction<'datetime' | 'timezone'>>;
isOpenedFromFooter: boolean; isOpenedFromFooter: boolean;
setIsOpenedFromFooter: Dispatch<SetStateAction<boolean>>; setIsOpenedFromFooter: Dispatch<SetStateAction<boolean>>;
onTimeChange?: ( }
interval: Time | CustomTimeType,
dateTimeRange?: [number, number], interface RecentlyUsedDateTimeRange {
) => void; label: string;
value: number;
timestamp: number;
from: string;
to: string;
} }
// eslint-disable-next-line sonarjs/cognitive-complexity // eslint-disable-next-line sonarjs/cognitive-complexity
@ -57,16 +62,42 @@ function CustomTimePickerPopoverContent({
setActiveView, setActiveView,
isOpenedFromFooter, isOpenedFromFooter,
setIsOpenedFromFooter, setIsOpenedFromFooter,
onTimeChange,
}: CustomTimePickerPopoverContentProps): JSX.Element { }: CustomTimePickerPopoverContentProps): JSX.Element {
const { pathname } = useLocation(); const { pathname } = useLocation();
const isLogsExplorerPage = useMemo(() => pathname === ROUTES.LOGS_EXPLORER, [ const isLogsExplorerPage = useMemo(() => pathname === ROUTES.LOGS_EXPLORER, [
pathname, pathname,
]); ]);
const { timezone } = useTimezone(); const { timezone } = useTimezone();
const activeTimezoneOffset = timezone.offset; const activeTimezoneOffset = timezone.offset;
const [recentlyUsedTimeRanges, setRecentlyUsedTimeRanges] = useState<
RecentlyUsedDateTimeRange[]
>([]);
useEffect(() => {
if (!customDateTimeVisible) {
const customTimeRanges = getCustomTimeRanges();
const formattedCustomTimeRanges: RecentlyUsedDateTimeRange[] = customTimeRanges.map(
(range) => ({
label: `${dayjs(range.from)
.tz(timezone.value)
.format(DATE_TIME_FORMATS.DD_MMM_YYYY_HH_MM_SS)} - ${dayjs(range.to)
.tz(timezone.value)
.format(DATE_TIME_FORMATS.DD_MMM_YYYY_HH_MM_SS)}`,
from: range.from,
to: range.to,
value: range.timestamp,
timestamp: range.timestamp,
}),
);
setRecentlyUsedTimeRanges(formattedCustomTimeRanges);
}
}, [customDateTimeVisible, timezone.value]);
function getTimeChips(options: Option[]): JSX.Element { function getTimeChips(options: Option[]): JSX.Element {
return ( return (
<div className="relative-date-time-section"> <div className="relative-date-time-section">
@ -112,6 +143,7 @@ function CustomTimePickerPopoverContent({
return ( return (
<> <>
<div className="date-time-popover"> <div className="date-time-popover">
{!customDateTimeVisible && (
<div className="date-time-options"> <div className="date-time-options">
{isLogsExplorerPage && ( {isLogsExplorerPage && (
<Button className="data-time-live" type="text" onClick={handleGoLive}> <Button className="data-time-live" type="text" onClick={handleGoLive}>
@ -136,27 +168,53 @@ function CustomTimePickerPopoverContent({
</Button> </Button>
))} ))}
</div> </div>
)}
<div <div
className={cx( className={cx(
'relative-date-time', 'relative-date-time',
selectedTime === 'custom' || customDateTimeVisible customDateTimeVisible ? 'date-picker' : 'relative-times',
? 'date-picker'
: 'relative-times',
)} )}
> >
{selectedTime === 'custom' || customDateTimeVisible ? ( {customDateTimeVisible ? (
<RangePickerModal <DatePickerV2
setCustomDTPickerVisible={setCustomDTPickerVisible} onSetCustomDTPickerVisible={setCustomDTPickerVisible}
setIsOpen={setIsOpen} setIsOpen={setIsOpen}
onCustomDateHandler={onCustomDateHandler} onCustomDateHandler={onCustomDateHandler}
selectedTime={selectedTime}
onTimeChange={onTimeChange}
/> />
) : ( ) : (
<div className="time-selector-container">
<div className="relative-times-container"> <div className="relative-times-container">
<div className="time-heading">RELATIVE TIMES</div> <div className="time-heading">RELATIVE TIMES</div>
<div>{getTimeChips(RelativeDurationSuggestionOptions)}</div> <div>{getTimeChips(RelativeDurationSuggestionOptions)}</div>
</div> </div>
<div className="recently-used-container">
<div className="time-heading">RECENTLY USED</div>
<div className="recently-used-range">
{recentlyUsedTimeRanges.map((range: RecentlyUsedDateTimeRange) => (
<div
className="recently-used-range-item"
role="button"
tabIndex={0}
onKeyDown={(e): void => {
if (e.key === 'Enter' || e.key === ' ') {
onCustomDateHandler([dayjs(range.from), dayjs(range.to)]);
setIsOpen(false);
}
}}
key={range.value}
onClick={(): void => {
onCustomDateHandler([dayjs(range.from), dayjs(range.to)]);
setIsOpen(false);
}}
>
{range.label}
</div>
))}
</div>
</div>
</div>
)} )}
</div> </div>
</div> </div>
@ -189,8 +247,4 @@ function CustomTimePickerPopoverContent({
); );
} }
CustomTimePickerPopoverContent.defaultProps = {
onTimeChange: undefined,
};
export default CustomTimePickerPopoverContent; export default CustomTimePickerPopoverContent;

View File

@ -0,0 +1,114 @@
.date-picker-v2-container {
display: flex;
flex-direction: row;
}
.custom-date-time-picker-v2 {
padding: 12px;
.periscope-calendar {
border-radius: 4px;
border: none !important;
background: none !important;
padding: 8px 0 !important;
}
.periscope-calendar-day {
background: none !important;
&.periscope-calendar-today {
&.text-accent-foreground {
color: var(--bg-vanilla-100) !important;
}
}
button {
&:hover {
background-color: var(--bg-robin-500) !important;
color: var(--bg-vanilla-100) !important;
}
}
}
.custom-time-selector {
display: flex;
flex-direction: row;
gap: 16px;
align-items: center;
justify-content: space-between;
.time-input {
border-radius: 4px;
border: none !important;
background: none !important;
padding: 8px 4px !important;
color: var(--bg-vanilla-100) !important;
&::-webkit-calendar-picker-indicator {
display: none !important;
-webkit-appearance: none;
appearance: none;
}
&:focus {
border: none !important;
outline: none !important;
box-shadow: none !important;
}
&:focus-visible {
border: none !important;
outline: none !important;
box-shadow: none !important;
}
}
}
.custom-date-time-picker-footer {
display: flex;
flex-direction: row;
gap: 8px;
align-items: center;
justify-content: flex-end;
margin-top: 16px;
.next-btn {
width: 80px;
}
.clear-btn {
width: 80px;
}
}
}
.invalid-date-range-tooltip {
.ant-tooltip-inner {
color: var(--bg-sakura-500) !important;
}
}
.lightMode {
.custom-date-time-picker-v2 {
.periscope-calendar-day {
&.periscope-calendar-today {
&.text-accent-foreground {
color: var(--bg-ink-500) !important;
}
}
button {
&:hover {
background-color: var(--bg-robin-500) !important;
color: var(--bg-ink-500) !important;
}
}
}
.custom-time-selector {
.time-input {
color: var(--bg-ink-500) !important;
}
}
}
}

View File

@ -0,0 +1,311 @@
import './DatePickerV2.styles.scss';
import { Calendar } from '@signozhq/calendar';
import { Input } from '@signozhq/input';
import { Button, Tooltip } from 'antd';
import cx from 'classnames';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { LexicalContext } from 'container/TopNav/DateTimeSelectionV2/config';
import dayjs, { Dayjs } from 'dayjs';
import { CornerUpLeft, MoveRight } from 'lucide-react';
import { useTimezone } from 'providers/Timezone';
import { useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { GlobalReducer } from 'types/reducer/globalTime';
import { addCustomTimeRange } from 'utils/customTimeRangeUtils';
function DatePickerV2({
onSetCustomDTPickerVisible,
setIsOpen,
onCustomDateHandler,
}: {
onSetCustomDTPickerVisible: (visible: boolean) => void;
setIsOpen: (isOpen: boolean) => void;
onCustomDateHandler: (
dateTimeRange: DateTimeRangeType,
lexicalContext?: LexicalContext,
) => void;
}): JSX.Element {
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const timeInputRef = useRef<HTMLInputElement>(null);
const { timezone } = useTimezone();
const [selectedDateTimeFor, setSelectedDateTimeFor] = useState<'to' | 'from'>(
'from',
);
const [selectedFromDateTime, setSelectedFromDateTime] = useState<Dayjs | null>(
dayjs(minTime / 1000_000).tz(timezone.value),
);
const [selectedToDateTime, setSelectedToDateTime] = useState<Dayjs | null>(
dayjs(maxTime / 1000_000).tz(timezone.value),
);
const handleNext = (): void => {
if (selectedDateTimeFor === 'to') {
onCustomDateHandler([selectedFromDateTime, selectedToDateTime]);
addCustomTimeRange([selectedFromDateTime, selectedToDateTime]);
setIsOpen(false);
onSetCustomDTPickerVisible(false);
setSelectedDateTimeFor('from');
} else {
setSelectedDateTimeFor('to');
}
};
const handleDateChange = (date: Date | undefined): void => {
if (!date) {
return;
}
if (selectedDateTimeFor === 'from') {
const prevFromDateTime = selectedFromDateTime;
const newDate = dayjs(date);
const updatedFromDateTime = prevFromDateTime
? prevFromDateTime
.year(newDate.year())
.month(newDate.month())
.date(newDate.date())
: dayjs(date).tz(timezone.value);
setSelectedFromDateTime(updatedFromDateTime);
} else {
// eslint-disable-next-line sonarjs/no-identical-functions
setSelectedToDateTime((prev) => {
const newDate = dayjs(date);
// Update only the date part, keeping time from existing state
return prev
? prev.year(newDate.year()).month(newDate.month()).date(newDate.date())
: dayjs(date).tz(timezone.value);
});
}
// focus the time input
timeInputRef?.current?.focus();
};
const handleTimeChange = (time: string): void => {
// time should have format HH:mm:ss
if (!/^\d{2}:\d{2}:\d{2}$/.test(time)) {
return;
}
if (selectedDateTimeFor === 'from') {
setSelectedFromDateTime((prev) => {
if (prev) {
return prev
.set('hour', parseInt(time.split(':')[0], 10))
.set('minute', parseInt(time.split(':')[1], 10))
.set('second', parseInt(time.split(':')[2], 10));
}
return prev;
});
}
if (selectedDateTimeFor === 'to') {
// eslint-disable-next-line sonarjs/no-identical-functions
setSelectedToDateTime((prev) => {
if (prev) {
return prev
.set('hour', parseInt(time.split(':')[0], 10))
.set('minute', parseInt(time.split(':')[1], 10))
.set('second', parseInt(time.split(':')[2], 10));
}
return prev;
});
}
};
const getDefaultMonth = (): Date => {
let defaultDate = null;
if (selectedDateTimeFor === 'from') {
defaultDate = selectedFromDateTime?.toDate();
} else if (selectedDateTimeFor === 'to') {
defaultDate = selectedToDateTime?.toDate();
}
return defaultDate ?? new Date();
};
const isValidRange = (): boolean => {
if (selectedDateTimeFor === 'to') {
return selectedToDateTime?.isAfter(selectedFromDateTime) ?? false;
}
return true;
};
const handleBack = (): void => {
setSelectedDateTimeFor('from');
};
const handleHideCustomDTPicker = (): void => {
onSetCustomDTPickerVisible(false);
};
const handleSelectDateTimeFor = (selectedDateTimeFor: 'to' | 'from'): void => {
setSelectedDateTimeFor(selectedDateTimeFor);
};
return (
<div className="date-picker-v2-container">
<div className="date-time-custom-options-container">
<div
className="back-btn"
onClick={handleHideCustomDTPicker}
role="button"
tabIndex={0}
onKeyDown={(e): void => {
if (e.key === 'Enter') {
handleHideCustomDTPicker();
}
}}
>
<CornerUpLeft size={16} />
<span>Back</span>
</div>
<div className="date-time-custom-options">
<div
role="button"
tabIndex={0}
onKeyDown={(e): void => {
if (e.key === 'Enter') {
handleSelectDateTimeFor('from');
}
}}
className={cx(
'date-time-custom-option-from',
selectedDateTimeFor === 'from' && 'active',
)}
onClick={(): void => {
handleSelectDateTimeFor('from');
}}
>
<div className="date-time-custom-option-from-title">FROM</div>
<div className="date-time-custom-option-from-value">
{selectedFromDateTime?.format('YYYY-MM-DD HH:mm:ss')}
</div>
</div>
<div
role="button"
tabIndex={0}
onKeyDown={(e): void => {
if (e.key === 'Enter') {
handleSelectDateTimeFor('to');
}
}}
className={cx(
'date-time-custom-option-to',
selectedDateTimeFor === 'to' && 'active',
)}
onClick={(): void => {
handleSelectDateTimeFor('to');
}}
>
<div className="date-time-custom-option-to-title">TO</div>
<div className="date-time-custom-option-to-value">
{selectedToDateTime?.format('YYYY-MM-DD HH:mm:ss')}
</div>
</div>
</div>
</div>
<div className="custom-date-time-picker-v2">
<Calendar
mode="single"
required
selected={
selectedDateTimeFor === 'from'
? selectedFromDateTime?.toDate()
: selectedToDateTime?.toDate()
}
key={selectedDateTimeFor + selectedDateTimeFor}
onSelect={handleDateChange}
defaultMonth={getDefaultMonth()}
disabled={(current): boolean => {
if (selectedDateTimeFor === 'to') {
// disable dates after today and before selectedFromDateTime
const currentDay = dayjs(current);
return currentDay.isAfter(dayjs()) || false;
}
if (selectedDateTimeFor === 'from') {
// disable dates after selectedToDateTime
return dayjs(current).isAfter(dayjs()) || false;
}
return false;
}}
className="rounded-md border"
navLayout="after"
/>
<div className="custom-time-selector">
<label className="text-xs font-normal block" htmlFor="time-picker">
Timestamp
</label>
<MoveRight size={16} />
<div className="time-input-container">
<Input
type="time"
ref={timeInputRef}
className="time-input"
value={
selectedDateTimeFor === 'from'
? selectedFromDateTime?.format('HH:mm:ss')
: selectedToDateTime?.format('HH:mm:ss')
}
onChange={(e): void => handleTimeChange(e.target.value)}
step="1"
/>
</div>
</div>
<div className="custom-date-time-picker-footer">
{selectedDateTimeFor === 'to' && (
<Button
className="periscope-btn secondary clear-btn"
type="default"
onClick={handleBack}
>
Back
</Button>
)}
<Tooltip
title={
!isValidRange() ? 'Invalid range: TO date should be after FROM date' : ''
}
overlayClassName="invalid-date-range-tooltip"
>
<Button
className="periscope-btn primary next-btn"
type="primary"
onClick={handleNext}
disabled={!isValidRange()}
>
{selectedDateTimeFor === 'from' ? 'Next' : 'Apply'}
</Button>
</Tooltip>
</div>
</div>
</div>
);
}
export default DatePickerV2;

View File

@ -39,6 +39,8 @@ export const DATE_TIME_FORMATS = {
MONTH_DATETIME_SECONDS: 'MMM DD YYYY HH:mm:ss', MONTH_DATETIME_SECONDS: 'MMM DD YYYY HH:mm:ss',
MONTH_DATETIME_FULL: 'MMMM DD, YYYY HH:mm', MONTH_DATETIME_FULL: 'MMMM DD, YYYY HH:mm',
MONTH_DATETIME_FULL_SECONDS: 'MMM DD, YYYY, HH:mm:ss', MONTH_DATETIME_FULL_SECONDS: 'MMM DD, YYYY, HH:mm:ss',
DD_MMM_YYYY_HH_MM: 'DD MMM YYYY, HH:mm',
DD_MMM_YYYY_HH_MM_SS: 'DD MMM YYYY, HH:mm:ss',
// Ordinal formats (1st, 2nd, 3rd, etc) // Ordinal formats (1st, 2nd, 3rd, etc)
ORDINAL_DATE: 'Do MMM YYYY', ORDINAL_DATE: 'Do MMM YYYY',

View File

@ -32,4 +32,5 @@ export enum LOCALSTORAGE {
BANNER_DISMISSED = 'BANNER_DISMISSED', BANNER_DISMISSED = 'BANNER_DISMISSED',
QUICK_FILTERS_SETTINGS_ANNOUNCEMENT = 'QUICK_FILTERS_SETTINGS_ANNOUNCEMENT', QUICK_FILTERS_SETTINGS_ANNOUNCEMENT = 'QUICK_FILTERS_SETTINGS_ANNOUNCEMENT',
FUNNEL_STEPS = 'FUNNEL_STEPS', FUNNEL_STEPS = 'FUNNEL_STEPS',
LAST_USED_CUSTOM_TIME_RANGES = 'LAST_USED_CUSTOM_TIME_RANGES',
} }

View File

@ -54,7 +54,7 @@
border: none; border: none;
&.active-tab { &.active-tab {
background-color: #1d212d; background-color: var(--bg-slate-400);
} }
} }
} }
@ -146,20 +146,20 @@
display: flex; display: flex;
width: 224px; width: 224px;
flex-direction: column; flex-direction: column;
border-right: 1px solid #1d212d; border-right: 1px solid var(--bg-slate-400);
.data-time-live { .data-time-live {
border-bottom: 1px solid #1d212d; border-bottom: 1px solid var(--bg-slate-400);
text-align: start; text-align: start;
padding: 13.5px 14px; padding: 13.5px 14px;
height: 44px; height: 44px;
color: var(--bg-vanilla-400, #c0c1c3); color: var(--bg-vanilla-400);
font-size: 14px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: normal; line-height: normal;
letter-spacing: 0.14px; letter-spacing: 0.14px;
border-bottom: 1px solid var(--bg-slate-400, #1d212d); border-bottom: 1px solid var(--bg-slate-400);
} }
.active { .active {
@ -176,8 +176,8 @@
text-align: start; text-align: start;
padding: 8px 13px; padding: 8px 13px;
height: 37px; height: 37px;
color: var(--bg-vanilla-400, #c0c1c3); color: var(--bg-vanilla-400);
font-size: 14px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: normal; line-height: normal;
@ -190,6 +190,80 @@
} }
} }
.date-time-custom-options-container {
display: flex;
width: 224px;
flex-direction: column;
border-right: 1px solid var(--bg-slate-400);
.back-btn {
display: flex;
align-items: center;
gap: 16px;
padding: 8px;
cursor: pointer;
&:hover {
background-color: rgba(171, 189, 255, 0.04);
}
}
.date-time-custom-options {
.date-time-custom-option-from,
.date-time-custom-option-to {
display: flex;
padding: 12px 14px;
flex-direction: column;
align-items: flex-start;
gap: 10px;
cursor: pointer;
&.disabled {
cursor: not-allowed;
}
.date-time-custom-option-from-title,
.date-time-custom-option-to-title {
color: var(--bg-slate-50);
font-variant-numeric: slashed-zero;
font-family: Inter;
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: normal;
letter-spacing: 0.12px;
text-transform: uppercase;
}
.date-time-custom-option-from-value,
.date-time-custom-option-to-value {
color: var(--bg-vanilla-400);
font-variant-numeric: slashed-zero;
font-family: Inter;
font-size: 13px;
font-style: normal;
font-weight: 300;
line-height: normal;
letter-spacing: 0.14px;
}
&.active {
background: rgba(171, 189, 255, 0.04);
.date-time-custom-option-from-title,
.date-time-custom-option-to-title {
color: var(--bg-vanilla-400);
}
.date-time-custom-option-from-value,
.date-time-custom-option-to-value {
color: var(--bg-vanilla-100);
}
}
}
}
}
.relative-date-time { .relative-date-time {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -197,12 +271,11 @@
padding: 13px 14px; padding: 13px 14px;
&.date-picker { &.date-picker {
width: 480px; padding: 0px;
height: 430px;
} }
&.relative-times { &.relative-times {
width: 320px; width: 360px;
} }
.relative-date-time-section { .relative-date-time-section {
@ -210,9 +283,45 @@
gap: 6px; gap: 6px;
flex-flow: wrap; flex-flow: wrap;
} }
.time-selector-container {
display: flex;
flex-direction: column;
gap: 32px;
}
.recently-used-container {
display: flex;
flex-direction: column;
gap: 8px;
.recently-used-range {
display: flex;
flex-direction: column;
gap: 8px;
.recently-used-range-item {
color: var(--bg-vanilla-400);
background-color: var(--bg-ink-200);
font-size: 12px;
line-height: 16px;
letter-spacing: 0.04em;
text-align: left;
border-radius: 2px;
padding: 8px;
cursor: pointer;
&:hover {
background-color: var(--bg-ink-100);
color: var(--bg-vanilla-100);
}
}
}
}
.time-heading { .time-heading {
text-align: left; text-align: left;
color: var(--bg-slate-200); color: var(--bg-vanilla-300);
font-size: 11px; font-size: 11px;
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
@ -224,8 +333,8 @@
.time-btns { .time-btns {
color: var(--bg-vanilla-400); color: var(--bg-vanilla-400);
background-color: #23262e; background-color: #23262e;
font-size: 14px; font-size: 12px;
line-height: 17px; line-height: 16px;
letter-spacing: 0.04em; letter-spacing: 0.04em;
text-align: left; text-align: left;
border-radius: 2px; border-radius: 2px;
@ -288,6 +397,54 @@
} }
} }
.date-time-custom-options-container {
display: flex;
width: 224px;
flex-direction: column;
border-right: 1px solid var(--bg-vanilla-400);
.back-btn {
display: flex;
align-items: center;
gap: 16px;
padding: 8px;
cursor: pointer;
&:hover {
background-color: var(--bg-vanilla-300);
}
}
.date-time-custom-options {
.date-time-custom-option-from,
.date-time-custom-option-to {
.date-time-custom-option-from-title,
.date-time-custom-option-to-title {
color: var(--bg-slate-50);
}
.date-time-custom-option-from-value,
.date-time-custom-option-to-value {
color: var(--bg-slate-400);
}
&.active {
background: var(--bg-vanilla-300);
.date-time-custom-option-from-title,
.date-time-custom-option-to-title {
color: var(--bg-slate-400);
}
.date-time-custom-option-from-value,
.date-time-custom-option-to-value {
color: var(--bg-slate-400);
}
}
}
}
}
.relative-date-time { .relative-date-time {
.time-heading { .time-heading {
color: var(--bg-vanilla-400); color: var(--bg-vanilla-400);
@ -297,6 +454,20 @@
background-color: var(--bg-vanilla-300); background-color: var(--bg-vanilla-300);
color: var(--bg-slate-400); color: var(--bg-slate-400);
} }
.recently-used-container {
.recently-used-range {
.recently-used-range-item {
color: var(--bg-slate-400);
background-color: var(--bg-vanilla-300);
&:hover {
background-color: var(--bg-vanilla-300);
color: var(--bg-slate-400);
}
}
}
}
} }
} }

View File

@ -248,7 +248,7 @@ function DateTimeSelection({
timeInterval: Time | CustomTimeType = '15m', timeInterval: Time | CustomTimeType = '15m',
): string | Time => { ): string | Time => {
if (startTime && endTime && timeInterval === 'custom') { if (startTime && endTime && timeInterval === 'custom') {
const format = DATE_TIME_FORMATS.UK_DATETIME; const format = DATE_TIME_FORMATS.UK_DATETIME_SECONDS;
const startString = startTime.format(format); const startString = startTime.format(format);
const endString = endTime.format(format); const endString = endTime.format(format);
@ -803,6 +803,17 @@ function DateTimeSelection({
const { timezone } = useTimezone(); const { timezone } = useTimezone();
const getSelectedValue = (): string =>
getInputLabel(
dayjs(isModalTimeSelection ? modalStartTime : minTime / 1000000).tz(
timezone.value,
),
dayjs(isModalTimeSelection ? modalEndTime : maxTime / 1000000).tz(
timezone.value,
),
isModalTimeSelection ? modalSelectedInterval : selectedTime,
);
return ( return (
<div className="date-time-selector"> <div className="date-time-selector">
{showResetButton && selectedTime !== defaultRelativeTime && ( {showResetButton && selectedTime !== defaultRelativeTime && (
@ -859,15 +870,7 @@ function DateTimeSelection({
onCustomTimeStatusUpdate={(isValid: boolean): void => { onCustomTimeStatusUpdate={(isValid: boolean): void => {
setIsValidteRelativeTime(isValid); setIsValidteRelativeTime(isValid);
}} }}
selectedValue={getInputLabel( selectedValue={getSelectedValue()}
dayjs(isModalTimeSelection ? modalStartTime : minTime / 1000000).tz(
timezone.value,
),
dayjs(isModalTimeSelection ? modalEndTime : maxTime / 1000000).tz(
timezone.value,
),
isModalTimeSelection ? modalSelectedInterval : selectedTime,
)}
data-testid="dropDown" data-testid="dropDown"
items={options} items={options}
newPopover newPopover
@ -875,7 +878,6 @@ function DateTimeSelection({
onCustomDateHandler={onCustomDateHandler} onCustomDateHandler={onCustomDateHandler}
customDateTimeVisible={customDateTimeVisible} customDateTimeVisible={customDateTimeVisible}
setCustomDTPickerVisible={setCustomDTPickerVisible} setCustomDTPickerVisible={setCustomDTPickerVisible}
onTimeChange={onTimeChange}
/> />
{showAutoRefresh && selectedTime !== 'custom' && ( {showAutoRefresh && selectedTime !== 'custom' && (

View File

@ -0,0 +1,112 @@
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import { useCallback, useEffect, useState } from 'react';
import {
addCustomTimeRange as addRange,
clearCustomTimeRanges as clearRanges,
CustomTimeRange,
getCustomTimeRanges as getRanges,
removeCustomTimeRange as removeRange,
} from 'utils/customTimeRangeUtils';
/**
* Custom hook for managing the last 3 used custom time ranges
* @returns Object containing custom time ranges and management functions
*/
export const useCustomTimeRanges = (): {
customTimeRanges: CustomTimeRange[];
addCustomTimeRange: (dateTimeRange: DateTimeRangeType) => CustomTimeRange[];
removeCustomTimeRange: (timestamp: number) => CustomTimeRange[];
clearCustomTimeRanges: () => void;
isCustomTimeRangeExists: (dateTimeRange: DateTimeRangeType) => boolean;
refreshCustomTimeRanges: () => void;
} => {
const [customTimeRanges, setCustomTimeRanges] = useState<CustomTimeRange[]>(
[],
);
// Always get the latest data from localStorage
const getLatestRanges = useCallback((): CustomTimeRange[] => getRanges(), []);
// Load initial data from localStorage
useEffect(() => {
const ranges = getLatestRanges();
setCustomTimeRanges(ranges);
}, [getLatestRanges]);
/**
* Adds a new custom time range to the stored list
* @param dateTimeRange - The DateTimeRangeType from the time picker
* @returns The updated list of custom time ranges
*/
const addCustomTimeRange = useCallback(
(dateTimeRange: DateTimeRangeType): CustomTimeRange[] => {
const updatedRanges = addRange(dateTimeRange);
setCustomTimeRanges(updatedRanges);
return updatedRanges;
},
[],
);
/**
* Removes a specific custom time range by its timestamp
* @param timestamp - The timestamp of the range to remove
* @returns The updated list of custom time ranges
*/
const removeCustomTimeRange = useCallback(
(timestamp: number): CustomTimeRange[] => {
const updatedRanges = removeRange(timestamp);
setCustomTimeRanges(updatedRanges);
return updatedRanges;
},
[],
);
/**
* Clears all stored custom time ranges
*/
const clearCustomTimeRanges = useCallback((): void => {
clearRanges();
setCustomTimeRanges([]);
}, []);
/**
* Checks if a time range already exists in the stored list
* @param dateTimeRange - The DateTimeRangeType to check
* @returns True if the range already exists
*/
const isCustomTimeRangeExists = useCallback(
(dateTimeRange: DateTimeRangeType): boolean => {
if (!dateTimeRange || !dateTimeRange[0] || !dateTimeRange[1]) {
return false;
}
const [startTime, endTime] = dateTimeRange;
// Always fetch latest data from localStorage
const latestRanges = getLatestRanges();
return latestRanges.some(
(range) =>
range.from === startTime.toISOString() &&
range.to === endTime.toISOString(),
);
},
[getLatestRanges],
);
/**
* Refreshes the custom time ranges from localStorage
* Useful when you want to sync with changes made outside the hook
*/
const refreshCustomTimeRanges = useCallback((): void => {
const ranges = getLatestRanges();
setCustomTimeRanges(ranges);
}, [getLatestRanges]);
return {
customTimeRanges,
addCustomTimeRange,
removeCustomTimeRange,
clearCustomTimeRanges,
isCustomTimeRangeExists,
refreshCustomTimeRanges,
};
};

View File

@ -755,3 +755,7 @@ notifications - 2050
.service-map-container { .service-map-container {
padding: 0px 8px; padding: 0px 8px;
} }
.cursor-pointer {
cursor: pointer;
}

View File

@ -0,0 +1,175 @@
import { LOCALSTORAGE } from 'constants/localStorage';
import { DateTimeRangeType } from 'container/TopNav/CustomDateTimeModal';
import dayjs from 'dayjs';
export interface CustomTimeRange {
from: string; // ISO string format
to: string; // ISO string format
timestamp: number; // When this range was created/used
}
const MAX_STORED_RANGES = 3;
/**
* Retrieves the list of stored custom time ranges
* @returns Array of CustomTimeRange objects
*/
export const getCustomTimeRanges = (): CustomTimeRange[] => {
try {
const stored = localStorage.getItem(
LOCALSTORAGE.LAST_USED_CUSTOM_TIME_RANGES,
);
if (!stored) return [];
const parsed = JSON.parse(stored);
// Validate stored data
if (Array.isArray(parsed)) {
return parsed.filter((item) => item && item.from && item.to);
}
return [];
} catch (error) {
console.warn(
'Failed to retrieve custom time ranges from localStorage:',
error,
);
return [];
}
};
/**
* Adds a new custom time range to the stored list, maintaining only the last 3 used ranges
* @param dateTimeRange - The DateTimeRangeType from the time picker
* @returns The updated list of custom time ranges
*/
export const addCustomTimeRange = (
dateTimeRange: DateTimeRangeType,
): CustomTimeRange[] => {
if (!dateTimeRange || !dateTimeRange[0] || !dateTimeRange[1]) {
return getCustomTimeRanges();
}
const [startTime, endTime] = dateTimeRange;
const now = dayjs();
const newRange: CustomTimeRange = {
from: startTime.toISOString(),
to: endTime.toISOString(),
timestamp: now.unix(),
};
// Get existing ranges
const existingRanges = getCustomTimeRanges();
// Remove duplicate ranges (same start and end time)
const filteredRanges = existingRanges.filter(
(range) =>
range.from !== startTime.toISOString() || range.to !== endTime.toISOString(),
);
// Add new range at the beginning (most recent)
const updatedRanges = [newRange, ...filteredRanges].slice(
0,
MAX_STORED_RANGES,
);
// Store in localStorage
try {
localStorage.setItem(
LOCALSTORAGE.LAST_USED_CUSTOM_TIME_RANGES,
JSON.stringify(updatedRanges),
);
} catch (error) {
console.warn('Failed to save custom time range to localStorage:', error);
}
return updatedRanges;
};
/**
* Clears all stored custom time ranges
*/
export const clearCustomTimeRanges = (): void => {
try {
localStorage.removeItem(LOCALSTORAGE.LAST_USED_CUSTOM_TIME_RANGES);
} catch (error) {
console.warn('Failed to clear custom time ranges from localStorage:', error);
}
};
/**
* Removes a specific custom time range by its timestamp
* @param timestamp - The timestamp of the range to remove
* @returns The updated list of custom time ranges
*/
export const removeCustomTimeRange = (timestamp: number): CustomTimeRange[] => {
const existingRanges = getCustomTimeRanges();
const updatedRanges = existingRanges.filter(
(range) => range.timestamp !== timestamp,
);
try {
localStorage.setItem(
LOCALSTORAGE.LAST_USED_CUSTOM_TIME_RANGES,
JSON.stringify(updatedRanges),
);
} catch (error) {
console.warn('Failed to update custom time ranges in localStorage:', error);
}
return updatedRanges;
};
/**
* Checks if a time range already exists in the stored list
* @param dateTimeRange - The DateTimeRangeType to check
* @returns True if the range already exists
*/
export const isCustomTimeRangeExists = (
dateTimeRange: DateTimeRangeType,
): boolean => {
if (!dateTimeRange || !dateTimeRange[0] || !dateTimeRange[1]) {
return false;
}
const [startTime, endTime] = dateTimeRange;
const existingRanges = getCustomTimeRanges();
return existingRanges.some(
(range) =>
range.from === startTime.toISOString() && range.to === endTime.toISOString(),
);
};
/**
* Converts a CustomTimeRange to DateTimeRangeType
* @param customRange - The CustomTimeRange to convert
* @returns DateTimeRangeType
*/
export const convertCustomRangeToDateTimeRange = (
customRange: CustomTimeRange,
): DateTimeRangeType => [dayjs(customRange.from), dayjs(customRange.to)];
/**
* Converts a DateTimeRangeType to CustomTimeRange format
* @param dateTimeRange - The DateTimeRangeType to convert
* @param label - Optional label, will be auto-generated if not provided
* @returns CustomTimeRange
*/
export const convertDateTimeRangeToCustomRange = (
dateTimeRange: DateTimeRangeType,
): CustomTimeRange | null => {
if (!dateTimeRange || !dateTimeRange[0] || !dateTimeRange[1]) {
return null;
}
const [startTime, endTime] = dateTimeRange;
return {
from: startTime.toISOString(),
to: endTime.toISOString(),
timestamp: Date.now(),
};
};

View File

@ -128,7 +128,6 @@ export const secondsToMilliseconds = (seconds: number): number =>
seconds * 1_000; seconds * 1_000;
export const epochToTimeString = (epochMs: number): string => { export const epochToTimeString = (epochMs: number): string => {
console.log({ epochMs });
const date = new Date(epochMs); const date = new Date(epochMs);
const options: Intl.DateTimeFormatOptions = { const options: Intl.DateTimeFormatOptions = {
hour: '2-digit', hour: '2-digit',

View File

@ -2578,6 +2578,11 @@
resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31" resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz#b6c75a56a1947cc916ea058772d666a2c8932f31"
integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA== integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==
"@date-fns/tz@^1.4.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@date-fns/tz/-/tz-1.4.1.tgz#2d905f282304630e07bef6d02d2e7dbf3f0cc4e4"
integrity sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==
"@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.0": "@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.0":
version "0.5.7" version "0.5.7"
resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz"
@ -3543,6 +3548,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/primitive@1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.3.tgz#e2dbc13bdc5e4168f4334f75832d7bdd3e2de5ba"
integrity sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==
"@radix-ui/react-arrow@1.0.3": "@radix-ui/react-arrow@1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d" resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d"
@ -3551,6 +3561,13 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3" "@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-arrow@1.1.7":
version "1.1.7"
resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz#e14a2657c81d961598c5e72b73dd6098acc04f09"
integrity sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==
dependencies:
"@radix-ui/react-primitive" "2.1.3"
"@radix-ui/react-collection@1.0.3": "@radix-ui/react-collection@1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159" resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159"
@ -3569,6 +3586,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs@1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz#a2c4c47af6337048ee78ff6dc0d090b390d2bb30"
integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==
"@radix-ui/react-context@1.0.1": "@radix-ui/react-context@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c"
@ -3576,6 +3598,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-context@1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.2.tgz#61628ef269a433382c364f6f1e3788a6dc213a36"
integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==
"@radix-ui/react-direction@1.0.1": "@radix-ui/react-direction@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b" resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b"
@ -3595,6 +3622,36 @@
"@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown" "1.0.3" "@radix-ui/react-use-escape-keydown" "1.0.3"
"@radix-ui/react-dismissable-layer@1.1.11":
version "1.1.11"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz#e33ab6f6bdaa00f8f7327c408d9f631376b88b37"
integrity sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==
dependencies:
"@radix-ui/primitive" "1.1.3"
"@radix-ui/react-compose-refs" "1.1.2"
"@radix-ui/react-primitive" "2.1.3"
"@radix-ui/react-use-callback-ref" "1.1.1"
"@radix-ui/react-use-escape-keydown" "1.1.1"
"@radix-ui/react-focus-guards@1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz#2a5669e464ad5fde9f86d22f7fdc17781a4dfa7f"
integrity sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==
"@radix-ui/react-focus-scope@1.1.7":
version "1.1.7"
resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz#dfe76fc103537d80bf42723a183773fd07bfb58d"
integrity sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==
dependencies:
"@radix-ui/react-compose-refs" "1.1.2"
"@radix-ui/react-primitive" "2.1.3"
"@radix-ui/react-use-callback-ref" "1.1.1"
"@radix-ui/react-icons@^1.3.0":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.2.tgz#09be63d178262181aeca5fb7f7bc944b10a7f441"
integrity sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==
"@radix-ui/react-id@1.0.1": "@radix-ui/react-id@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0"
@ -3603,6 +3660,34 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "1.0.1" "@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-id@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.1.tgz#1404002e79a03fe062b7e3864aa01e24bd1471f7"
integrity sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==
dependencies:
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-popover@^1.1.15":
version "1.1.15"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.15.tgz#9c852f93990a687ebdc949b2c3de1f37cdc4c5d5"
integrity sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==
dependencies:
"@radix-ui/primitive" "1.1.3"
"@radix-ui/react-compose-refs" "1.1.2"
"@radix-ui/react-context" "1.1.2"
"@radix-ui/react-dismissable-layer" "1.1.11"
"@radix-ui/react-focus-guards" "1.1.3"
"@radix-ui/react-focus-scope" "1.1.7"
"@radix-ui/react-id" "1.1.1"
"@radix-ui/react-popper" "1.2.8"
"@radix-ui/react-portal" "1.1.9"
"@radix-ui/react-presence" "1.1.5"
"@radix-ui/react-primitive" "2.1.3"
"@radix-ui/react-slot" "1.2.3"
"@radix-ui/react-use-controllable-state" "1.2.2"
aria-hidden "^1.2.4"
react-remove-scroll "^2.6.3"
"@radix-ui/react-popper@1.1.3": "@radix-ui/react-popper@1.1.3":
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42" resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42"
@ -3620,6 +3705,22 @@
"@radix-ui/react-use-size" "1.0.1" "@radix-ui/react-use-size" "1.0.1"
"@radix-ui/rect" "1.0.1" "@radix-ui/rect" "1.0.1"
"@radix-ui/react-popper@1.2.8":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.8.tgz#a79f39cdd2b09ab9fb50bf95250918422c4d9602"
integrity sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==
dependencies:
"@floating-ui/react-dom" "^2.0.0"
"@radix-ui/react-arrow" "1.1.7"
"@radix-ui/react-compose-refs" "1.1.2"
"@radix-ui/react-context" "1.1.2"
"@radix-ui/react-primitive" "2.1.3"
"@radix-ui/react-use-callback-ref" "1.1.1"
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-use-rect" "1.1.1"
"@radix-ui/react-use-size" "1.1.1"
"@radix-ui/rect" "1.1.1"
"@radix-ui/react-portal@1.0.4": "@radix-ui/react-portal@1.0.4":
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15"
@ -3628,6 +3729,14 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "1.0.3" "@radix-ui/react-primitive" "1.0.3"
"@radix-ui/react-portal@1.1.9":
version "1.1.9"
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.9.tgz#14c3649fe48ec474ac51ed9f2b9f5da4d91c4472"
integrity sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==
dependencies:
"@radix-ui/react-primitive" "2.1.3"
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-presence@1.0.1": "@radix-ui/react-presence@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba"
@ -3637,6 +3746,14 @@
"@radix-ui/react-compose-refs" "1.0.1" "@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-use-layout-effect" "1.0.1" "@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-presence@1.1.5":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.5.tgz#5d8f28ac316c32f078afce2996839250c10693db"
integrity sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==
dependencies:
"@radix-ui/react-compose-refs" "1.1.2"
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-primitive@1.0.3": "@radix-ui/react-primitive@1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0"
@ -3645,6 +3762,13 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-slot" "1.0.2" "@radix-ui/react-slot" "1.0.2"
"@radix-ui/react-primitive@2.1.3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz#db9b8bcff49e01be510ad79893fb0e4cda50f1bc"
integrity sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==
dependencies:
"@radix-ui/react-slot" "1.2.3"
"@radix-ui/react-roving-focus@1.0.4": "@radix-ui/react-roving-focus@1.0.4":
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz#e90c4a6a5f6ac09d3b8c1f5b5e81aab2f0db1974" resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz#e90c4a6a5f6ac09d3b8c1f5b5e81aab2f0db1974"
@ -3669,6 +3793,13 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-compose-refs" "1.0.1" "@radix-ui/react-compose-refs" "1.0.1"
"@radix-ui/react-slot@1.2.3", "@radix-ui/react-slot@^1.1.0", "@radix-ui/react-slot@^1.2.3":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.2.3.tgz#502d6e354fc847d4169c3bc5f189de777f68cfe1"
integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==
dependencies:
"@radix-ui/react-compose-refs" "1.1.2"
"@radix-ui/react-tabs@1.0.4": "@radix-ui/react-tabs@1.0.4":
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz#993608eec55a5d1deddd446fa9978d2bc1053da2" resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz#993608eec55a5d1deddd446fa9978d2bc1053da2"
@ -3710,6 +3841,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz#62a4dba8b3255fdc5cc7787faeac1c6e4cc58d40"
integrity sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==
"@radix-ui/react-use-controllable-state@1.0.1": "@radix-ui/react-use-controllable-state@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286"
@ -3718,6 +3854,21 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-controllable-state@1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz#905793405de57d61a439f4afebbb17d0645f3190"
integrity sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==
dependencies:
"@radix-ui/react-use-effect-event" "0.0.2"
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-use-effect-event@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz#090cf30d00a4c7632a15548512e9152217593907"
integrity sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==
dependencies:
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-use-escape-keydown@1.0.3": "@radix-ui/react-use-escape-keydown@1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755"
@ -3726,6 +3877,13 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "1.0.1" "@radix-ui/react-use-callback-ref" "1.0.1"
"@radix-ui/react-use-escape-keydown@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz#b3fed9bbea366a118f40427ac40500aa1423cc29"
integrity sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==
dependencies:
"@radix-ui/react-use-callback-ref" "1.1.1"
"@radix-ui/react-use-layout-effect@1.0.1": "@radix-ui/react-use-layout-effect@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399"
@ -3733,6 +3891,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz#0c4230a9eed49d4589c967e2d9c0d9d60a23971e"
integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==
"@radix-ui/react-use-rect@1.0.1": "@radix-ui/react-use-rect@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2"
@ -3741,6 +3904,13 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/rect" "1.0.1" "@radix-ui/rect" "1.0.1"
"@radix-ui/react-use-rect@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz#01443ca8ed071d33023c1113e5173b5ed8769152"
integrity sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==
dependencies:
"@radix-ui/rect" "1.1.1"
"@radix-ui/react-use-size@1.0.1": "@radix-ui/react-use-size@1.0.1":
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2"
@ -3749,6 +3919,13 @@
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "1.0.1" "@radix-ui/react-use-layout-effect" "1.0.1"
"@radix-ui/react-use-size@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz#6de276ffbc389a537ffe4316f5b0f24129405b37"
integrity sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==
dependencies:
"@radix-ui/react-use-layout-effect" "1.1.1"
"@radix-ui/react-visually-hidden@1.0.3": "@radix-ui/react-visually-hidden@1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac" resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac"
@ -3764,6 +3941,11 @@
dependencies: dependencies:
"@babel/runtime" "^7.13.10" "@babel/runtime" "^7.13.10"
"@radix-ui/rect@1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.1.tgz#78244efe12930c56fd255d7923865857c41ac8cb"
integrity sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==
"@rc-component/color-picker@~1.4.1": "@rc-component/color-picker@~1.4.1":
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/@rc-component/color-picker/-/color-picker-1.4.1.tgz#dcab0b660e9c4ed63a7582db68ed4a77c862cb93" resolved "https://registry.yarnpkg.com/@rc-component/color-picker/-/color-picker-1.4.1.tgz#dcab0b660e9c4ed63a7582db68ed4a77c862cb93"
@ -4009,11 +4191,81 @@
unplugin "1.0.1" unplugin "1.0.1"
uuid "^9.0.0" uuid "^9.0.0"
"@signozhq/button@0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@signozhq/button/-/button-0.0.1.tgz#7d3204454b0361bd3fdf91fa6604af01a481a9db"
integrity sha512-k5WFpckNXzwcTS82jU+65M3V1KdriopBObB1ls7W2OU0RKof6Gf+/9uqDXnuu+Y4Cxn2cPo8+6MfiQbS02LHeg==
dependencies:
"@radix-ui/react-icons" "^1.3.0"
"@radix-ui/react-slot" "^1.1.0"
class-variance-authority "^0.7.0"
clsx "^2.1.1"
lucide-react "^0.445.0"
tailwind-merge "^2.5.2"
tailwindcss-animate "^1.0.7"
"@signozhq/button@^0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@signozhq/button/-/button-0.0.2.tgz#c13edef1e735134b784a41f874b60a14bc16993f"
integrity sha512-434/gbTykC00LrnzFPp7c33QPWZkf9n+8+SToLZFTB0rzcaS/xoB4b7QKhvk+8xLCj4zpw6BxfeRAL+gSoOUJw==
dependencies:
"@radix-ui/react-icons" "^1.3.0"
"@radix-ui/react-slot" "^1.1.0"
class-variance-authority "^0.7.0"
clsx "^2.1.1"
lucide-react "^0.445.0"
tailwind-merge "^2.5.2"
tailwindcss-animate "^1.0.7"
"@signozhq/calendar@0.0.0":
version "0.0.0"
resolved "https://registry.yarnpkg.com/@signozhq/calendar/-/calendar-0.0.0.tgz#93b2cec2586efee814df934f88a2193cec95bae9"
integrity sha512-lm7tzPEhaHNjrksvi2GPGH4suEe6x2DQJ2dpku+JmKyLGB5rg9saSAosvrZVKhXLoZuSSjlBSkz+oHYEKIdHfA==
dependencies:
"@radix-ui/react-icons" "^1.3.0"
"@radix-ui/react-slot" "^1.2.3"
"@signozhq/button" "0.0.1"
class-variance-authority "^0.7.0"
clsx "^2.1.1"
date-fns "^4.1.0"
lucide-react "^0.445.0"
react-day-picker "^9.8.1"
tailwind-merge "^2.5.2"
tailwindcss-animate "^1.0.7"
"@signozhq/design-tokens@1.1.4": "@signozhq/design-tokens@1.1.4":
version "1.1.4" version "1.1.4"
resolved "https://registry.yarnpkg.com/@signozhq/design-tokens/-/design-tokens-1.1.4.tgz#5d5de5bd9d19b6a3631383db015cc4b70c3f7661" resolved "https://registry.yarnpkg.com/@signozhq/design-tokens/-/design-tokens-1.1.4.tgz#5d5de5bd9d19b6a3631383db015cc4b70c3f7661"
integrity sha512-ICZz5szxTq8NcKAsk6LP+nSybPyEcyy8eu2zfxlPQCnJ1YjJP1PglaKLlF0N6+D60gAd3yC5he06BqR8/HxjNg== integrity sha512-ICZz5szxTq8NcKAsk6LP+nSybPyEcyy8eu2zfxlPQCnJ1YjJP1PglaKLlF0N6+D60gAd3yC5he06BqR8/HxjNg==
"@signozhq/input@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@signozhq/input/-/input-0.0.2.tgz#b2fea8c0979a53984ebcd5e3c3c50b38082eb1b1"
integrity sha512-Iti9GkvexSsULX1pQsN6FT6Gw96YWilts72wITZd5fzgZq1yKqaDtQl98/QNuyoS3I3WEh+hVF4EIeCCe7oRsQ==
dependencies:
"@radix-ui/react-icons" "^1.3.0"
"@radix-ui/react-slot" "^1.1.0"
class-variance-authority "^0.7.0"
clsx "^2.1.1"
lucide-react "^0.445.0"
tailwind-merge "^2.5.2"
tailwindcss-animate "^1.0.7"
"@signozhq/popover@0.0.0":
version "0.0.0"
resolved "https://registry.yarnpkg.com/@signozhq/popover/-/popover-0.0.0.tgz#675baf1c18ca0180369b4df0700c24e2c55ad758"
integrity sha512-XW0MhzxWzZNQWjVeb+BFjiOIbBbYCT+9MCUOIW8kiL0axFaaimnk0QPi1rk09u136MMGByI6fYuCJ5Qa07l1dA==
dependencies:
"@radix-ui/react-icons" "^1.3.0"
"@radix-ui/react-popover" "^1.1.15"
"@radix-ui/react-slot" "^1.1.0"
"@signozhq/button" "^0.0.2"
class-variance-authority "^0.7.0"
clsx "^2.1.1"
lucide-react "^0.445.0"
tailwind-merge "^2.5.2"
tailwindcss-animate "^1.0.7"
"@sinclair/typebox@^0.25.16": "@sinclair/typebox@^0.25.16":
version "0.25.24" version "0.25.24"
resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz" resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz"
@ -5787,6 +6039,13 @@ argparse@^1.0.7:
dependencies: dependencies:
sprintf-js "~1.0.2" sprintf-js "~1.0.2"
aria-hidden@^1.2.4:
version "1.2.6"
resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.6.tgz#73051c9b088114c795b1ea414e9c0fff874ffc1a"
integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==
dependencies:
tslib "^2.0.0"
aria-query@^5.0.0, aria-query@^5.1.3: aria-query@^5.0.0, aria-query@^5.1.3:
version "5.1.3" version "5.1.3"
resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz"
@ -6870,6 +7129,13 @@ cjs-module-lexer@^1.0.0:
resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz" resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz"
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
class-variance-authority@^0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787"
integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==
dependencies:
clsx "^2.1.1"
classnames@2.3.2, classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1, classnames@^2.3.2: classnames@2.3.2, classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1, classnames@^2.3.2:
version "2.3.2" version "2.3.2"
resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz" resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz"
@ -6964,6 +7230,11 @@ clsx@^1.1.1:
resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz"
integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
co@^4.6.0: co@^4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz"
@ -7787,11 +8058,21 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0" whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0" whatwg-url "^8.0.0"
date-fns-jalali@^4.1.0-0:
version "4.1.0-0"
resolved "https://registry.yarnpkg.com/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz#9c7fb286004fab267a300d3e9f1ada9f10b4b6b0"
integrity sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==
date-fns@3.6.0: date-fns@3.6.0:
version "3.6.0" version "3.6.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-3.6.0.tgz#f20ca4fe94f8b754951b24240676e8618c0206bf"
integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww== integrity sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==
date-fns@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14"
integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==
dayjs@^1.10.7, dayjs@^1.11.1: dayjs@^1.10.7, dayjs@^1.11.1:
version "1.11.7" version "1.11.7"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz"
@ -7993,6 +8274,11 @@ detect-newline@^3.0.0:
resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz"
integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
detect-node-es@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
detect-node@^2.0.4, detect-node@^2.1.0: detect-node@^2.0.4, detect-node@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz"
@ -9418,6 +9704,11 @@ get-intrinsic@^1.2.6:
hasown "^2.0.2" hasown "^2.0.2"
math-intrinsics "^1.1.0" math-intrinsics "^1.1.0"
get-nonce@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3"
integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==
get-package-type@^0.1.0: get-package-type@^0.1.0:
version "0.1.0" version "0.1.0"
resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz"
@ -11932,6 +12223,11 @@ lucide-react@0.498.0:
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.498.0.tgz#3109eac93dfd0c1561db7a5cddfe4b9b20c14315" resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.498.0.tgz#3109eac93dfd0c1561db7a5cddfe4b9b20c14315"
integrity sha512-k8IKbvMNV5Dj7CHRrKyIc1wAtmGdEF0r6SCaiGAt5cZ8KnjcEao8mfdydKkWspy65l40MdlcfdK0kT3QrxpnIg== integrity sha512-k8IKbvMNV5Dj7CHRrKyIc1wAtmGdEF0r6SCaiGAt5cZ8KnjcEao8mfdydKkWspy65l40MdlcfdK0kT3QrxpnIg==
lucide-react@^0.445.0:
version "0.445.0"
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.445.0.tgz#35c42341e98fbf0475b2a6cf74fd25ef7cbfcd62"
integrity sha512-YrLf3aAHvmd4dZ8ot+mMdNFrFpJD7YRwQ2pUcBhgqbmxtrMP4xDzIorcj+8y+6kpuXBF4JB0NOCTUWIYetJjgA==
lz-string@^1.4.4: lz-string@^1.4.4:
version "1.5.0" version "1.5.0"
resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz" resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz"
@ -14759,6 +15055,15 @@ react-beautiful-dnd@13.1.1:
redux "^4.0.4" redux "^4.0.4"
use-memo-one "^1.1.1" use-memo-one "^1.1.1"
react-day-picker@^9.8.1:
version "9.9.0"
resolved "https://registry.yarnpkg.com/react-day-picker/-/react-day-picker-9.9.0.tgz#494da0f1470e8f0ca61c30100b17615687b68393"
integrity sha512-NtkJbuX6cl/VaGNb3sVVhmMA6LSMnL5G3xNL+61IyoZj0mUZFWTg4hmj7PHjIQ8MXN9dHWhUHFoJWG6y60DKSg==
dependencies:
"@date-fns/tz" "^1.4.1"
date-fns "^4.1.0"
date-fns-jalali "^4.1.0-0"
react-dnd-html5-backend@16.0.1: react-dnd-html5-backend@16.0.1:
version "16.0.1" version "16.0.1"
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz#87faef15845d512a23b3c08d29ecfd34871688b6" resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz#87faef15845d512a23b3c08d29ecfd34871688b6"
@ -14962,6 +15267,25 @@ react-redux@^7.2.0, react-redux@^7.2.2:
prop-types "^15.7.2" prop-types "^15.7.2"
react-is "^17.0.2" react-is "^17.0.2"
react-remove-scroll-bar@^2.3.7:
version "2.3.8"
resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223"
integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==
dependencies:
react-style-singleton "^2.2.2"
tslib "^2.0.0"
react-remove-scroll@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz#d2101d414f6d81d7d3bf033f3c1cb4785789f753"
integrity sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==
dependencies:
react-remove-scroll-bar "^2.3.7"
react-style-singleton "^2.2.3"
tslib "^2.1.0"
use-callback-ref "^1.3.3"
use-sidecar "^1.1.3"
react-resizable@3.0.4: react-resizable@3.0.4:
version "3.0.4" version "3.0.4"
resolved "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.4.tgz" resolved "https://registry.npmjs.org/react-resizable/-/react-resizable-3.0.4.tgz"
@ -15022,6 +15346,14 @@ react-router@6.27.0:
dependencies: dependencies:
"@remix-run/router" "1.20.0" "@remix-run/router" "1.20.0"
react-style-singleton@^2.2.2, react-style-singleton@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388"
integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==
dependencies:
get-nonce "^1.0.0"
tslib "^2.0.0"
react-syntax-highlighter@15.5.0: react-syntax-highlighter@15.5.0:
version "15.5.0" version "15.5.0"
resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz#4b3eccc2325fa2ec8eff1e2d6c18fa4a9e07ab20" resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz#4b3eccc2325fa2ec8eff1e2d6c18fa4a9e07ab20"
@ -16608,6 +16940,16 @@ table@^6.0.9:
string-width "^4.2.3" string-width "^4.2.3"
strip-ansi "^6.0.1" strip-ansi "^6.0.1"
tailwind-merge@^2.5.2:
version "2.6.0"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.6.0.tgz#ac5fb7e227910c038d458f396b7400d93a3142d5"
integrity sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==
tailwindcss-animate@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz#318b692c4c42676cc9e67b19b78775742388bef4"
integrity sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==
tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
version "2.2.1" version "2.2.1"
resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz"
@ -17346,6 +17688,13 @@ url-set-query@^1.0.0:
resolved "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz" resolved "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz"
integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==
use-callback-ref@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.3.tgz#98d9fab067075841c5b2c6852090d5d0feabe2bf"
integrity sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==
dependencies:
tslib "^2.0.0"
use-isomorphic-layout-effect@^1.1.2: use-isomorphic-layout-effect@^1.1.2:
version "1.1.2" version "1.1.2"
resolved "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz" resolved "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz"
@ -17356,6 +17705,14 @@ use-memo-one@^1.1.1:
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99" resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ== integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
use-sidecar@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.3.tgz#10e7fd897d130b896e2c546c63a5e8233d00efdb"
integrity sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==
dependencies:
detect-node-es "^1.1.0"
tslib "^2.0.0"
use-sync-external-store@^1.0.0: use-sync-external-store@^1.0.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz"