@astral/ui 4.51.0 → 4.52.1
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/components/DashboardContext/DashboardContext.d.ts +2 -0
- package/components/DashboardContext/DashboardContext.js +2 -0
- package/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.d.ts +2 -2
- package/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js +4 -1
- package/components/DashboardLayout/DashboardLayout.d.ts +1 -1
- package/components/DashboardLayout/DashboardLayout.js +2 -2
- package/components/DashboardLayout/Header/Header.js +28 -3
- package/components/DashboardLayout/Header/constants.d.ts +5 -1
- package/components/DashboardLayout/Header/constants.js +5 -1
- package/components/DashboardLayout/Header/styles.d.ts +4 -3
- package/components/DashboardLayout/Header/styles.js +66 -24
- package/components/DashboardLayout/Header/useLogic/useLogic.d.ts +4 -1
- package/components/DashboardLayout/Header/useLogic/useLogic.js +16 -11
- package/components/DashboardLayout/types.d.ts +5 -0
- package/components/DashboardSidebar/DashboardSidebar.js +17 -2
- package/components/DashboardSidebar/constants.d.ts +1 -0
- package/components/DashboardSidebar/constants.js +1 -0
- package/components/DashboardSidebar/styles.js +1 -1
- package/components/DashboardSidebar/useLogic/useLogic.d.ts +2 -1
- package/components/DashboardSidebar/useLogic/useLogic.js +5 -6
- package/components/DatePicker/hooks/useDatePickerOptions/useDatePickerOptions.d.ts +2 -0
- package/components/DatePicker/hooks/useDatePickerOptions/useDatePickerOptions.js +2 -1
- package/components/DatePicker/hooks/useMaskedValue/useMaskedValue.d.ts +4 -0
- package/components/DatePicker/hooks/useMaskedValue/useMaskedValue.js +37 -8
- package/components/DatePicker/useLogic/useLogic.d.ts +1 -0
- package/components/DatePicker/useLogic/useLogic.js +19 -13
- package/components/DateRangePicker/useLogic/useLogic.d.ts +2 -0
- package/components/DateRangePicker/useLogic/useLogic.js +27 -3
- package/components/DateRangePicker/useLogic/utils/index.d.ts +0 -1
- package/components/DateRangePicker/useLogic/utils/index.js +0 -1
- package/components/MenuOrganization/OrganizationButton/OrganizationButton.js +1 -1
- package/components/MenuOrganization/constants.d.ts +1 -0
- package/components/MenuOrganization/constants.js +1 -0
- package/components/Profile/Profile.js +1 -1
- package/components/Profile/constants.d.ts +3 -0
- package/components/Profile/constants.js +3 -0
- package/components/utils/date/format/index.d.ts +1 -0
- package/components/utils/date/format/index.js +1 -0
- package/{node/components/DateRangePicker/useLogic/utils → components/utils/date/format}/isMaskedDateSyntacticallyComplete/isMaskedDateSyntacticallyComplete.d.ts +1 -1
- package/components/utils/date/format/parseDate/parseDate.d.ts +1 -0
- package/components/utils/date/format/parseDate/parseDate.js +42 -13
- package/node/components/DashboardContext/DashboardContext.d.ts +2 -0
- package/node/components/DashboardContext/DashboardContext.js +2 -0
- package/node/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.d.ts +2 -2
- package/node/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js +4 -1
- package/node/components/DashboardLayout/DashboardLayout.d.ts +1 -1
- package/node/components/DashboardLayout/DashboardLayout.js +2 -2
- package/node/components/DashboardLayout/Header/Header.js +27 -2
- package/node/components/DashboardLayout/Header/constants.d.ts +5 -1
- package/node/components/DashboardLayout/Header/constants.js +5 -1
- package/node/components/DashboardLayout/Header/styles.d.ts +4 -3
- package/node/components/DashboardLayout/Header/styles.js +74 -32
- package/node/components/DashboardLayout/Header/useLogic/useLogic.d.ts +4 -1
- package/node/components/DashboardLayout/Header/useLogic/useLogic.js +15 -10
- package/node/components/DashboardLayout/types.d.ts +5 -0
- package/node/components/DashboardSidebar/DashboardSidebar.js +17 -2
- package/node/components/DashboardSidebar/constants.d.ts +1 -0
- package/node/components/DashboardSidebar/constants.js +1 -0
- package/node/components/DashboardSidebar/styles.js +1 -1
- package/node/components/DashboardSidebar/useLogic/useLogic.d.ts +2 -1
- package/node/components/DashboardSidebar/useLogic/useLogic.js +4 -5
- package/node/components/DatePicker/hooks/useDatePickerOptions/useDatePickerOptions.d.ts +2 -0
- package/node/components/DatePicker/hooks/useDatePickerOptions/useDatePickerOptions.js +2 -1
- package/node/components/DatePicker/hooks/useMaskedValue/useMaskedValue.d.ts +4 -0
- package/node/components/DatePicker/hooks/useMaskedValue/useMaskedValue.js +35 -6
- package/node/components/DatePicker/useLogic/useLogic.d.ts +1 -0
- package/node/components/DatePicker/useLogic/useLogic.js +19 -13
- package/node/components/DateRangePicker/useLogic/useLogic.d.ts +2 -0
- package/node/components/DateRangePicker/useLogic/useLogic.js +28 -4
- package/node/components/DateRangePicker/useLogic/utils/index.d.ts +0 -1
- package/node/components/DateRangePicker/useLogic/utils/index.js +0 -1
- package/node/components/MenuOrganization/OrganizationButton/OrganizationButton.js +1 -1
- package/node/components/MenuOrganization/constants.d.ts +1 -0
- package/node/components/MenuOrganization/constants.js +1 -0
- package/node/components/Profile/Profile.js +1 -1
- package/node/components/Profile/constants.d.ts +3 -0
- package/node/components/Profile/constants.js +3 -0
- package/node/components/utils/date/format/index.d.ts +1 -0
- package/node/components/utils/date/format/index.js +1 -0
- package/{components/DateRangePicker/useLogic/utils → node/components/utils/date/format}/isMaskedDateSyntacticallyComplete/isMaskedDateSyntacticallyComplete.d.ts +1 -1
- package/node/components/utils/date/format/parseDate/parseDate.d.ts +1 -0
- package/node/components/utils/date/format/parseDate/parseDate.js +45 -13
- package/package.json +1 -1
- /package/components/{DateRangePicker/useLogic/utils → utils/date/format}/isMaskedDateSyntacticallyComplete/index.d.ts +0 -0
- /package/components/{DateRangePicker/useLogic/utils → utils/date/format}/isMaskedDateSyntacticallyComplete/index.js +0 -0
- /package/components/{DateRangePicker/useLogic/utils → utils/date/format}/isMaskedDateSyntacticallyComplete/isMaskedDateSyntacticallyComplete.js +0 -0
- /package/node/components/{DateRangePicker/useLogic/utils → utils/date/format}/isMaskedDateSyntacticallyComplete/index.d.ts +0 -0
- /package/node/components/{DateRangePicker/useLogic/utils → utils/date/format}/isMaskedDateSyntacticallyComplete/index.js +0 -0
- /package/node/components/{DateRangePicker/useLogic/utils → utils/date/format}/isMaskedDateSyntacticallyComplete/isMaskedDateSyntacticallyComplete.js +0 -0
|
@@ -4,7 +4,6 @@ import { usePopover } from '../../usePopover';
|
|
|
4
4
|
import { useViewportType } from '../../useViewportType';
|
|
5
5
|
import { DEFAULT_DATE_MASK } from '../constants';
|
|
6
6
|
import { useDatePickerOptions } from '../hooks/useDatePickerOptions';
|
|
7
|
-
import { useMaskedValue } from '../hooks/useMaskedValue';
|
|
8
7
|
import { DEFAULT_MAX_DATE, DEFAULT_MIN_DATE } from '../MinMaxDateContext';
|
|
9
8
|
export const useLogic = ({ label, value, maxDate = DEFAULT_MAX_DATE, minDate = DEFAULT_MIN_DATE, mask = DEFAULT_DATE_MASK, onOpen, onClose, onBlur, onChange, forwardedRef, }) => {
|
|
10
9
|
const ref = useForwardedRef(forwardedRef);
|
|
@@ -12,21 +11,11 @@ export const useLogic = ({ label, value, maxDate = DEFAULT_MAX_DATE, minDate = D
|
|
|
12
11
|
const { isOpen, actions } = usePopover();
|
|
13
12
|
const { open, close } = actions;
|
|
14
13
|
const { isMobile } = useViewportType();
|
|
15
|
-
const { maskedValue } = useMaskedValue({
|
|
16
|
-
currentValue: value,
|
|
17
|
-
mask,
|
|
18
|
-
onChangeValue: onChange,
|
|
19
|
-
});
|
|
20
14
|
const isTitleShow = isMobile && typeof label === 'string';
|
|
21
15
|
const handleOpen = (event) => {
|
|
22
16
|
onOpen?.();
|
|
23
17
|
open(event);
|
|
24
18
|
};
|
|
25
|
-
const handleClose = () => {
|
|
26
|
-
onBlur?.();
|
|
27
|
-
onClose?.();
|
|
28
|
-
close();
|
|
29
|
-
};
|
|
30
19
|
const handleDayPick = (date) => {
|
|
31
20
|
if (isMobile) {
|
|
32
21
|
setSelectedDate(date);
|
|
@@ -39,7 +28,7 @@ export const useLogic = ({ label, value, maxDate = DEFAULT_MAX_DATE, minDate = D
|
|
|
39
28
|
onChange?.(date);
|
|
40
29
|
}
|
|
41
30
|
};
|
|
42
|
-
const { onAccept, inputProps: calculatedInputProps, pickerProps, } = useDatePickerOptions({
|
|
31
|
+
const { onAccept, inputProps: calculatedInputProps, pickerProps, onMaskedValueBlur, } = useDatePickerOptions({
|
|
43
32
|
currentValue: value,
|
|
44
33
|
maxDate,
|
|
45
34
|
minDate,
|
|
@@ -47,6 +36,22 @@ export const useLogic = ({ label, value, maxDate = DEFAULT_MAX_DATE, minDate = D
|
|
|
47
36
|
onDatePick: handleDayPick,
|
|
48
37
|
onChange: handleChange,
|
|
49
38
|
});
|
|
39
|
+
/** Blur: неполный ввод -Invalid Date в onChange (при isMobile onChange не шлём), потом внешний onBlur. */
|
|
40
|
+
const flushMaskedValueAndCallOnBlur = () => {
|
|
41
|
+
onMaskedValueBlur();
|
|
42
|
+
onBlur?.();
|
|
43
|
+
};
|
|
44
|
+
function handleClose() {
|
|
45
|
+
flushMaskedValueAndCallOnBlur();
|
|
46
|
+
onClose?.();
|
|
47
|
+
close();
|
|
48
|
+
}
|
|
49
|
+
const handleInputBlur = () => {
|
|
50
|
+
if (isOpen) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
flushMaskedValueAndCallOnBlur();
|
|
54
|
+
};
|
|
50
55
|
const handleConfirm = () => {
|
|
51
56
|
onChange?.(selectedDate);
|
|
52
57
|
handleClose();
|
|
@@ -58,7 +63,8 @@ export const useLogic = ({ label, value, maxDate = DEFAULT_MAX_DATE, minDate = D
|
|
|
58
63
|
title: isTitleShow ? label : undefined,
|
|
59
64
|
};
|
|
60
65
|
const DatePickerInputProps = {
|
|
61
|
-
value:
|
|
66
|
+
value: calculatedInputProps.value,
|
|
67
|
+
onBlur: handleInputBlur,
|
|
62
68
|
};
|
|
63
69
|
const confirmButtonProps = {
|
|
64
70
|
onClick: handleConfirm,
|
|
@@ -7,12 +7,14 @@ export declare const useLogic: ({ value, minDate, maxDate, mask, onChange, onOpe
|
|
|
7
7
|
ref: import("react").RefObject<HTMLInputElement | null>;
|
|
8
8
|
value: string;
|
|
9
9
|
onAccept: (_: string, maskRef: IMask.InputMask<IMask.AnyMaskedOptions>) => void;
|
|
10
|
+
onBlur: () => void;
|
|
10
11
|
onClick: (e: SyntheticEvent) => void;
|
|
11
12
|
};
|
|
12
13
|
endDatePickerInputProps: {
|
|
13
14
|
ref: import("react").RefObject<HTMLInputElement | null>;
|
|
14
15
|
value: string;
|
|
15
16
|
onAccept: (_: string, maskRef: IMask.InputMask<IMask.AnyMaskedOptions>) => void;
|
|
17
|
+
onBlur: () => void;
|
|
16
18
|
onClick: (e: SyntheticEvent) => void;
|
|
17
19
|
};
|
|
18
20
|
popoverHoveredContextProviderProps: {
|
|
@@ -2,8 +2,9 @@ import { useEffect, useRef, useState, } from 'react';
|
|
|
2
2
|
import { DEFAULT_DATE_MASK, DEFAULT_MAX_DATE, DEFAULT_MIN_DATE, useMaskedValue, useSelectedBaseDate, } from '../../DatePicker';
|
|
3
3
|
import { useForwardedRef } from '../../useForwardedRef';
|
|
4
4
|
import { usePopover } from '../../usePopover';
|
|
5
|
+
import { isMaskedDateSyntacticallyComplete } from '../../utils/date';
|
|
5
6
|
import { useBaseRangeDates } from './hooks';
|
|
6
|
-
import { getBoundaryDate
|
|
7
|
+
import { getBoundaryDate } from './utils';
|
|
7
8
|
export const useLogic = ({ value, minDate = DEFAULT_MIN_DATE, maxDate = DEFAULT_MAX_DATE, mask = DEFAULT_DATE_MASK, onChange, onOpen, onClose, onBlur, }, forwardedRef) => {
|
|
8
9
|
const ref = useForwardedRef(forwardedRef);
|
|
9
10
|
const startInputRef = useRef(null);
|
|
@@ -65,12 +66,12 @@ export const useLogic = ({ value, minDate = DEFAULT_MIN_DATE, maxDate = DEFAULT_
|
|
|
65
66
|
}
|
|
66
67
|
onChange?.({ ...value, end: endDateValue });
|
|
67
68
|
};
|
|
68
|
-
const { maskedValue: startMaskedValue, onMaskedValueChange: onMaskedStartValueChange, onMaskedDateChange: onMaskedStartDateChange, } = useMaskedValue({
|
|
69
|
+
const { maskedValue: startMaskedValue, onMaskedValueChange: onMaskedStartValueChange, onMaskedValueBlur: onMaskedStartValueBlur, onMaskedDateChange: onMaskedStartDateChange, } = useMaskedValue({
|
|
69
70
|
currentValue: value?.start,
|
|
70
71
|
mask,
|
|
71
72
|
onChangeValue: handleChangeStartDate,
|
|
72
73
|
});
|
|
73
|
-
const { maskedValue: endMaskedValue, onMaskedValueChange: onMaskedEndValueChange, onMaskedDateChange: onMaskedEndDateChange, } = useMaskedValue({
|
|
74
|
+
const { maskedValue: endMaskedValue, onMaskedValueChange: onMaskedEndValueChange, onMaskedValueBlur: onMaskedEndValueBlur, onMaskedDateChange: onMaskedEndDateChange, } = useMaskedValue({
|
|
74
75
|
currentValue: value?.end,
|
|
75
76
|
mask,
|
|
76
77
|
onChangeValue: handleChangeEndDate,
|
|
@@ -79,11 +80,32 @@ export const useLogic = ({ value, minDate = DEFAULT_MIN_DATE, maxDate = DEFAULT_
|
|
|
79
80
|
onOpen?.();
|
|
80
81
|
open(event);
|
|
81
82
|
};
|
|
83
|
+
const flushActiveMaskedValueOnClose = () => {
|
|
84
|
+
if (activeInput === 'startDate') {
|
|
85
|
+
onMaskedStartValueBlur();
|
|
86
|
+
}
|
|
87
|
+
if (activeInput === 'endDate') {
|
|
88
|
+
onMaskedEndValueBlur();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
82
91
|
const handleClose = () => {
|
|
92
|
+
flushActiveMaskedValueOnClose();
|
|
83
93
|
onBlur?.();
|
|
84
94
|
onClose?.();
|
|
85
95
|
close();
|
|
86
96
|
};
|
|
97
|
+
const handleStartInputBlur = () => {
|
|
98
|
+
if (isOpen) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
onMaskedStartValueBlur();
|
|
102
|
+
};
|
|
103
|
+
const handleEndInputBlur = () => {
|
|
104
|
+
if (isOpen) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
onMaskedEndValueBlur();
|
|
108
|
+
};
|
|
87
109
|
const handleClickStartInput = (e) => {
|
|
88
110
|
setActiveInput('startDate');
|
|
89
111
|
startInputRef.current?.focus();
|
|
@@ -138,12 +160,14 @@ export const useLogic = ({ value, minDate = DEFAULT_MIN_DATE, maxDate = DEFAULT_
|
|
|
138
160
|
ref: startInputRef,
|
|
139
161
|
value: startMaskedValue,
|
|
140
162
|
onAccept: handleAcceptStart,
|
|
163
|
+
onBlur: handleStartInputBlur,
|
|
141
164
|
onClick: handleClickStartInput,
|
|
142
165
|
},
|
|
143
166
|
endDatePickerInputProps: {
|
|
144
167
|
ref: endInputRef,
|
|
145
168
|
value: endMaskedValue,
|
|
146
169
|
onAccept: handleAcceptEnd,
|
|
170
|
+
onBlur: handleEndInputBlur,
|
|
147
171
|
onClick: handleClickEndInput,
|
|
148
172
|
},
|
|
149
173
|
popoverHoveredContextProviderProps: {
|
|
@@ -13,7 +13,7 @@ export const OrganizationButton = forwardRef(({ onClick, isOpen, currentOrganiza
|
|
|
13
13
|
});
|
|
14
14
|
const renderButton = () => (_jsx(StyledButton, { ref: ref, variant: "text", disabled: isDisabled, onClick: onClick, className: menuOrganizationClassnames.button, endIcon: _jsx(StyledChevron, { isActive: isOpen, width: 24, height: 24 }), children: renderPreview ? (renderPreview(currentOrganization, {
|
|
15
15
|
className: hidePersonalDataClassname,
|
|
16
|
-
})) : (_jsxs(Container, { className: hidePersonalDataClassname, children: [_jsx(OverflowTypography, { variant: "h6", component: "div", children: name }), _jsxs(OrganizationData, { children: [_jsxs(StyledTypography, { "$isDisabled": isDisabled, variant: "caption", color: "textSecondary", children: ["\u0418\u041D\u041D ", inn] }), kpp && (_jsxs(StyledTypography, { "$isDisabled": isDisabled, variant: "caption", color: "textSecondary", children: ["\u041A\u041F\u041F ", kpp] }))] })] })) }));
|
|
16
|
+
})) : (_jsxs(Container, { className: hidePersonalDataClassname, children: [_jsx(OverflowTypography, { variant: "h6", component: "div", children: name }), _jsxs(OrganizationData, { className: menuOrganizationClassnames.organizationData, children: [_jsxs(StyledTypography, { "$isDisabled": isDisabled, variant: "caption", color: "textSecondary", children: ["\u0418\u041D\u041D ", inn] }), kpp && (_jsxs(StyledTypography, { "$isDisabled": isDisabled, variant: "caption", color: "textSecondary", children: ["\u041A\u041F\u041F ", kpp] }))] })] })) }));
|
|
17
17
|
if (isDisabled && disabledReason) {
|
|
18
18
|
return (_jsx(Tooltip, { title: disabledReason, withoutContainer: false, placement: "bottom", children: renderButton() }));
|
|
19
19
|
}
|
|
@@ -6,4 +6,5 @@ export const menuOrganizationClassnames = {
|
|
|
6
6
|
root: createUIKitClassname('menu-organization'),
|
|
7
7
|
errorPlaceholder: createUIKitClassname('menu-organization__error-placeholder'),
|
|
8
8
|
button: createUIKitClassname('menu-organization__button'),
|
|
9
|
+
organizationData: createUIKitClassname('menu-organization__organization-data'),
|
|
9
10
|
};
|
|
@@ -23,7 +23,7 @@ export const Profile = (props) => {
|
|
|
23
23
|
if (isLoading) {
|
|
24
24
|
return _jsx(ProfileSkeleton, {});
|
|
25
25
|
}
|
|
26
|
-
return (_jsxs(_Fragment, { children: [_jsx(ClickAwayListener, { onClickAway: handleCloseMenu, children: _jsxs(ProfileRoot, { ref: anchorRef, variant: "text", onClick: handleOpenMenu, children: [_jsx(StyledAvatar, { ...avatar }), _jsxs(User, { children: [_jsxs(Credentials, { className: hidePersonalDataClassname, children: [_jsx(Typography, { variant: "body1", className: profileClassnames.credentials, children: displayName }), _jsx(Typography, { variant: "caption", color: "textSecondary", className: profileClassnames.credentials, children: annotation })] }), _jsx(StyledChevron, { isActive: open })] })] }) }), Menu ? (_jsx(Menu, { open: open, anchorEl: anchorRef.current, onClose: handleCloseMenu, anchorOrigin: {
|
|
26
|
+
return (_jsxs(_Fragment, { children: [_jsx(ClickAwayListener, { onClickAway: handleCloseMenu, children: _jsxs(ProfileRoot, { ref: anchorRef, variant: "text", onClick: handleOpenMenu, className: profileClassnames.button, children: [_jsx(StyledAvatar, { ...avatar, className: profileClassnames.avatar }), _jsxs(User, { className: profileClassnames.user, children: [_jsxs(Credentials, { className: hidePersonalDataClassname, children: [_jsx(Typography, { variant: "body1", className: profileClassnames.credentials, children: displayName }), _jsx(Typography, { variant: "caption", color: "textSecondary", className: profileClassnames.credentials, children: annotation })] }), _jsx(StyledChevron, { isActive: open })] })] }) }), Menu ? (_jsx(Menu, { open: open, anchorEl: anchorRef.current, onClose: handleCloseMenu, anchorOrigin: {
|
|
27
27
|
vertical: 'bottom',
|
|
28
28
|
horizontal: 'right',
|
|
29
29
|
}, transformOrigin: {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { createUIKitClassname } from '../utils/createUIKitClassname';
|
|
2
2
|
export const profileClassnames = {
|
|
3
3
|
credentials: createUIKitClassname('profile__credentials'),
|
|
4
|
+
button: createUIKitClassname('profile__button'),
|
|
5
|
+
avatar: createUIKitClassname('profile__avatar'),
|
|
6
|
+
user: createUIKitClassname('profile__user'),
|
|
4
7
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type DateMask } from '../maskDate';
|
|
2
2
|
/**
|
|
3
3
|
* утилита конвертации строковой даты созданной по маске обратно в Date
|
|
4
|
+
* Строгий разбор UTC через `dayjs` + `customParseFormat`; при невалидной строке — Invalid Date
|
|
4
5
|
*/
|
|
5
6
|
export declare const parseDate: (date: string, mask: DateMask, separator?: string) => Date;
|
|
@@ -1,21 +1,50 @@
|
|
|
1
|
-
import
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
3
|
+
import utc from 'dayjs/plugin/utc';
|
|
2
4
|
import { DateMaskElements } from '../maskDate';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
dayjs.extend(customParseFormat);
|
|
6
|
+
dayjs.extend(utc);
|
|
7
|
+
/**
|
|
8
|
+
* Токен маски UI → литерал формата `dayjs` (strict UTC).
|
|
9
|
+
* В маске час — `hh`, в дате используются сутки 0–23 как в `formatDate` (UTC), поэтому `HH`.
|
|
10
|
+
*/
|
|
11
|
+
const maskElementToDayjs = {
|
|
12
|
+
[DateMaskElements.Day]: 'DD',
|
|
13
|
+
[DateMaskElements.Month]: 'MM',
|
|
14
|
+
[DateMaskElements.Year]: 'YYYY',
|
|
15
|
+
[DateMaskElements.Hour]: 'HH',
|
|
16
|
+
[DateMaskElements.Minute]: 'mm',
|
|
17
|
+
[DateMaskElements.Second]: 'ss',
|
|
18
|
+
};
|
|
19
|
+
const buildDayjsFormat = (mask, separator) => {
|
|
20
|
+
const parts = mask.split(separator);
|
|
21
|
+
const tokens = [];
|
|
22
|
+
for (const part of parts) {
|
|
23
|
+
const t = maskElementToDayjs[part];
|
|
24
|
+
if (t == null) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
tokens.push(t);
|
|
28
|
+
}
|
|
29
|
+
return tokens.join(separator);
|
|
10
30
|
};
|
|
11
31
|
/**
|
|
12
32
|
* утилита конвертации строковой даты созданной по маске обратно в Date
|
|
33
|
+
* Строгий разбор UTC через `dayjs` + `customParseFormat`; при невалидной строке — Invalid Date
|
|
13
34
|
*/
|
|
14
35
|
export const parseDate = (date, mask, separator = '.') => {
|
|
15
36
|
const dateArr = date.split(separator);
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
37
|
+
const maskSplit = mask.split(separator);
|
|
38
|
+
if (dateArr.length !== maskSplit.length) {
|
|
39
|
+
return new Date(Number.NaN);
|
|
40
|
+
}
|
|
41
|
+
const format = buildDayjsFormat(mask, separator);
|
|
42
|
+
if (format == null) {
|
|
43
|
+
return new Date(Number.NaN);
|
|
44
|
+
}
|
|
45
|
+
const parsed = dayjs.utc(date, format, true);
|
|
46
|
+
if (!parsed.isValid()) {
|
|
47
|
+
return new Date(Number.NaN);
|
|
48
|
+
}
|
|
49
|
+
return parsed.toDate();
|
|
21
50
|
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { type RefObject } from 'react';
|
|
2
2
|
export type DashboardContextProps = {
|
|
3
3
|
isFocusedMode: boolean;
|
|
4
|
+
mobileHeaderPriorityFeature: 'profile' | 'menuOrg';
|
|
4
5
|
setAlertElement?: (element: HTMLElement | null) => void;
|
|
5
6
|
alertHeight: number;
|
|
6
7
|
isLoading: boolean;
|
|
7
8
|
hasMenuOrganizationRef: RefObject<boolean | null>;
|
|
9
|
+
hasProfileRef: RefObject<boolean | null>;
|
|
8
10
|
setFocusedMode: (isFocusedMode: boolean) => void;
|
|
9
11
|
};
|
|
10
12
|
export declare const DashboardContext: import("react").Context<DashboardContextProps>;
|
|
@@ -4,8 +4,10 @@ exports.DashboardContext = void 0;
|
|
|
4
4
|
const react_1 = require("react");
|
|
5
5
|
exports.DashboardContext = (0, react_1.createContext)({
|
|
6
6
|
isFocusedMode: false,
|
|
7
|
+
mobileHeaderPriorityFeature: 'menuOrg',
|
|
7
8
|
alertHeight: 0,
|
|
8
9
|
isLoading: false,
|
|
9
10
|
hasMenuOrganizationRef: (0, react_1.createRef)(),
|
|
11
|
+
hasProfileRef: (0, react_1.createRef)(),
|
|
10
12
|
setFocusedMode: () => undefined,
|
|
11
13
|
});
|
package/node/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import { type DashboardContextProps } from '../DashboardContext';
|
|
3
|
-
type Props = Pick<DashboardContextProps, 'isFocusedMode'> & {
|
|
3
|
+
type Props = Pick<DashboardContextProps, 'isFocusedMode' | 'mobileHeaderPriorityFeature'> & {
|
|
4
4
|
children: ReactNode;
|
|
5
5
|
isLoading: boolean;
|
|
6
6
|
};
|
|
7
|
-
export declare const DashboardContextProvider: ({ children, isFocusedMode, isLoading, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare const DashboardContextProvider: ({ children, isFocusedMode, isLoading, mobileHeaderPriorityFeature, }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export {};
|
package/node/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js
CHANGED
|
@@ -4,11 +4,12 @@ exports.DashboardContextProvider = void 0;
|
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
const react_1 = require("react");
|
|
6
6
|
const DashboardContext_1 = require("../DashboardContext");
|
|
7
|
-
const DashboardContextProvider = ({ children, isFocusedMode, isLoading, }) => {
|
|
7
|
+
const DashboardContextProvider = ({ children, isFocusedMode, isLoading, mobileHeaderPriorityFeature, }) => {
|
|
8
8
|
const [alertElement, setAlertElement] = (0, react_1.useState)(null);
|
|
9
9
|
const [alertHeight, setAlertHeight] = (0, react_1.useState)(0);
|
|
10
10
|
const [isFocusedModeInternal, setFocusedMode] = (0, react_1.useState)(isFocusedMode);
|
|
11
11
|
const hasMenuOrganizationRef = (0, react_1.useRef)(false);
|
|
12
|
+
const hasProfileRef = (0, react_1.useRef)(false);
|
|
12
13
|
(0, react_1.useEffect)(() => {
|
|
13
14
|
if (isFocusedMode !== isFocusedModeInternal) {
|
|
14
15
|
setFocusedMode(isFocusedMode);
|
|
@@ -30,9 +31,11 @@ const DashboardContextProvider = ({ children, isFocusedMode, isLoading, }) => {
|
|
|
30
31
|
}, [alertElement]);
|
|
31
32
|
return ((0, jsx_runtime_1.jsx)(DashboardContext_1.DashboardContext.Provider, { value: {
|
|
32
33
|
isFocusedMode: isFocusedModeInternal,
|
|
34
|
+
mobileHeaderPriorityFeature,
|
|
33
35
|
setAlertElement,
|
|
34
36
|
alertHeight,
|
|
35
37
|
isLoading,
|
|
38
|
+
hasProfileRef,
|
|
36
39
|
hasMenuOrganizationRef,
|
|
37
40
|
setFocusedMode,
|
|
38
41
|
}, children: children }));
|
|
@@ -4,7 +4,7 @@ import { type DashboardLayoutProps } from './types';
|
|
|
4
4
|
* Общий Layout приложения
|
|
5
5
|
*/
|
|
6
6
|
export declare const DashboardLayout: {
|
|
7
|
-
({ children, isFocusedMode, isLoading, }: DashboardLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
({ children, isFocusedMode, isLoading, mobileHeaderPriorityFeature, }: DashboardLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
Header: import("react").ForwardRefExoticComponent<import("./Header").HeaderProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
9
9
|
Sidebar: import("react").ForwardRefExoticComponent<import("../DashboardSidebar").DashboardSidebarProps & import("react").RefAttributes<HTMLBaseElement>>;
|
|
10
10
|
Main: import("react").ForwardRefExoticComponent<import("./Main").MainProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -10,8 +10,8 @@ const Main_1 = require("./Main");
|
|
|
10
10
|
/**
|
|
11
11
|
* Общий Layout приложения
|
|
12
12
|
*/
|
|
13
|
-
const DashboardLayout = ({ children, isFocusedMode = false, isLoading = false, }) => {
|
|
14
|
-
return ((0, jsx_runtime_1.jsx)(DashboardContext_1.DashboardContextProvider, { isFocusedMode: isFocusedMode, isLoading: isLoading, children: (0, jsx_runtime_1.jsx)(DashboardWrapper_1.DashboardWrapper, { children: children }) }));
|
|
13
|
+
const DashboardLayout = ({ children, isFocusedMode = false, isLoading = false, mobileHeaderPriorityFeature = 'menuOrg', }) => {
|
|
14
|
+
return ((0, jsx_runtime_1.jsx)(DashboardContext_1.DashboardContextProvider, { isFocusedMode: isFocusedMode, isLoading: isLoading, mobileHeaderPriorityFeature: mobileHeaderPriorityFeature, children: (0, jsx_runtime_1.jsx)(DashboardWrapper_1.DashboardWrapper, { children: children }) }));
|
|
15
15
|
};
|
|
16
16
|
exports.DashboardLayout = DashboardLayout;
|
|
17
17
|
exports.DashboardLayout.Header = Header_1.Header;
|
|
@@ -9,15 +9,40 @@ const QuitOutlineMd_1 = require("../../../icons/QuitOutlineMd");
|
|
|
9
9
|
const Button_1 = require("../../Button");
|
|
10
10
|
const Product_1 = require("../../Product");
|
|
11
11
|
const Profile_1 = require("../../Profile");
|
|
12
|
+
const cva_1 = require("../../utils/cva");
|
|
12
13
|
const getInertProps_1 = require("../../utils/getInertProps");
|
|
13
14
|
const constants_1 = require("./constants");
|
|
14
15
|
const styles_1 = require("./styles");
|
|
15
16
|
const useLogic_1 = require("./useLogic");
|
|
17
|
+
const headerPriorityFeature = (0, cva_1.cva)('', {
|
|
18
|
+
variants: {
|
|
19
|
+
feature: {
|
|
20
|
+
menuOrg: constants_1.dashboardLayoutHeaderClassnames.priorityFeatureMenuOrg,
|
|
21
|
+
profile: constants_1.dashboardLayoutHeaderClassnames.priorityFeatureProfile,
|
|
22
|
+
},
|
|
23
|
+
isPinned: {
|
|
24
|
+
true: constants_1.dashboardLayoutHeaderClassnames.mobileSidebarPriorityFeatureVisible,
|
|
25
|
+
},
|
|
26
|
+
featureInSidebar: {
|
|
27
|
+
true: constants_1.dashboardLayoutHeaderClassnames.featureInSidebar,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
16
31
|
/**
|
|
17
32
|
* Основной header приложения
|
|
18
33
|
*/
|
|
19
34
|
exports.Header = (0, react_1.forwardRef)((props, ref) => {
|
|
20
35
|
const { productSwitcher: ProductSwitcher, product, profile, menuOrganization, children, } = props;
|
|
21
|
-
const { isShowExitButton, isShowProfile, isFocusedMode, isMobile, collapsedIn, onToggleSidebar, isLoading,
|
|
22
|
-
return ((0, jsx_runtime_1.jsx)(styles_1.HeaderRoot, { ref: ref, "$isFocusedMode": isFocusedMode, ...(0, getInertProps_1.getInertProps)(!isMobile && isFocusedMode), className: constants_1.dashboardLayoutHeaderClassnames.root, children: (0, jsx_runtime_1.jsxs)(styles_1.HeaderContent, { children: [(0, jsx_runtime_1.jsx)(styles_1.MobileSidebarTogglerWrapper, { className: constants_1.dashboardLayoutHeaderClassnames.mobileSidebarButton, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { startIcon: collapsedIn ? (0, jsx_runtime_1.jsx)(CrossOutlineMd_1.CrossOutlineMd, {}) : (0, jsx_runtime_1.jsx)(MenuOnOutlineMd_1.MenuOnOutlineMd, {}), variant: "text", onClick: () => onToggleSidebar(), title: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0431\u043E\u043A\u043E\u0432\u043E\u0435 \u043C\u0435\u043D\u044E" }) }), (0, jsx_runtime_1.jsxs)(styles_1.HeaderSection, { children: [ProductSwitcher && ((0, jsx_runtime_1.jsx)(styles_1.ProductSwitcherWrapper, { children: (0, jsx_runtime_1.jsx)(ProductSwitcher, {}) })), (0, jsx_runtime_1.jsx)(Product_1.Product, { ...product })] }), (0, jsx_runtime_1.jsxs)(styles_1.HeaderContentSection, {
|
|
36
|
+
const { isShowExitButton, isShowProfile, isFocusedMode, isMobile, collapsedIn, onToggleSidebar, isLoading, mobileHeaderPriorityFeature, headerStyle, isPinned, } = (0, useLogic_1.useLogic)(props);
|
|
37
|
+
return ((0, jsx_runtime_1.jsx)(styles_1.HeaderRoot, { ref: ref, "$isFocusedMode": isFocusedMode, ...(0, getInertProps_1.getInertProps)(!isMobile && isFocusedMode), className: constants_1.dashboardLayoutHeaderClassnames.root, style: headerStyle, children: (0, jsx_runtime_1.jsxs)(styles_1.HeaderContent, { children: [(0, jsx_runtime_1.jsx)(styles_1.MobileSidebarTogglerWrapper, { className: constants_1.dashboardLayoutHeaderClassnames.mobileSidebarButton, children: (0, jsx_runtime_1.jsx)(Button_1.Button, { startIcon: collapsedIn ? (0, jsx_runtime_1.jsx)(CrossOutlineMd_1.CrossOutlineMd, {}) : (0, jsx_runtime_1.jsx)(MenuOnOutlineMd_1.MenuOnOutlineMd, {}), variant: "text", onClick: () => onToggleSidebar(), title: "\u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0431\u043E\u043A\u043E\u0432\u043E\u0435 \u043C\u0435\u043D\u044E" }) }), (0, jsx_runtime_1.jsxs)(styles_1.HeaderSection, { children: [ProductSwitcher && ((0, jsx_runtime_1.jsx)(styles_1.ProductSwitcherWrapper, { children: (0, jsx_runtime_1.jsx)(ProductSwitcher, {}) })), (0, jsx_runtime_1.jsx)(Product_1.Product, { ...product })] }), (0, jsx_runtime_1.jsxs)(styles_1.HeaderContentSection, { className: headerPriorityFeature({
|
|
38
|
+
feature: mobileHeaderPriorityFeature,
|
|
39
|
+
}), children: [children, menuOrganization && ((0, jsx_runtime_1.jsx)(styles_1.PriorityFeatureWrapper, { className: headerPriorityFeature({
|
|
40
|
+
feature: mobileHeaderPriorityFeature,
|
|
41
|
+
isPinned,
|
|
42
|
+
featureInSidebar: mobileHeaderPriorityFeature === 'profile',
|
|
43
|
+
}), children: menuOrganization() })), profile && ((0, jsx_runtime_1.jsx)(styles_1.PriorityFeatureWrapper, { className: headerPriorityFeature({
|
|
44
|
+
feature: mobileHeaderPriorityFeature,
|
|
45
|
+
isPinned,
|
|
46
|
+
featureInSidebar: mobileHeaderPriorityFeature === 'menuOrg',
|
|
47
|
+
}), children: (0, jsx_runtime_1.jsx)(styles_1.ProfileWrapper, { className: constants_1.dashboardLayoutHeaderClassnames.profile, "$isShow": isShowProfile, children: (0, jsx_runtime_1.jsx)(Profile_1.Profile, { isLoading: isLoading, ...profile }) }) })), (0, jsx_runtime_1.jsx)(styles_1.ExitButton, { "$isShow": isShowExitButton, onClick: profile?.exitButton?.onClick, title: "\u0412\u044B\u0445\u043E\u0434", variant: "text", children: (0, jsx_runtime_1.jsx)(QuitOutlineMd_1.QuitOutlineMd, {}) })] })] }) }));
|
|
23
48
|
});
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export declare const dashboardLayoutHeaderClassnames: {
|
|
2
2
|
root: string;
|
|
3
3
|
mobileSidebarButton: string;
|
|
4
|
-
|
|
4
|
+
priorityFeatureMenuOrg: string;
|
|
5
|
+
priorityFeatureProfile: string;
|
|
6
|
+
mobileSidebarPriorityFeatureVisible: string;
|
|
7
|
+
featureInSidebar: string;
|
|
8
|
+
profile: string;
|
|
5
9
|
};
|
|
@@ -5,5 +5,9 @@ const createUIKitClassname_1 = require("../../utils/createUIKitClassname");
|
|
|
5
5
|
exports.dashboardLayoutHeaderClassnames = {
|
|
6
6
|
root: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header'),
|
|
7
7
|
mobileSidebarButton: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header__sidebar-button_mobile'),
|
|
8
|
-
|
|
8
|
+
priorityFeatureMenuOrg: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header__priority-feature_menu-org'),
|
|
9
|
+
priorityFeatureProfile: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header__priority-feature_profile'),
|
|
10
|
+
mobileSidebarPriorityFeatureVisible: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header__sidebar-priority-feature_visible'),
|
|
11
|
+
featureInSidebar: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header__feature-in-sidebar'),
|
|
12
|
+
profile: (0, createUIKitClassname_1.createUIKitClassname)('dashboard-layout-header__profile'),
|
|
9
13
|
};
|
|
@@ -44,9 +44,10 @@ export declare const HeaderContent: import("@emotion/styled/dist/declarations/sr
|
|
|
44
44
|
theme?: import("@emotion/react").Theme | undefined;
|
|
45
45
|
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
46
46
|
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Обертка для элементов которые должны быть в мобильном хедере или помещены в sidebar.
|
|
49
|
+
*/
|
|
50
|
+
export declare const PriorityFeatureWrapper: import("@emotion/styled/dist/declarations/src/types").StyledComponent<{
|
|
48
51
|
theme?: import("@emotion/react").Theme | undefined;
|
|
49
52
|
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
50
|
-
} & {
|
|
51
|
-
$alertHeight?: number | undefined;
|
|
52
53
|
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|