diff --git a/package.json b/package.json
index d4d8fc9c..dbb40b90 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"clsx": "2.1.1",
"dayjs": "1.11.13",
"dotenv-webpack": "8.1.0",
+ "rc-picker": "4.9.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-error-boundary": "4.0.13",
diff --git a/src/features/transfer/MutateTransferForm/components/TransferSchedule/index.tsx b/src/features/transfer/MutateTransferForm/components/TransferSchedule/index.tsx
index bd47215f..54013a70 100644
--- a/src/features/transfer/MutateTransferForm/components/TransferSchedule/index.tsx
+++ b/src/features/transfer/MutateTransferForm/components/TransferSchedule/index.tsx
@@ -1,4 +1,5 @@
-import { Form, Input, Switch } from 'antd';
+import { CronSelect } from '@shared/ui';
+import { Form, Switch } from 'antd';
import React, { useState } from 'react';
export const TransferSchedule = () => {
@@ -16,7 +17,7 @@ export const TransferSchedule = () => {
{isScheduled && (
-
+
)}
>
diff --git a/src/features/transfer/TransferDetailInfo/index.tsx b/src/features/transfer/TransferDetailInfo/index.tsx
index a5d08ea6..f3faeaab 100644
--- a/src/features/transfer/TransferDetailInfo/index.tsx
+++ b/src/features/transfer/TransferDetailInfo/index.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import { Descriptions } from 'antd';
import { Link } from 'react-router-dom';
+import { CronService } from '@shared/services';
import { TransferDetailInfoProps } from './types';
import classes from './styles.module.less';
@@ -32,12 +33,11 @@ export const TransferDetailInfo = ({
{queue.name}
-
- {transfer.is_scheduled ? 'Yes' : 'No'}
-
-
- {transfer.schedule}
-
+ {transfer.is_scheduled && (
+
+ {new CronService(transfer.schedule).getSchedule()}
+
+ )}
{transfer.strategy_params.type}
diff --git a/src/shared/services/cronService/constants.ts b/src/shared/services/cronService/constants.ts
new file mode 100644
index 00000000..8f2765d6
--- /dev/null
+++ b/src/shared/services/cronService/constants.ts
@@ -0,0 +1,10 @@
+import { CronSegmentKey, CronSegmentValue, DayOfWeekName } from './types';
+
+export const CRON_VALUE_DEFAULT = new Map([
+ ['minute', new Date().getMinutes()],
+ ['hour', new Date().getHours()],
+ ['date', null],
+ ['day', null],
+]);
+
+export const DAYS_OF_WEEK = Object.values(DayOfWeekName);
diff --git a/src/shared/services/cronService/cronService.ts b/src/shared/services/cronService/cronService.ts
new file mode 100644
index 00000000..5b0a6216
--- /dev/null
+++ b/src/shared/services/cronService/cronService.ts
@@ -0,0 +1,158 @@
+import { getOrdinalNumber } from '@shared/utils';
+
+import { CRON_VALUE_DEFAULT, DAYS_OF_WEEK } from './constants';
+import { CronSegmentKey, CronSegmentValue, Period } from './types';
+
+/** Class for convenient handling cron settings */
+export class CronService {
+ private initialValueLength = 5;
+
+ private period: Period;
+
+ private value: Map;
+
+ constructor(initialValue?: string) {
+ this.value = this.transformInitialValueToMap(initialValue);
+ this.period = this.initPeriod();
+ }
+
+ private transformInitialValueToMap(initialValue?: string) {
+ const splittedValue = initialValue?.split(' ');
+ if (splittedValue?.length !== this.initialValueLength) {
+ return CRON_VALUE_DEFAULT;
+ }
+
+ const cronValue = splittedValue.map((segment) => {
+ const parsedValue = parseInt(segment);
+ if (Number.isInteger(parsedValue)) {
+ return parsedValue;
+ }
+ return null;
+ });
+
+ return new Map([
+ ['minute', cronValue[0]],
+ ['hour', cronValue[1]],
+ ['date', cronValue[2]],
+ ['day', cronValue[4]],
+ ]);
+ }
+
+ private initPeriod() {
+ if (this.getMonthDay() === null && this.getWeekDay() === null) {
+ return Period.DAY;
+ }
+ if (this.getMonthDay()) {
+ return Period.MONTH;
+ }
+ return Period.WEEK;
+ }
+
+ getPeriod() {
+ return this.period;
+ }
+
+ getMinute(): number {
+ return this.value.get('minute')!;
+ }
+
+ getHour(): number {
+ return this.value.get('hour')!;
+ }
+
+ getTime() {
+ return `${this.getHour()}:${this.getMinute()}`;
+ }
+
+ getMonthDay(): CronSegmentValue {
+ return this.value.get('date') ?? null;
+ }
+
+ getWeekDay(): CronSegmentValue {
+ return this.value.get('day') ?? null;
+ }
+
+ setPeriod(period: Period) {
+ this.period = period;
+ switch (period) {
+ case Period.DAY:
+ this.setMonthDay(null);
+ this.setWeekDay(null);
+ break;
+ case Period.WEEK:
+ this.setWeekDay(new Date().getDay());
+ this.setMonthDay(null);
+ break;
+ case Period.MONTH:
+ this.setWeekDay(null);
+ this.setMonthDay(new Date().getDate());
+ }
+ }
+
+ setMinute(value: number) {
+ if (value < 0 || value > 59) {
+ throw new Error('Invalid value');
+ }
+ this.value.set('minute', value);
+ }
+
+ setHour(value: number) {
+ if (value < 0 || value > 23) {
+ throw new Error('Invalid value');
+ }
+ this.value.set('hour', value);
+ }
+
+ setTime(hour?: number, minute?: number) {
+ this.setHour(hour ?? new Date().getHours());
+ this.setMinute(minute ?? new Date().getMinutes());
+ }
+
+ setMonthDay(value: CronSegmentValue) {
+ if (value === null) {
+ this.value.set('date', null);
+ return;
+ }
+ if (value < 1 || value > 31) {
+ throw new Error('Invalid value');
+ }
+ this.value.set('date', value);
+ }
+
+ setWeekDay(value: CronSegmentValue) {
+ if (value === null) {
+ this.value.set('day', null);
+ return;
+ }
+ if (value < 0 || value > 6) {
+ throw new Error('Invalid value');
+ }
+ this.value.set('day', value);
+ }
+
+ toString() {
+ const minute = this.getMinute();
+ const hour = this.getHour();
+ const date = this.getMonthDay() ?? '*';
+ const day = this.getWeekDay() ?? '*';
+ return `${minute} ${hour} ${date} * ${day}`;
+ }
+
+ getSchedule() {
+ const time = this.getTime();
+ const day = this.getWeekDay();
+ const date = this.getMonthDay();
+
+ let schedule = `Every ${this.period} `;
+
+ if (day !== null) {
+ schedule += `on ${DAYS_OF_WEEK[day]} `;
+ } else if (date) {
+ schedule += `${getOrdinalNumber(date)} `;
+ }
+
+ schedule += `at ${time}`;
+
+ return schedule;
+ }
+}
diff --git a/src/shared/services/cronService/index.ts b/src/shared/services/cronService/index.ts
new file mode 100644
index 00000000..d9eddf23
--- /dev/null
+++ b/src/shared/services/cronService/index.ts
@@ -0,0 +1,2 @@
+export * from './cronService';
+export * from './types';
diff --git a/src/shared/services/cronService/types.ts b/src/shared/services/cronService/types.ts
new file mode 100644
index 00000000..2c46f3b6
--- /dev/null
+++ b/src/shared/services/cronService/types.ts
@@ -0,0 +1,29 @@
+export type CronSegmentValue = number | null;
+
+export type CronSegmentKey = 'date' | 'day' | 'hour' | 'minute';
+
+export enum Period {
+ DAY = 'day',
+ WEEK = 'week',
+ MONTH = 'month',
+}
+
+export enum DayOfWeek {
+ SUNDAY,
+ MONDAY,
+ TUESDAY,
+ WEDNESDAY,
+ THURSDAY,
+ FRIDAY,
+ SATURDAY,
+}
+
+export enum DayOfWeekName {
+ SUNDAY = 'Sunday',
+ MONDAY = 'Monday',
+ TUESDAY = 'Tuesday',
+ WEDNESDAY = 'Wednesday',
+ THURSDAY = 'Thursday',
+ FRIDAY = 'Friday',
+ SATURDAY = 'Saturday',
+}
diff --git a/src/shared/services/index.ts b/src/shared/services/index.ts
new file mode 100644
index 00000000..35c276dd
--- /dev/null
+++ b/src/shared/services/index.ts
@@ -0,0 +1 @@
+export * from './cronService';
diff --git a/src/shared/ui/Calendar/index.tsx b/src/shared/ui/Calendar/index.tsx
new file mode 100644
index 00000000..622df3bf
--- /dev/null
+++ b/src/shared/ui/Calendar/index.tsx
@@ -0,0 +1,5 @@
+import { Dayjs } from 'dayjs';
+import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
+import generateCalendar from 'antd/es/calendar/generateCalendar';
+
+export const Calendar = generateCalendar(dayjsGenerateConfig);
diff --git a/src/shared/ui/CronSelect/components/DynamicSelect/index.tsx b/src/shared/ui/CronSelect/components/DynamicSelect/index.tsx
new file mode 100644
index 00000000..a93d2117
--- /dev/null
+++ b/src/shared/ui/CronSelect/components/DynamicSelect/index.tsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import { Select } from 'antd';
+import { getOrdinalNumber } from '@shared/utils';
+import { Period } from '@shared/services';
+
+import classes from '../../styles.module.less';
+import { DAYS_OF_MONTH_SELECT_OPTIONS, DAYS_OF_WEEK_SELECT_OPTIONS } from '../../constants';
+
+import { DynamicSelectProps } from './types';
+
+export const DynamicSelect = ({ period, weekDay, monthDay, onChangeWeekDay, onChangeMonthDay }: DynamicSelectProps) => {
+ switch (period) {
+ case Period.WEEK:
+ return (
+
+ );
+ case Period.MONTH:
+ return (
+
+
+ {getOrdinalNumber(monthDay!, true)}
+
+ );
+ default:
+ return null;
+ }
+};
diff --git a/src/shared/ui/CronSelect/components/DynamicSelect/types.ts b/src/shared/ui/CronSelect/components/DynamicSelect/types.ts
new file mode 100644
index 00000000..f659553c
--- /dev/null
+++ b/src/shared/ui/CronSelect/components/DynamicSelect/types.ts
@@ -0,0 +1,15 @@
+import { CronSegmentValue, Period } from '@shared/services';
+
+/** Interface as Props for component "DynamicSelect" */
+export interface DynamicSelectProps {
+ /** Value of period Select */
+ period: Period;
+ /** Value of week day Select */
+ weekDay: CronSegmentValue;
+ /** Value of month day Select */
+ monthDay: CronSegmentValue;
+ /** Callback for changing value of week day Select */
+ onChangeWeekDay: (value: CronSegmentValue) => void;
+ /** Callback for changing value of month day Select */
+ onChangeMonthDay: (value: CronSegmentValue) => void;
+}
diff --git a/src/shared/ui/CronSelect/components/index.ts b/src/shared/ui/CronSelect/components/index.ts
new file mode 100644
index 00000000..a7b7feee
--- /dev/null
+++ b/src/shared/ui/CronSelect/components/index.ts
@@ -0,0 +1 @@
+export * from './DynamicSelect';
diff --git a/src/shared/ui/CronSelect/constants.ts b/src/shared/ui/CronSelect/constants.ts
new file mode 100644
index 00000000..d2fbf481
--- /dev/null
+++ b/src/shared/ui/CronSelect/constants.ts
@@ -0,0 +1,28 @@
+import { DayOfWeek, DayOfWeekName, Period } from '@shared/services';
+import { prepareOptionsForSelect } from '@shared/ui';
+
+export const PERIOD_SELECT_OPTIONS = prepareOptionsForSelect({
+ data: Object.values(Period),
+ renderLabel: (data) => data,
+ renderValue: (data) => data,
+});
+
+export const DAYS_OF_WEEK_SELECT_OPTIONS = prepareOptionsForSelect({
+ data: [
+ { value: DayOfWeek.MONDAY, label: DayOfWeekName.MONDAY },
+ { value: DayOfWeek.TUESDAY, label: DayOfWeekName.TUESDAY },
+ { value: DayOfWeek.WEDNESDAY, label: DayOfWeekName.WEDNESDAY },
+ { value: DayOfWeek.THURSDAY, label: DayOfWeekName.THURSDAY },
+ { value: DayOfWeek.FRIDAY, label: DayOfWeekName.FRIDAY },
+ { value: DayOfWeek.SATURDAY, label: DayOfWeekName.SATURDAY },
+ { value: DayOfWeek.SUNDAY, label: DayOfWeekName.SUNDAY },
+ ],
+ renderLabel: (data) => data.label,
+ renderValue: (data) => data.value,
+});
+
+export const DAYS_OF_MONTH_SELECT_OPTIONS = prepareOptionsForSelect({
+ data: Array.from({ length: 31 }, (_, index) => index + 1),
+ renderLabel: (data) => data,
+ renderValue: (data) => data,
+});
diff --git a/src/shared/ui/CronSelect/hooks/index.ts b/src/shared/ui/CronSelect/hooks/index.ts
new file mode 100644
index 00000000..39b816b3
--- /dev/null
+++ b/src/shared/ui/CronSelect/hooks/index.ts
@@ -0,0 +1 @@
+export * from './useCron';
diff --git a/src/shared/ui/CronSelect/hooks/useCron/index.ts b/src/shared/ui/CronSelect/hooks/useCron/index.ts
new file mode 100644
index 00000000..ba279942
--- /dev/null
+++ b/src/shared/ui/CronSelect/hooks/useCron/index.ts
@@ -0,0 +1,2 @@
+export * from './useCron';
+export * from './types';
diff --git a/src/shared/ui/CronSelect/hooks/useCron/types.ts b/src/shared/ui/CronSelect/hooks/useCron/types.ts
new file mode 100644
index 00000000..af0c5c55
--- /dev/null
+++ b/src/shared/ui/CronSelect/hooks/useCron/types.ts
@@ -0,0 +1,7 @@
+/** Interface as Props for hook "useCron" */
+export interface UseCronProps {
+ /** Value of cron expression like "* * * * *" */
+ value?: string;
+ /** Callback for changing value of cron expression */
+ onChange?: (value: string) => void;
+}
diff --git a/src/shared/ui/CronSelect/hooks/useCron/useCron.ts b/src/shared/ui/CronSelect/hooks/useCron/useCron.ts
new file mode 100644
index 00000000..144eabd7
--- /dev/null
+++ b/src/shared/ui/CronSelect/hooks/useCron/useCron.ts
@@ -0,0 +1,42 @@
+import { CronSegmentValue, CronService, Period } from '@shared/services';
+import dayjs, { Dayjs } from 'dayjs';
+
+import { UseCronProps } from './types';
+
+/** Hook for handling value of CronSelect component */
+export const useCron = ({ value, onChange = () => undefined }: UseCronProps) => {
+ const cronService = new CronService(value);
+
+ const handleChange = () => onChange(cronService.toString());
+
+ const handleChangePeriod = (period: Period) => {
+ cronService.setPeriod(period);
+ handleChange();
+ };
+
+ const handleChangeWeekDay = (weekDay: CronSegmentValue) => {
+ cronService.setWeekDay(weekDay);
+ handleChange();
+ };
+
+ const handleChangeMonthDay = (monthDay: CronSegmentValue) => {
+ cronService.setMonthDay(monthDay);
+ handleChange();
+ };
+
+ const handleChangeTime = (time: Dayjs | null) => {
+ cronService.setTime(time?.hour(), time?.minute());
+ handleChange();
+ };
+
+ return {
+ period: cronService.getPeriod(),
+ weekDay: cronService.getWeekDay(),
+ monthDay: cronService.getMonthDay(),
+ time: dayjs(cronService.getTime(), 'HH:mm'),
+ handleChangePeriod,
+ handleChangeMonthDay,
+ handleChangeWeekDay,
+ handleChangeTime,
+ };
+};
diff --git a/src/shared/ui/CronSelect/index.tsx b/src/shared/ui/CronSelect/index.tsx
new file mode 100644
index 00000000..7523777a
--- /dev/null
+++ b/src/shared/ui/CronSelect/index.tsx
@@ -0,0 +1,63 @@
+import React, { memo } from 'react';
+import { Select } from 'antd';
+import { TimePicker } from '@shared/ui';
+import { Period } from '@shared/services';
+
+import { PERIOD_SELECT_OPTIONS } from './constants';
+import { CronSelectProps } from './types';
+import classes from './styles.module.less';
+import { useCron } from './hooks';
+import { DynamicSelect } from './components';
+
+export const CronSelect = memo(({ value, onChange }: CronSelectProps) => {
+ const {
+ period,
+ weekDay,
+ monthDay,
+ time,
+ handleChangePeriod,
+ handleChangeWeekDay,
+ handleChangeMonthDay,
+ handleChangeTime,
+ } = useCron({ value, onChange });
+
+ return (
+
+
+ Every:
+
+
+
+ {period !== Period.DAY && (
+
+ On:
+
+
+ )}
+
+
+ At:
+
+
+
+ );
+});
diff --git a/src/shared/ui/CronSelect/styles.module.less b/src/shared/ui/CronSelect/styles.module.less
new file mode 100644
index 00000000..ca6ed030
--- /dev/null
+++ b/src/shared/ui/CronSelect/styles.module.less
@@ -0,0 +1,33 @@
+.root {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+
+ .segment {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+
+ .month {
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ }
+
+ .period {
+ width: 100px;
+ }
+
+ .date {
+ width: 70px;
+ }
+
+ .day {
+ width: 140px;
+ }
+
+ .time {
+ width: 100px;
+ }
+ }
+}
diff --git a/src/shared/ui/CronSelect/types.ts b/src/shared/ui/CronSelect/types.ts
new file mode 100644
index 00000000..465b529b
--- /dev/null
+++ b/src/shared/ui/CronSelect/types.ts
@@ -0,0 +1,3 @@
+import { UseCronProps } from './hooks';
+
+export interface CronSelectProps extends UseCronProps {}
diff --git a/src/shared/ui/DatePicker/index.tsx b/src/shared/ui/DatePicker/index.tsx
new file mode 100644
index 00000000..2bddfa63
--- /dev/null
+++ b/src/shared/ui/DatePicker/index.tsx
@@ -0,0 +1,5 @@
+import { Dayjs } from 'dayjs';
+import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
+import generatePicker from 'antd/es/date-picker/generatePicker';
+
+export const DatePicker = generatePicker(dayjsGenerateConfig);
diff --git a/src/shared/ui/TimePicker/index.tsx b/src/shared/ui/TimePicker/index.tsx
new file mode 100644
index 00000000..905dfe9f
--- /dev/null
+++ b/src/shared/ui/TimePicker/index.tsx
@@ -0,0 +1,12 @@
+import { DatePicker } from '@shared/ui';
+import React, { forwardRef } from 'react';
+
+import { TimePickerProps } from './types';
+
+// Use any in generic, cause it using in https://4x.ant.design/docs/react/replace-moment#TimePicker.tsx
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export const TimePicker = forwardRef((props, ref) => {
+ return ;
+});
+
+TimePicker.displayName = 'TimePicker';
diff --git a/src/shared/ui/TimePicker/types.ts b/src/shared/ui/TimePicker/types.ts
new file mode 100644
index 00000000..8dfe675b
--- /dev/null
+++ b/src/shared/ui/TimePicker/types.ts
@@ -0,0 +1,4 @@
+import { PickerTimeProps } from 'antd/es/date-picker/generatePicker';
+import { Dayjs } from 'dayjs';
+
+export interface TimePickerProps extends Omit, 'picker'> {}
diff --git a/src/shared/ui/index.ts b/src/shared/ui/index.ts
index bac119ac..6e4af9a1 100644
--- a/src/shared/ui/index.ts
+++ b/src/shared/ui/index.ts
@@ -7,3 +7,7 @@ export * from './SpinOverlay';
export * from './FormCurrentGroupDescription';
export * from './ModalWrapper';
export * from './AccessWrapper';
+export * from './DatePicker';
+export * from './TimePicker';
+export * from './Calendar';
+export * from './CronSelect';
diff --git a/src/shared/utils/getOrdinalNumber/index.ts b/src/shared/utils/getOrdinalNumber/index.ts
new file mode 100644
index 00000000..dc84571d
--- /dev/null
+++ b/src/shared/utils/getOrdinalNumber/index.ts
@@ -0,0 +1,29 @@
+/**
+ * Util for getting number with its ordinal postfix
+ *
+ * @param value - number
+ * @param onlyPostfix - flag for returning only postfix without number
+ *
+ * @returns - ordinal number
+ */
+export const getOrdinalNumber = (value: number, onlyPostfix = false): string => {
+ const lastDigit = value % 10;
+ const twoLastDigits = value % 100;
+ let postfix = '';
+
+ if (lastDigit === 1 && twoLastDigits !== 11) {
+ postfix = 'st';
+ } else if (lastDigit === 2 && twoLastDigits !== 12) {
+ postfix = 'nd';
+ } else if (lastDigit === 3 && twoLastDigits !== 13) {
+ postfix = 'rd';
+ } else {
+ postfix = 'th';
+ }
+
+ if (onlyPostfix) {
+ return postfix;
+ }
+
+ return `${value}${postfix}`;
+};
diff --git a/src/shared/utils/index.ts b/src/shared/utils/index.ts
index f3aeb8e3..8ec89b45 100644
--- a/src/shared/utils/index.ts
+++ b/src/shared/utils/index.ts
@@ -1 +1,2 @@
export * from './hasAccessByUserRole';
+export * from './getOrdinalNumber';
diff --git a/yarn.lock b/yarn.lock
index 8b58e932..f08b505b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1484,6 +1484,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.24.7":
+ version: 7.26.0
+ resolution: "@babel/runtime@npm:7.26.0"
+ dependencies:
+ regenerator-runtime: "npm:^0.14.0"
+ checksum: 10c0/12c01357e0345f89f4f7e8c0e81921f2a3e3e101f06e8eaa18a382b517376520cd2fa8c237726eb094dab25532855df28a7baaf1c26342b52782f6936b07c287
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0":
version: 7.25.0
resolution: "@babel/template@npm:7.25.0"
@@ -1800,7 +1809,7 @@ __metadata:
languageName: node
linkType: hard
-"@rc-component/portal@npm:^1.0.0-8, @rc-component/portal@npm:^1.0.2, @rc-component/portal@npm:^1.1.1":
+"@rc-component/portal@npm:^1.0.0-8, @rc-component/portal@npm:^1.0.2, @rc-component/portal@npm:^1.1.0, @rc-component/portal@npm:^1.1.1":
version: 1.1.2
resolution: "@rc-component/portal@npm:1.1.2"
dependencies:
@@ -1814,6 +1823,23 @@ __metadata:
languageName: node
linkType: hard
+"@rc-component/trigger@npm:^2.0.0":
+ version: 2.2.6
+ resolution: "@rc-component/trigger@npm:2.2.6"
+ dependencies:
+ "@babel/runtime": "npm:^7.23.2"
+ "@rc-component/portal": "npm:^1.1.0"
+ classnames: "npm:^2.3.2"
+ rc-motion: "npm:^2.0.0"
+ rc-resize-observer: "npm:^1.3.1"
+ rc-util: "npm:^5.44.0"
+ peerDependencies:
+ react: ">=16.9.0"
+ react-dom: ">=16.9.0"
+ checksum: 10c0/e7ef14099fac74a58301ccf65a003ddaefb6f2a410c950c8354e0d63fd13e21e3a1f32dd4e73a11c7c0c6199e66629f7f3e31c09d887198b974d35805c4de8e1
+ languageName: node
+ linkType: hard
+
"@remix-run/router@npm:1.15.3":
version: 1.15.3
resolution: "@remix-run/router@npm:1.15.3"
@@ -8504,6 +8530,21 @@ __metadata:
languageName: node
linkType: hard
+"rc-overflow@npm:^1.3.2":
+ version: 1.4.1
+ resolution: "rc-overflow@npm:1.4.1"
+ dependencies:
+ "@babel/runtime": "npm:^7.11.1"
+ classnames: "npm:^2.2.1"
+ rc-resize-observer: "npm:^1.0.0"
+ rc-util: "npm:^5.37.0"
+ peerDependencies:
+ react: ">=16.9.0"
+ react-dom: ">=16.9.0"
+ checksum: 10c0/ac47d2c7b4cfc99e8ca20c75f99e601eac4d524f6690d9a36fb65d84b9f627f13aa70f11fc5c09b24c1e9a0395a15c16998a57f2517c08a6abe545539cb5e162
+ languageName: node
+ linkType: hard
+
"rc-pagination@npm:~3.2.0":
version: 3.2.0
resolution: "rc-pagination@npm:3.2.0"
@@ -8517,6 +8558,36 @@ __metadata:
languageName: node
linkType: hard
+"rc-picker@npm:4.9.2":
+ version: 4.9.2
+ resolution: "rc-picker@npm:4.9.2"
+ dependencies:
+ "@babel/runtime": "npm:^7.24.7"
+ "@rc-component/trigger": "npm:^2.0.0"
+ classnames: "npm:^2.2.1"
+ rc-overflow: "npm:^1.3.2"
+ rc-resize-observer: "npm:^1.4.0"
+ rc-util: "npm:^5.43.0"
+ peerDependencies:
+ date-fns: ">= 2.x"
+ dayjs: ">= 1.x"
+ luxon: ">= 3.x"
+ moment: ">= 2.x"
+ react: ">=16.9.0"
+ react-dom: ">=16.9.0"
+ peerDependenciesMeta:
+ date-fns:
+ optional: true
+ dayjs:
+ optional: true
+ luxon:
+ optional: true
+ moment:
+ optional: true
+ checksum: 10c0/052a78e5277f71e8eaf66333dba5aea165bf999ffeef2cea1f5b63395dc083ce80a398dcd51002fe808961282089dfcf92a81ded326fe2bf54f320a24c8f4dbb
+ languageName: node
+ linkType: hard
+
"rc-picker@npm:~2.7.0":
version: 2.7.6
resolution: "rc-picker@npm:2.7.6"
@@ -8579,6 +8650,21 @@ __metadata:
languageName: node
linkType: hard
+"rc-resize-observer@npm:^1.3.1, rc-resize-observer@npm:^1.4.0":
+ version: 1.4.3
+ resolution: "rc-resize-observer@npm:1.4.3"
+ dependencies:
+ "@babel/runtime": "npm:^7.20.7"
+ classnames: "npm:^2.2.1"
+ rc-util: "npm:^5.44.1"
+ resize-observer-polyfill: "npm:^1.5.1"
+ peerDependencies:
+ react: ">=16.9.0"
+ react-dom: ">=16.9.0"
+ checksum: 10c0/93073c9ef5cc704f9d99307f58f8eeccabb953edf4e8a056b090104fc28ed19b77c2a32bd88ca2e0407fbedeb266d1985e655b35b8bc36b04d243e9d0471c911
+ languageName: node
+ linkType: hard
+
"rc-segmented@npm:~2.1.0":
version: 2.1.2
resolution: "rc-segmented@npm:2.1.2"
@@ -8794,6 +8880,19 @@ __metadata:
languageName: node
linkType: hard
+"rc-util@npm:^5.44.0, rc-util@npm:^5.44.1":
+ version: 5.44.3
+ resolution: "rc-util@npm:5.44.3"
+ dependencies:
+ "@babel/runtime": "npm:^7.18.3"
+ react-is: "npm:^18.2.0"
+ peerDependencies:
+ react: ">=16.9.0"
+ react-dom: ">=16.9.0"
+ checksum: 10c0/9b6b737cb1995cba7a936bd6c10d521b422cd62987af3b130d2f0b45f3505491b51f66b0252aeca23b1000998d18294f942abca16f455fd8023709756a3fbd01
+ languageName: node
+ linkType: hard
+
"rc-virtual-list@npm:^3.2.0, rc-virtual-list@npm:^3.5.1":
version: 3.14.7
resolution: "rc-virtual-list@npm:3.14.7"
@@ -9976,6 +10075,7 @@ __metadata:
lint-staged: "npm:15.2.2"
mini-css-extract-plugin: "npm:2.8.1"
prettier: "npm:3.2.5"
+ rc-picker: "npm:4.9.2"
react: "npm:18.2.0"
react-dom: "npm:18.2.0"
react-error-boundary: "npm:4.0.13"