@centreon/ui 23.10.17 → 23.10.18-MON-17793-create-graph-component-centreon-ui.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/Graph/Axes/UnitLabel.tsx +20 -0
- package/src/Graph/Axes/index.tsx +99 -0
- package/src/Graph/Axes/models.ts +26 -0
- package/src/Graph/Axes/useAxisY.ts +100 -0
- package/src/Graph/Graph.tsx +231 -0
- package/src/Graph/Grids/index.tsx +20 -0
- package/src/Graph/Header/index.tsx +34 -0
- package/src/Graph/InteractionWithGraph/AnchorPoint/RegularAnchorPoint.tsx +88 -0
- package/src/Graph/InteractionWithGraph/AnchorPoint/StackedAnchorPoint.tsx +97 -0
- package/src/Graph/InteractionWithGraph/AnchorPoint/index.tsx +56 -0
- package/src/Graph/InteractionWithGraph/AnchorPoint/models.ts +25 -0
- package/src/Graph/InteractionWithGraph/AnchorPoint/useAnchorPoint.ts +109 -0
- package/src/Graph/InteractionWithGraph/Bar.tsx +21 -0
- package/src/Graph/InteractionWithGraph/ZoomPreview/index.tsx +38 -0
- package/src/Graph/InteractionWithGraph/ZoomPreview/models.ts +17 -0
- package/src/Graph/InteractionWithGraph/ZoomPreview/useZoomPreview.ts +101 -0
- package/src/Graph/InteractionWithGraph/ZoomPreview/zoomPreviewAtoms.ts +5 -0
- package/src/Graph/InteractionWithGraph/index.tsx +93 -0
- package/src/Graph/InteractionWithGraph/interactionWithGraphAtoms.ts +7 -0
- package/src/Graph/InteractionWithGraph/mouseTimeValueAtoms.ts +49 -0
- package/src/Graph/Lines/RegularLines/index.tsx +99 -0
- package/src/Graph/Lines/RegularLines/useRegularLines.ts +15 -0
- package/src/Graph/Lines/StackedLines/index.tsx +74 -0
- package/src/Graph/Lines/StackedLines/useStackedLines.ts +39 -0
- package/src/Graph/Lines/index.tsx +153 -0
- package/src/Graph/Lines/models.ts +32 -0
- package/src/Graph/LoadingProgress.tsx +46 -0
- package/src/Graph/common/index.ts +33 -0
- package/src/Graph/data.json +1338 -0
- package/src/Graph/helpers/doc.ts +323 -0
- package/src/Graph/helpers/index.ts +15 -0
- package/src/Graph/index.stories.tsx +30 -0
- package/src/Graph/index.tsx +66 -0
- package/src/Graph/models.ts +68 -0
- package/src/Graph/timeSeries/index.test.ts +484 -0
- package/src/Graph/timeSeries/index.ts +512 -0
- package/src/Graph/timeSeries/models.ts +119 -0
- package/src/Graph/useGraphData.ts +117 -0
- package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.styles.ts +57 -0
- package/src/TimePeriods/CustomTimePeriod/CompactCustomTimePeriod.tsx +78 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/ErrorText.tsx +14 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/PickersStartEndDate.tsx +169 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/index.tsx +76 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/models.ts +61 -0
- package/src/TimePeriods/CustomTimePeriod/PopoverCustomTimePeriod/usePickersStartEndDate.ts +91 -0
- package/src/TimePeriods/CustomTimePeriod/index.tsx +63 -0
- package/src/TimePeriods/DateTimePickerInput.tsx +99 -0
- package/src/TimePeriods/SelectedTimePeriod.tsx +99 -0
- package/src/TimePeriods/TimePeriods.cypress.spec.tsx +497 -0
- package/src/TimePeriods/helpers/index.ts +25 -0
- package/src/TimePeriods/index.stories.tsx +74 -0
- package/src/TimePeriods/index.tsx +77 -0
- package/src/TimePeriods/models.ts +103 -0
- package/src/TimePeriods/timePeriods.styles.ts +20 -0
- package/src/TimePeriods/timePeriodsAtoms.ts +113 -0
- package/src/TimePeriods/useDateTimePickerAdapter.ts +329 -0
- package/src/TimePeriods/useSortTimePeriods.ts +24 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
|
|
3
|
+
import dayjs from 'dayjs';
|
|
4
|
+
|
|
5
|
+
export const dateFormat = 'L';
|
|
6
|
+
export const timeFormat = 'LT';
|
|
7
|
+
export const dateTimeFormat = `${dateFormat} ${timeFormat}`;
|
|
8
|
+
|
|
9
|
+
export enum CustomTimePeriodProperty {
|
|
10
|
+
end = 'end',
|
|
11
|
+
start = 'start'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface TimePeriod {
|
|
15
|
+
dateTimeFormat: string;
|
|
16
|
+
getStart: () => Date;
|
|
17
|
+
id: string;
|
|
18
|
+
largeName: string;
|
|
19
|
+
name: string;
|
|
20
|
+
timelineEventsLimit: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const label1Day = '1 day';
|
|
24
|
+
export const label7Days = '7 days';
|
|
25
|
+
export const label31Days = '31 days';
|
|
26
|
+
export const labelLastDay = 'Last day';
|
|
27
|
+
export const labelLast7Days = 'Last 7 days';
|
|
28
|
+
export const labelLast31Days = 'Last 31 days';
|
|
29
|
+
|
|
30
|
+
export const lastDayPeriod: TimePeriod = {
|
|
31
|
+
dateTimeFormat: timeFormat,
|
|
32
|
+
getStart: (): Date => dayjs(Date.now()).subtract(24, 'hour').toDate(),
|
|
33
|
+
id: 'last_24_h',
|
|
34
|
+
largeName: labelLastDay,
|
|
35
|
+
name: label1Day,
|
|
36
|
+
timelineEventsLimit: 20
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const last7Days: TimePeriod = {
|
|
40
|
+
dateTimeFormat: dateFormat,
|
|
41
|
+
getStart: (): Date => dayjs(Date.now()).subtract(7, 'day').toDate(),
|
|
42
|
+
id: 'last_7_days',
|
|
43
|
+
largeName: labelLast7Days,
|
|
44
|
+
name: label7Days,
|
|
45
|
+
timelineEventsLimit: 100
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const last31Days: TimePeriod = {
|
|
49
|
+
dateTimeFormat: dateFormat,
|
|
50
|
+
getStart: (): Date => dayjs(Date.now()).subtract(31, 'day').toDate(),
|
|
51
|
+
id: 'last_31_days',
|
|
52
|
+
largeName: labelLast31Days,
|
|
53
|
+
name: label31Days,
|
|
54
|
+
timelineEventsLimit: 500
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const timePeriods: Array<TimePeriod> = [
|
|
58
|
+
lastDayPeriod,
|
|
59
|
+
last7Days,
|
|
60
|
+
last31Days
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
export interface TimePeriodById {
|
|
64
|
+
id: string;
|
|
65
|
+
timePeriods: Array<TimePeriod>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface CustomTimePeriod {
|
|
69
|
+
end: Date;
|
|
70
|
+
start: Date;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface DateTimePickerInputModel {
|
|
74
|
+
changeDate: (props) => void;
|
|
75
|
+
date: Date | dayjs.Dayjs | null;
|
|
76
|
+
disabled?: boolean;
|
|
77
|
+
maxDate?: Date | dayjs.Dayjs;
|
|
78
|
+
minDate?: Date | dayjs.Dayjs;
|
|
79
|
+
onClosePicker?: (isClosed: boolean) => void;
|
|
80
|
+
property: CustomTimePeriodProperty;
|
|
81
|
+
setDate: Dispatch<SetStateAction<Date | null>>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface GetNewCustomTimePeriodProps {
|
|
85
|
+
end: Date;
|
|
86
|
+
start: Date;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export interface TimeLineAxisTickFormat extends CustomTimePeriod {
|
|
90
|
+
timeLineLimit: number;
|
|
91
|
+
xAxisTickFormat: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface GraphQueryParametersProps {
|
|
95
|
+
endDate?: Date;
|
|
96
|
+
startDate?: Date;
|
|
97
|
+
timePeriod?: TimePeriod | null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface EndStartInterval {
|
|
101
|
+
end: string;
|
|
102
|
+
start: string;
|
|
103
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { makeStyles } from 'tss-react/mui';
|
|
2
|
+
|
|
3
|
+
interface StylesProps {
|
|
4
|
+
disabled: boolean;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const useStyles = makeStyles<StylesProps>()((theme, { disabled }) => ({
|
|
8
|
+
header: {
|
|
9
|
+
alignItems: 'center',
|
|
10
|
+
backgroundColor: disabled ? 'transparent' : 'undefined',
|
|
11
|
+
border: disabled ? 'unset' : 'undefined',
|
|
12
|
+
boxShadow: disabled ? 'unset' : 'undefined',
|
|
13
|
+
columnGap: theme.spacing(2),
|
|
14
|
+
display: 'grid',
|
|
15
|
+
gridTemplateColumns: `repeat(4, auto)`,
|
|
16
|
+
gridTemplateRows: '1fr',
|
|
17
|
+
justifyContent: 'center',
|
|
18
|
+
padding: theme.spacing(1, 0.5)
|
|
19
|
+
}
|
|
20
|
+
}));
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { atom } from 'jotai';
|
|
2
|
+
import { isNil, not, pipe } from 'ramda';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
defaultTimePeriod,
|
|
6
|
+
getTimePeriodById,
|
|
7
|
+
getTimePeriodFromNow
|
|
8
|
+
} from './helpers';
|
|
9
|
+
import {
|
|
10
|
+
GraphQueryParametersProps,
|
|
11
|
+
TimePeriod,
|
|
12
|
+
TimePeriodById
|
|
13
|
+
} from './models';
|
|
14
|
+
|
|
15
|
+
export const selectedTimePeriodAtom = atom<TimePeriod | null>(
|
|
16
|
+
defaultTimePeriod
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const defaultCustomTimePeriod = getTimePeriodFromNow(defaultTimePeriod);
|
|
20
|
+
|
|
21
|
+
export const customTimePeriodAtom = atom(defaultCustomTimePeriod);
|
|
22
|
+
|
|
23
|
+
export const errorTimePeriodAtom = atom(false);
|
|
24
|
+
|
|
25
|
+
export const changeSelectedTimePeriodDerivedAtom = atom(
|
|
26
|
+
null,
|
|
27
|
+
(_, set, { id, timePeriods }: TimePeriodById) => {
|
|
28
|
+
const timePeriod = getTimePeriodById({ id, timePeriods });
|
|
29
|
+
|
|
30
|
+
set(selectedTimePeriodAtom, timePeriod);
|
|
31
|
+
|
|
32
|
+
const newCustomTimePeriod = getTimePeriodFromNow(timePeriod);
|
|
33
|
+
|
|
34
|
+
set(customTimePeriodAtom, newCustomTimePeriod);
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
export const changeCustomTimePeriodDerivedAtom = atom(
|
|
39
|
+
null,
|
|
40
|
+
(get, set, { date, property }) => {
|
|
41
|
+
const customTimePeriod = get(customTimePeriodAtom);
|
|
42
|
+
|
|
43
|
+
const newCustomTimePeriod = {
|
|
44
|
+
...customTimePeriod,
|
|
45
|
+
[property]: date
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
set(customTimePeriodAtom, newCustomTimePeriod);
|
|
49
|
+
set(selectedTimePeriodAtom, null);
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
export const getDatesDerivedAtom = atom(
|
|
54
|
+
(get) =>
|
|
55
|
+
(timePeriod?: TimePeriod | null): [string, string] => {
|
|
56
|
+
const customTimePeriod = get(customTimePeriodAtom);
|
|
57
|
+
|
|
58
|
+
if (isNil(timePeriod)) {
|
|
59
|
+
return [
|
|
60
|
+
customTimePeriod.start.toISOString(),
|
|
61
|
+
customTimePeriod.end.toISOString()
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
timePeriod.getStart().toISOString(),
|
|
67
|
+
new Date(Date.now()).toISOString()
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
export const graphQueryParametersDerivedAtom = atom(
|
|
73
|
+
(get) =>
|
|
74
|
+
({ timePeriod, startDate, endDate }: GraphQueryParametersProps): string => {
|
|
75
|
+
const getDates = get(getDatesDerivedAtom);
|
|
76
|
+
|
|
77
|
+
if (pipe(isNil, not)(timePeriod)) {
|
|
78
|
+
const [start, end] = getDates(timePeriod);
|
|
79
|
+
|
|
80
|
+
return `?start=${start}&end=${end}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return `?start=${startDate?.toISOString()}&end=${endDate?.toISOString()}`;
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// a deplacer le timelinelimit vers le graph
|
|
88
|
+
|
|
89
|
+
// export const getNewTimeLineLimitAndAxisTickFormat = ({
|
|
90
|
+
// start,
|
|
91
|
+
// end
|
|
92
|
+
// }: GetNewCustomTimePeriodProps): TimeLineAxisTickFormat => {
|
|
93
|
+
// const customTimePeriodInDay = dayjs
|
|
94
|
+
// .duration(dayjs(end).diff(dayjs(start)))
|
|
95
|
+
// .asDays();
|
|
96
|
+
|
|
97
|
+
// const xAxisTickFormat = gte(customTimePeriodInDay, 2)
|
|
98
|
+
// ? dateFormat
|
|
99
|
+
// : timeFormat;
|
|
100
|
+
|
|
101
|
+
// const timelineLimit = cond<number, number>([
|
|
102
|
+
// [gte(1), always(20)],
|
|
103
|
+
// [gte(7), always(100)],
|
|
104
|
+
// [T, always(500)]
|
|
105
|
+
// ])(customTimePeriodInDay);
|
|
106
|
+
|
|
107
|
+
// return {
|
|
108
|
+
// end,
|
|
109
|
+
// start,
|
|
110
|
+
// timelineLimit,
|
|
111
|
+
// xAxisTickFormat
|
|
112
|
+
// };
|
|
113
|
+
// };
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/* eslint-disable class-methods-use-this */
|
|
2
|
+
import { useCallback } from 'react';
|
|
3
|
+
|
|
4
|
+
import DayjsAdapter from '@date-io/dayjs';
|
|
5
|
+
import dayjs from 'dayjs';
|
|
6
|
+
import { useAtomValue } from 'jotai';
|
|
7
|
+
import { equals, isNil, not, pipe } from 'ramda';
|
|
8
|
+
|
|
9
|
+
import { useLocaleDateTimeFormat } from '@centreon/ui';
|
|
10
|
+
import { userAtom } from '@centreon/ui-context';
|
|
11
|
+
|
|
12
|
+
interface UseDateTimePickerAdapterProps {
|
|
13
|
+
Adapter;
|
|
14
|
+
formatKeyboardValue: (value?: string) => string | undefined;
|
|
15
|
+
getDestinationAndConfiguredTimezoneOffset: (
|
|
16
|
+
destinationTimezone?: string
|
|
17
|
+
) => number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
enum DSTState {
|
|
21
|
+
SUMMER,
|
|
22
|
+
WINTER,
|
|
23
|
+
NODST
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface ToTimezonedDateProps {
|
|
27
|
+
date: Date;
|
|
28
|
+
timeZone?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const isSummerDate = equals(DSTState.SUMMER);
|
|
32
|
+
|
|
33
|
+
const useDateTimePickerAdapter = (): UseDateTimePickerAdapterProps => {
|
|
34
|
+
const { timezone, locale } = useAtomValue(userAtom);
|
|
35
|
+
const { format } = useLocaleDateTimeFormat();
|
|
36
|
+
|
|
37
|
+
const normalizedLocale = locale.substring(0, 2);
|
|
38
|
+
|
|
39
|
+
const toTimezonedDate = ({
|
|
40
|
+
date,
|
|
41
|
+
timeZone = undefined
|
|
42
|
+
}: ToTimezonedDateProps): Date => {
|
|
43
|
+
if (isNil(timeZone)) {
|
|
44
|
+
return new Date(date.toLocaleString('en-US'));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new Date(date.toLocaleString('en-US', { timeZone }));
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const getDestinationAndConfiguredTimezoneOffset = (
|
|
51
|
+
destinationTimezone?: string
|
|
52
|
+
): number => {
|
|
53
|
+
const now = new Date();
|
|
54
|
+
const currentTimezoneDate = toTimezonedDate({
|
|
55
|
+
date: now,
|
|
56
|
+
timeZone: destinationTimezone
|
|
57
|
+
});
|
|
58
|
+
const destinationTimezoneDate = toTimezonedDate({
|
|
59
|
+
date: now,
|
|
60
|
+
timeZone: timezone
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
return Math.floor(
|
|
64
|
+
(currentTimezoneDate.getTime() - destinationTimezoneDate.getTime()) /
|
|
65
|
+
60 /
|
|
66
|
+
60 /
|
|
67
|
+
1000
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const getDSTState = useCallback(
|
|
72
|
+
(date: dayjs.Dayjs): DSTState => {
|
|
73
|
+
const currentYear = toTimezonedDate({
|
|
74
|
+
date: new Date(),
|
|
75
|
+
timeZone: timezone
|
|
76
|
+
}).getFullYear();
|
|
77
|
+
|
|
78
|
+
const january = dayjs(new Date(currentYear, 0, 1))
|
|
79
|
+
.tz(timezone)
|
|
80
|
+
.utcOffset();
|
|
81
|
+
const july = dayjs(new Date(currentYear, 6, 1)).tz(timezone).utcOffset();
|
|
82
|
+
|
|
83
|
+
if (equals(january, july)) {
|
|
84
|
+
return DSTState.NODST;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return july === date.utcOffset() ? DSTState.SUMMER : DSTState.WINTER;
|
|
88
|
+
},
|
|
89
|
+
[timezone]
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const formatKeyboardValue = (value?: string): string | undefined => {
|
|
93
|
+
if (equals(normalizedLocale, 'en') || isNil(value)) {
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
const month = value.substring(0, 2);
|
|
97
|
+
const day = value.substring(3, 5);
|
|
98
|
+
|
|
99
|
+
const newValue = `${day}/${month}/${value.substring(6, 16)}`;
|
|
100
|
+
|
|
101
|
+
return newValue;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
interface Chunk {
|
|
105
|
+
array: Array<unknown>;
|
|
106
|
+
size: number;
|
|
107
|
+
}
|
|
108
|
+
class Adapter extends DayjsAdapter {
|
|
109
|
+
public formatByString = (value, formatKey: string): string => {
|
|
110
|
+
return format({
|
|
111
|
+
date: value.tz(timezone),
|
|
112
|
+
formatString: formatKey
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
public isEqual = (value, comparing): boolean => {
|
|
117
|
+
if (value === null && comparing === null) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return equals(
|
|
122
|
+
format({ date: value, formatString: 'LT' }),
|
|
123
|
+
format({ date: comparing, formatString: 'LT' })
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
public format = (date: dayjs.Dayjs, formatKey: string): string => {
|
|
128
|
+
return this.formatByString(
|
|
129
|
+
date.tz(timezone, true),
|
|
130
|
+
this.formats[formatKey]
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
public startOfWeek = (date: dayjs.Dayjs): dayjs.Dayjs => {
|
|
135
|
+
if (date.tz(timezone).isUTC()) {
|
|
136
|
+
return date.tz(timezone).startOf('week').utc();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return date.tz(timezone).startOf('week');
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
public getHours = (date): number => {
|
|
143
|
+
return date.tz(timezone).get('hour');
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
public setHours = (date: dayjs.Dayjs, count: number): dayjs.Dayjs => {
|
|
147
|
+
const dateDSTState = getDSTState(date.tz(timezone));
|
|
148
|
+
|
|
149
|
+
const isNotASummerDate = pipe(isSummerDate, not)(dateDSTState);
|
|
150
|
+
const isInUTC = equals(
|
|
151
|
+
getDestinationAndConfiguredTimezoneOffset('UTC'),
|
|
152
|
+
0
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
if ((isInUTC && isNotASummerDate) || equals('UTC', timezone)) {
|
|
156
|
+
return date
|
|
157
|
+
.tz(timezone)
|
|
158
|
+
.set('hour', count - getDestinationAndConfiguredTimezoneOffset());
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return date.tz(timezone).set('hour', count);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
public isSameHour = (
|
|
165
|
+
date: dayjs.Dayjs,
|
|
166
|
+
comparing: dayjs.Dayjs
|
|
167
|
+
): boolean => {
|
|
168
|
+
return date.tz(timezone).isSame(comparing.tz(timezone), 'hour');
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
public isSameDay = (date: dayjs.Dayjs, comparing: dayjs.Dayjs): boolean => {
|
|
172
|
+
const isSameYearAndMonth = this.isSameYear(date, comparing)
|
|
173
|
+
? this.isSameMonth(date, comparing)
|
|
174
|
+
: false;
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
isSameYearAndMonth &&
|
|
178
|
+
date.tz(timezone).isSame(comparing.tz(timezone), 'day')
|
|
179
|
+
);
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
public startOfDay = (date: dayjs.Dayjs): dayjs.Dayjs => {
|
|
183
|
+
return date.tz(timezone).startOf('day') as dayjs.Dayjs;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
public endOfDay = (date: dayjs.Dayjs): dayjs.Dayjs => {
|
|
187
|
+
return date.tz(timezone).endOf('day') as dayjs.Dayjs;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
public startOfMonth = (date: dayjs.Dayjs): dayjs.Dayjs => {
|
|
191
|
+
if (date.tz(timezone).isUTC()) {
|
|
192
|
+
return date.tz(timezone).utc();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return date.tz(timezone);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
public endOfMonth = (date: dayjs.Dayjs): dayjs.Dayjs => {
|
|
199
|
+
return date.endOf('month') as dayjs.Dayjs;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
public isSameMonth = (
|
|
203
|
+
date: dayjs.Dayjs,
|
|
204
|
+
comparing: dayjs.Dayjs
|
|
205
|
+
): boolean => {
|
|
206
|
+
return date.tz(timezone).isSame(comparing.tz(timezone), 'month');
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
public getMonth = (date: dayjs.Dayjs): number => {
|
|
210
|
+
return date.month();
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
public isAfter = (date: dayjs.Dayjs, value: dayjs.Dayjs): boolean => {
|
|
214
|
+
return date.isAfter(value.endOf('month'));
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
public isBefore = (date: dayjs.Dayjs, value: dayjs.Dayjs): boolean => {
|
|
218
|
+
return date.isBefore(value.startOf('month'));
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
public getDaysInMonth = (date: dayjs.Dayjs): number => {
|
|
222
|
+
return date.tz(timezone).daysInMonth();
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
public getWeekdays = (): Array<string> => {
|
|
226
|
+
const start = dayjs().locale(locale).tz(timezone).startOf('week');
|
|
227
|
+
|
|
228
|
+
return [0, 1, 2, 3, 4, 5, 6].map((diff) =>
|
|
229
|
+
this.formatByString(start.add(diff, 'day'), 'dd')
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
public getChunkFromArray = ({ array, size }: Chunk): Array<unknown> => {
|
|
234
|
+
if (!array.length) {
|
|
235
|
+
return [];
|
|
236
|
+
}
|
|
237
|
+
const head = array.slice(0, size);
|
|
238
|
+
const tail = array.slice(size);
|
|
239
|
+
|
|
240
|
+
return [head, ...this.getChunkFromArray({ array: tail, size })];
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
public getWeekArray = (date: dayjs.Dayjs): Array<Array<dayjs.Dayjs>> => {
|
|
244
|
+
const isMorning = equals(dayjs().tz(timezone).format('a'), 'am');
|
|
245
|
+
|
|
246
|
+
const startOfWeek = date.startOf('month').startOf('week');
|
|
247
|
+
const endOfWeek = date.endOf('month').endOf('week');
|
|
248
|
+
|
|
249
|
+
const start = startOfWeek.endOf('day');
|
|
250
|
+
|
|
251
|
+
const end = endOfWeek.endOf('day');
|
|
252
|
+
const customStart = isMorning
|
|
253
|
+
? startOfWeek.startOf('day')
|
|
254
|
+
: startOfWeek.endOf('day');
|
|
255
|
+
|
|
256
|
+
const customEnd = isMorning
|
|
257
|
+
? endOfWeek.startOf('day')
|
|
258
|
+
: endOfWeek.endOf('day');
|
|
259
|
+
|
|
260
|
+
const currentStart = start.isUTC()
|
|
261
|
+
? start.tz(timezone, true)
|
|
262
|
+
: customStart;
|
|
263
|
+
const currentEnd = end.isUTC() ? end.tz(timezone, true) : customEnd;
|
|
264
|
+
|
|
265
|
+
const numberOfDaysInCurrentMonth = currentEnd.diff(
|
|
266
|
+
currentStart,
|
|
267
|
+
'd',
|
|
268
|
+
true
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
const daysOfMonthWithTimezone = [
|
|
272
|
+
...Array(Math.round(numberOfDaysInCurrentMonth)).keys()
|
|
273
|
+
].reduce(
|
|
274
|
+
(acc, _, currentIndex) => {
|
|
275
|
+
if (acc[currentIndex].isUTC()) {
|
|
276
|
+
const newCurrent = acc[currentIndex]
|
|
277
|
+
.utc()
|
|
278
|
+
.add(1, 'day')
|
|
279
|
+
.tz(timezone, true);
|
|
280
|
+
|
|
281
|
+
return [...acc, newCurrent];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const newCurrent = acc[currentIndex].add(1, 'day');
|
|
285
|
+
|
|
286
|
+
return [...acc, newCurrent];
|
|
287
|
+
},
|
|
288
|
+
[currentStart]
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const weeksArray = this.getChunkFromArray({
|
|
292
|
+
array: daysOfMonthWithTimezone,
|
|
293
|
+
size: 7
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
return weeksArray as Array<Array<dayjs.Dayjs>>;
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
public mergeDateAndTime = (
|
|
300
|
+
date: dayjs.Dayjs,
|
|
301
|
+
time: dayjs.Dayjs
|
|
302
|
+
): dayjs.Dayjs => {
|
|
303
|
+
const dateWithTimezone = date.tz(timezone).startOf('day');
|
|
304
|
+
const timeWithTimezone = time.tz(timezone);
|
|
305
|
+
|
|
306
|
+
const dateDSTState = getDSTState(dateWithTimezone);
|
|
307
|
+
|
|
308
|
+
if (not(equals(dateDSTState, DSTState.SUMMER))) {
|
|
309
|
+
return dateWithTimezone
|
|
310
|
+
.add(timeWithTimezone.hour(), 'hour')
|
|
311
|
+
.add(timeWithTimezone.minute(), 'minute')
|
|
312
|
+
.add(timeWithTimezone.second(), 'second');
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return dateWithTimezone
|
|
316
|
+
.hour(timeWithTimezone.hour())
|
|
317
|
+
.minute(timeWithTimezone.minute())
|
|
318
|
+
.second(timeWithTimezone.second());
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
Adapter,
|
|
324
|
+
formatKeyboardValue,
|
|
325
|
+
getDestinationAndConfiguredTimezoneOffset
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
export default useDateTimePickerAdapter;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
|
|
3
|
+
import { getTimePeriodFromNow } from './helpers';
|
|
4
|
+
import { TimePeriod } from './models';
|
|
5
|
+
|
|
6
|
+
const useSortTimePeriods = (
|
|
7
|
+
timePeriods: Array<TimePeriod>
|
|
8
|
+
): Array<TimePeriod> => {
|
|
9
|
+
const adjustedTimePeriods = timePeriods.map((item) => {
|
|
10
|
+
const { end, start } = getTimePeriodFromNow(item);
|
|
11
|
+
|
|
12
|
+
const numberOfDays = dayjs.duration(dayjs(end).diff(dayjs(start))).asDays();
|
|
13
|
+
|
|
14
|
+
return { item, numberOfDays };
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const sortedTimePeriods = adjustedTimePeriods.sort(
|
|
18
|
+
(a, b) => a.numberOfDays - b.numberOfDays
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return sortedTimePeriods.map((element) => element.item);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default useSortTimePeriods;
|