Skip to content

Commit

Permalink
[DOP-22993] rewrite cronService
Browse files Browse the repository at this point in the history
  • Loading branch information
Zabilsya committed Jan 17, 2025
1 parent bb21ccc commit 5719a27
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 81 deletions.
77 changes: 51 additions & 26 deletions src/shared/services/cronService/cronService.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { getOrdinalNumber } from '@shared/utils';

import { CRON_VALUE_DEFAULT, DAYS_OF_WEEK } from './constants';
import { CronSegmentKey, CronSegmentValue } from './types';
import { CronSegmentKey, CronSegmentValue, Period } from './types';

/** Class for convenient handling cron settings */
export class CronService {
private initialValueLength = 5;

private period: Period;

private value: Map<CronSegmentKey, CronSegmentValue>;

constructor(initialValue?: string) {
this.value = this.transformInitialValueToMap(initialValue);
this.period = this.initPeriod();
}

private transformInitialValueToMap(initialValue?: string) {
Expand All @@ -35,6 +38,20 @@ export class CronService {
]);
}

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')!;
}
Expand All @@ -43,6 +60,10 @@ export class CronService {
return this.value.get('hour')!;
}

getTime() {
return `${this.getHour()}:${this.getMinute()}`;
}

getMonthDay(): CronSegmentValue {
return this.value.get('date') ?? null;
}
Expand All @@ -51,24 +72,40 @@ export class CronService {
return this.value.get('day') ?? null;
}

getTime() {
return `${this.getHour()}:${this.getMinute()}`;
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) {
this.value.set('minute', new Date().getMinutes());
} else {
this.value.set('minute', value);
throw new Error('Invalid value');
}
this.value.set('minute', value);
}

setHour(value: number) {
if (value < 0 || value > 23) {
this.value.set('hour', new Date().getHours());
} else {
this.value.set('hour', value);
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) {
Expand All @@ -77,11 +114,9 @@ export class CronService {
return;
}
if (value < 1 || value > 31) {
this.value.set('date', new Date().getDate());
} else {
this.value.set('date', value);
throw new Error('Invalid value');
}
this.setWeekDay(null);
this.value.set('date', value);
}

setWeekDay(value: CronSegmentValue) {
Expand All @@ -90,11 +125,9 @@ export class CronService {
return;
}
if (value < 0 || value > 6) {
this.value.set('day', new Date().getDay());
} else {
this.value.set('day', value);
throw new Error('Invalid value');
}
this.setMonthDay(null);
this.value.set('day', value);
}

toString() {
Expand All @@ -110,15 +143,7 @@ export class CronService {
const day = this.getWeekDay();
const date = this.getMonthDay();

let schedule = 'Every ';

if (day === null && !date) {
schedule += 'day ';
} else if (day !== null && !date) {
schedule += 'week ';
} else {
schedule += 'month ';
}
let schedule = `Every ${this.period} `;

if (day !== null) {
schedule += `on ${DAYS_OF_WEEK[day]} `;
Expand Down
6 changes: 6 additions & 0 deletions src/shared/services/cronService/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ 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,
Expand Down
12 changes: 3 additions & 9 deletions src/shared/ui/CronSelect/components/DynamicSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
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 { Period } from '../../types';

import { DynamicSelectProps } from './types';

export const DynamicSelect = ({
periodSelectValue,
weekDay,
monthDay,
onChangeWeekDay,
onChangeMonthDay,
}: DynamicSelectProps) => {
switch (periodSelectValue) {
export const DynamicSelect = ({ period, weekDay, monthDay, onChangeWeekDay, onChangeMonthDay }: DynamicSelectProps) => {
switch (period) {
case Period.WEEK:
return (
<Select
Expand Down
6 changes: 2 additions & 4 deletions src/shared/ui/CronSelect/components/DynamicSelect/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { CronSegmentValue } from '@shared/services';

import { Period } from '../../types';
import { CronSegmentValue, Period } from '@shared/services';

/** Interface as Props for component "DynamicSelect" */
export interface DynamicSelectProps {
/** Value of period Select */
periodSelectValue: Period;
period: Period;
/** Value of week day Select */
weekDay: CronSegmentValue;
/** Value of month day Select */
Expand Down
4 changes: 1 addition & 3 deletions src/shared/ui/CronSelect/constants.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { DayOfWeek, DayOfWeekName } from '@shared/services';
import { DayOfWeek, DayOfWeekName, Period } from '@shared/services';
import { prepareOptionsForSelect } from '@shared/ui';

import { Period } from './types';

export const PERIOD_SELECT_OPTIONS = prepareOptionsForSelect({
data: Object.values(Period),
renderLabel: (data) => data,
Expand Down
32 changes: 4 additions & 28 deletions src/shared/ui/CronSelect/hooks/useCron/useCron.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { CronSegmentValue, CronService } from '@shared/services';
import { CronSegmentValue, CronService, Period } from '@shared/services';
import dayjs, { Dayjs } from 'dayjs';

import { Period } from '../../types';

import { UseCronProps } from './types';

/** Hook for handling value of CronSelect component */
Expand All @@ -12,18 +10,7 @@ export const useCron = ({ value, onChange = () => undefined }: UseCronProps) =>
const handleChange = () => onChange(cronService.toString());

const handleChangePeriod = (period: Period) => {
switch (period) {
case Period.DAY:
cronService.setMonthDay(null);
cronService.setWeekDay(null);
break;
case Period.WEEK:
cronService.setWeekDay(dayjs().day());
break;
case Period.MONTH:
cronService.setMonthDay(dayjs().date());
break;
}
cronService.setPeriod(period);
handleChange();
};

Expand All @@ -38,23 +25,12 @@ export const useCron = ({ value, onChange = () => undefined }: UseCronProps) =>
};

const handleChangeTime = (time: Dayjs | null) => {
cronService.setMinute(time?.minute() ?? dayjs().minute());
cronService.setHour(time?.hour() ?? dayjs().hour());
cronService.setTime(time?.hour(), time?.minute());
handleChange();
};

const getPeriodSelectValue = () => {
if (cronService.getMonthDay() === null && cronService.getWeekDay() === null) {
return Period.DAY;
}
if (cronService.getMonthDay()) {
return Period.MONTH;
}
return Period.WEEK;
};

return {
periodSelectValue: getPeriodSelectValue(),
period: cronService.getPeriod(),
weekDay: cronService.getWeekDay(),
monthDay: cronService.getMonthDay(),
time: dayjs(cronService.getTime(), 'HH:mm'),
Expand Down
11 changes: 6 additions & 5 deletions src/shared/ui/CronSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
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, Period } from './types';
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 {
periodSelectValue,
period,
weekDay,
monthDay,
time,
Expand All @@ -28,16 +29,16 @@ export const CronSelect = memo(({ value, onChange }: CronSelectProps) => {
className={classes.period}
size="large"
onChange={handleChangePeriod}
value={periodSelectValue}
value={period}
options={PERIOD_SELECT_OPTIONS}
/>
</div>

{periodSelectValue !== Period.DAY && (
{period !== Period.DAY && (
<div className={classes.segment}>
<span>On:</span>
<DynamicSelect
periodSelectValue={periodSelectValue}
period={period}
weekDay={weekDay}
monthDay={monthDay}
onChangeWeekDay={handleChangeWeekDay}
Expand Down
6 changes: 0 additions & 6 deletions src/shared/ui/CronSelect/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import { UseCronProps } from './hooks';

export interface CronSelectProps extends UseCronProps {}

export enum Period {
DAY = 'day',
WEEK = 'week',
MONTH = 'month',
}

0 comments on commit 5719a27

Please sign in to comment.