@astral/ui 4.23.0 → 4.24.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/BottomDrawer/BottomDrawer.js +2 -2
- package/components/BottomDrawer/constants.d.ts +3 -0
- package/components/BottomDrawer/constants.js +4 -0
- package/components/BottomDrawer/index.d.ts +1 -0
- package/components/BottomDrawer/index.js +1 -0
- package/components/BottomDrawer/public.d.ts +1 -0
- package/components/BottomDrawer/public.js +1 -0
- package/components/DashboardContext/DashboardContext.d.ts +2 -1
- package/components/DashboardContext/DashboardContext.js +2 -1
- package/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js +9 -2
- package/components/DashboardLayout/Header/Header.js +3 -9
- package/components/DashboardLayout/Header/useLogic/useLogic.d.ts +6 -1
- package/components/DashboardLayout/Header/useLogic/useLogic.js +18 -2
- package/components/DashboardSidebar/DashboardSidebar.js +2 -4
- package/components/DashboardSidebar/constants.d.ts +1 -0
- package/components/DashboardSidebar/constants.js +1 -0
- package/components/DashboardSidebar/styles.js +6 -0
- package/components/DashboardSidebar/useLogic/useLogic.d.ts +2 -1
- package/components/DashboardSidebar/useLogic/useLogic.js +10 -3
- package/components/MenuOrganization/MenuOrganization.js +5 -6
- package/components/MenuOrganization/NoData/styles.js +4 -0
- package/components/MenuOrganization/OrganizationButton/constants.d.ts +1 -0
- package/components/MenuOrganization/OrganizationButton/constants.js +1 -0
- package/components/MenuOrganization/OrganizationButton/index.d.ts +1 -0
- package/components/MenuOrganization/OrganizationButton/index.js +1 -0
- package/components/MenuOrganization/OrganizationButton/styles.js +22 -0
- package/components/MenuOrganization/OrganizationItem/styles.d.ts +1 -1
- package/components/MenuOrganization/OrganizationItem/styles.js +9 -0
- package/components/MenuOrganization/OrganizationListSkeleton/styles.js +12 -0
- package/components/MenuOrganization/constants.d.ts +2 -0
- package/components/MenuOrganization/constants.js +2 -0
- package/components/MenuOrganization/styles.d.ts +11 -0
- package/components/MenuOrganization/styles.js +82 -0
- package/components/MenuOrganization/useLogic/useLogic.d.ts +14 -4
- package/components/MenuOrganization/useLogic/useLogic.js +21 -2
- package/components/PageHeader/Title/Title.js +1 -1
- package/components/Popover/Popover.d.ts +1 -1
- package/components/Popover/Popover.js +3 -3
- package/components/placeholders/Placeholder/Placeholder.js +2 -2
- package/components/placeholders/Placeholder/constants.d.ts +4 -0
- package/components/placeholders/Placeholder/constants.js +5 -0
- package/components/placeholders/Placeholder/index.d.ts +1 -0
- package/components/placeholders/Placeholder/index.js +1 -0
- package/components/placeholders/Placeholder/public.d.ts +1 -0
- package/components/placeholders/Placeholder/public.js +1 -0
- package/node/components/BottomDrawer/BottomDrawer.js +1 -1
- package/node/components/BottomDrawer/constants.d.ts +3 -0
- package/node/components/BottomDrawer/constants.js +5 -1
- package/node/components/BottomDrawer/index.d.ts +1 -0
- package/node/components/BottomDrawer/index.js +3 -0
- package/node/components/BottomDrawer/public.d.ts +1 -0
- package/node/components/BottomDrawer/public.js +3 -0
- package/node/components/DashboardContext/DashboardContext.d.ts +2 -1
- package/node/components/DashboardContext/DashboardContext.js +1 -0
- package/node/components/DashboardContext/DashboardContextProvider/DashboardContextProvider.js +8 -1
- package/node/components/DashboardLayout/Header/Header.js +2 -8
- package/node/components/DashboardLayout/Header/useLogic/useLogic.d.ts +6 -1
- package/node/components/DashboardLayout/Header/useLogic/useLogic.js +18 -2
- package/node/components/DashboardSidebar/DashboardSidebar.js +2 -4
- package/node/components/DashboardSidebar/constants.d.ts +1 -0
- package/node/components/DashboardSidebar/constants.js +1 -0
- package/node/components/DashboardSidebar/styles.js +6 -0
- package/node/components/DashboardSidebar/useLogic/useLogic.d.ts +2 -1
- package/node/components/DashboardSidebar/useLogic/useLogic.js +9 -2
- package/node/components/MenuOrganization/MenuOrganization.js +3 -4
- package/node/components/MenuOrganization/NoData/styles.js +4 -0
- package/node/components/MenuOrganization/OrganizationButton/constants.d.ts +1 -0
- package/node/components/MenuOrganization/OrganizationButton/constants.js +4 -0
- package/node/components/MenuOrganization/OrganizationButton/index.d.ts +1 -0
- package/node/components/MenuOrganization/OrganizationButton/index.js +3 -0
- package/node/components/MenuOrganization/OrganizationButton/styles.js +22 -0
- package/node/components/MenuOrganization/OrganizationItem/styles.d.ts +1 -1
- package/node/components/MenuOrganization/OrganizationItem/styles.js +11 -2
- package/node/components/MenuOrganization/OrganizationListSkeleton/styles.js +12 -0
- package/node/components/MenuOrganization/constants.d.ts +2 -0
- package/node/components/MenuOrganization/constants.js +3 -1
- package/node/components/MenuOrganization/styles.d.ts +11 -0
- package/node/components/MenuOrganization/styles.js +87 -5
- package/node/components/MenuOrganization/useLogic/useLogic.d.ts +14 -4
- package/node/components/MenuOrganization/useLogic/useLogic.js +21 -2
- package/node/components/PageHeader/Title/Title.js +1 -1
- package/node/components/Popover/Popover.d.ts +1 -1
- package/node/components/Popover/Popover.js +3 -3
- package/node/components/placeholders/Placeholder/Placeholder.js +1 -1
- package/node/components/placeholders/Placeholder/constants.d.ts +4 -0
- package/node/components/placeholders/Placeholder/constants.js +6 -1
- package/node/components/placeholders/Placeholder/index.d.ts +1 -0
- package/node/components/placeholders/Placeholder/index.js +3 -0
- package/node/components/placeholders/Placeholder/public.d.ts +1 -0
- package/node/components/placeholders/Placeholder/public.js +3 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { CrossOutlineMd } from '../../icons/CrossOutlineMd';
|
|
3
3
|
import { IconButton } from '../IconButton';
|
|
4
|
-
import { DEFAULT_HEADER_HEIGHT } from './constants';
|
|
4
|
+
import { bottomDrawerClassnames, DEFAULT_HEADER_HEIGHT } from './constants';
|
|
5
5
|
import { Body, Header, HeaderTitle, StyledDrawer } from './styles';
|
|
6
6
|
export const BottomDrawer = ({ title, drawerHeaderHeight = DEFAULT_HEADER_HEIGHT, children, onClose, ...props }) => {
|
|
7
7
|
const handleClose = (event) => {
|
|
@@ -9,5 +9,5 @@ export const BottomDrawer = ({ title, drawerHeaderHeight = DEFAULT_HEADER_HEIGHT
|
|
|
9
9
|
onClose(event, 'escapeKeyDown');
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
|
-
return (_jsxs(StyledDrawer, { ...props, anchor: "bottom", onClose: onClose, children: [_jsxs(Header, { drawerHeaderHeight: drawerHeaderHeight, children: [_jsx(HeaderTitle, { variant: "h6", noWrap: true, children: title }), _jsx(IconButton, { variant: "text", onClick: handleClose, size: "large", children: _jsx(CrossOutlineMd, {}) })] }), _jsx(Body, { children: children })] }));
|
|
12
|
+
return (_jsxs(StyledDrawer, { ...props, anchor: "bottom", onClose: onClose, children: [_jsxs(Header, { drawerHeaderHeight: drawerHeaderHeight, children: [_jsx(HeaderTitle, { variant: "h6", noWrap: true, children: title }), _jsx(IconButton, { variant: "text", onClick: handleClose, size: "large", children: _jsx(CrossOutlineMd, {}) })] }), _jsx(Body, { className: bottomDrawerClassnames.content, children: children })] }));
|
|
13
13
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
2
|
export type DashboardContextProps = {
|
|
3
3
|
isFocusedMode: boolean;
|
|
4
4
|
setAlertElement?: (element: HTMLElement | null) => void;
|
|
5
5
|
alertHeight: number;
|
|
6
6
|
isLoading: boolean;
|
|
7
|
+
hasMenuOrganizationRef: RefObject<boolean | null>;
|
|
7
8
|
};
|
|
8
9
|
export declare const DashboardContext: import("react").Context<DashboardContextProps>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { DashboardContext, } from '../DashboardContext';
|
|
4
4
|
export const DashboardContextProvider = ({ children, isFocusedMode, isLoading, }) => {
|
|
5
5
|
const [alertElement, setAlertElement] = useState(null);
|
|
6
6
|
const [alertHeight, setAlertHeight] = useState(0);
|
|
7
|
+
const hasMenuOrganizationRef = useRef(false);
|
|
7
8
|
useEffect(() => {
|
|
8
9
|
if (!alertElement) {
|
|
9
10
|
setAlertHeight(0);
|
|
@@ -18,5 +19,11 @@ export const DashboardContextProvider = ({ children, isFocusedMode, isLoading, }
|
|
|
18
19
|
resizeObserver.observe(alertElement);
|
|
19
20
|
return () => resizeObserver.disconnect();
|
|
20
21
|
}, [alertElement]);
|
|
21
|
-
return (_jsx(DashboardContext.Provider, { value: {
|
|
22
|
+
return (_jsx(DashboardContext.Provider, { value: {
|
|
23
|
+
isFocusedMode,
|
|
24
|
+
setAlertElement,
|
|
25
|
+
alertHeight,
|
|
26
|
+
isLoading,
|
|
27
|
+
hasMenuOrganizationRef,
|
|
28
|
+
}, children: children }));
|
|
22
29
|
};
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
3
|
import { CrossOutlineMd } from '../../../icons/CrossOutlineMd';
|
|
4
4
|
import { MenuOnOutlineMd } from '../../../icons/MenuOnOutlineMd';
|
|
5
5
|
import { QuitOutlineMd } from '../../../icons/QuitOutlineMd';
|
|
6
6
|
import { Button } from '../../Button';
|
|
7
|
-
import { DashboardContext } from '../../DashboardContext';
|
|
8
|
-
import { DashboardSidebarContext } from '../../DashboardSidebarProvider';
|
|
9
7
|
import { Product } from '../../Product';
|
|
10
8
|
import { Profile } from '../../Profile';
|
|
11
|
-
import { useViewportType } from '../../useViewportType';
|
|
12
9
|
import { getInertProps } from '../../utils/getInertProps';
|
|
13
10
|
import { dashboardLayoutHeaderClassnames } from './constants';
|
|
14
11
|
import { ExitButton, HeaderContent, HeaderContentSection, HeaderRoot, HeaderSection, MobileSidebarTogglerWrapper, ProductSwitcherWrapper, ProfileWrapper, } from './styles';
|
|
@@ -18,9 +15,6 @@ import { useLogic } from './useLogic';
|
|
|
18
15
|
*/
|
|
19
16
|
export const Header = forwardRef((props, ref) => {
|
|
20
17
|
const { productSwitcher: ProductSwitcher, product, profile, menuOrganization, children, } = props;
|
|
21
|
-
const { isShowExitButton, isShowProfile } = useLogic(props);
|
|
22
|
-
|
|
23
|
-
const { collapsedIn, onToggleSidebar } = useContext(DashboardSidebarContext);
|
|
24
|
-
const { isMobile } = useViewportType();
|
|
25
|
-
return (_jsx(HeaderRoot, { ref: ref, "$isFocusedMode": isFocusedMode, ...getInertProps(!isMobile && isFocusedMode), className: dashboardLayoutHeaderClassnames.root, children: _jsxs(HeaderContent, { children: [_jsx(MobileSidebarTogglerWrapper, { className: dashboardLayoutHeaderClassnames.mobileSidebarButton, children: _jsx(Button, { startIcon: collapsedIn ? _jsx(CrossOutlineMd, {}) : _jsx(MenuOnOutlineMd, {}), variant: "text", onClick: () => onToggleSidebar() }) }), _jsxs(HeaderSection, { children: [ProductSwitcher && (_jsx(ProductSwitcherWrapper, { children: _jsx(ProductSwitcher, {}) })), _jsx(Product, { ...product })] }), _jsxs(HeaderContentSection, { children: [children, menuOrganization?.(), profile && (_jsx(ProfileWrapper, { "$isShow": isShowProfile, children: _jsx(Profile, { isLoading: isLoading, ...profile }) })), _jsx(ExitButton, { "$isShow": isShowExitButton, onClick: profile?.exitButton?.onClick, title: "\u0412\u044B\u0445\u043E\u0434", variant: "text", children: _jsx(QuitOutlineMd, {}) })] })] }) }));
|
|
18
|
+
const { isShowExitButton, isShowProfile, isFocusedMode, isMobile, collapsedIn, onToggleSidebar, isLoading, } = useLogic(props);
|
|
19
|
+
return (_jsx(HeaderRoot, { ref: ref, "$isFocusedMode": isFocusedMode, ...getInertProps(!isMobile && isFocusedMode), className: dashboardLayoutHeaderClassnames.root, children: _jsxs(HeaderContent, { children: [_jsx(MobileSidebarTogglerWrapper, { className: dashboardLayoutHeaderClassnames.mobileSidebarButton, children: _jsx(Button, { startIcon: collapsedIn ? _jsx(CrossOutlineMd, {}) : _jsx(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" }) }), _jsxs(HeaderSection, { children: [ProductSwitcher && (_jsx(ProductSwitcherWrapper, { children: _jsx(ProductSwitcher, {}) })), _jsx(Product, { ...product })] }), _jsxs(HeaderContentSection, { children: [children, menuOrganization?.(), profile && (_jsx(ProfileWrapper, { "$isShow": isShowProfile, children: _jsx(Profile, { isLoading: isLoading, ...profile }) })), _jsx(ExitButton, { "$isShow": isShowExitButton, onClick: profile?.exitButton?.onClick, title: "\u0412\u044B\u0445\u043E\u0434", variant: "text", children: _jsx(QuitOutlineMd, {}) })] })] }) }));
|
|
26
20
|
});
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { type HeaderProps } from '../types';
|
|
2
|
-
export declare const useLogic: ({ profile }: HeaderProps) => {
|
|
2
|
+
export declare const useLogic: ({ profile, menuOrganization }: HeaderProps) => {
|
|
3
3
|
isShowExitButton: boolean;
|
|
4
4
|
isShowProfile: boolean;
|
|
5
|
+
isMobile: boolean;
|
|
6
|
+
isFocusedMode: boolean;
|
|
7
|
+
isLoading: boolean;
|
|
8
|
+
collapsedIn: boolean;
|
|
9
|
+
onToggleSidebar: (newValue?: boolean | undefined) => void;
|
|
5
10
|
};
|
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
import { useContext, useEffect } from 'react';
|
|
2
|
+
import { DashboardContext } from '../../../DashboardContext';
|
|
3
|
+
import { DashboardSidebarContext } from '../../../DashboardSidebarProvider';
|
|
1
4
|
import { useViewportType } from '../../../useViewportType';
|
|
2
|
-
export const useLogic = ({ profile }) => {
|
|
5
|
+
export const useLogic = ({ profile, menuOrganization }) => {
|
|
6
|
+
const { isFocusedMode, isLoading, hasMenuOrganizationRef } = useContext(DashboardContext);
|
|
7
|
+
const { collapsedIn, onToggleSidebar } = useContext(DashboardSidebarContext);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
hasMenuOrganizationRef.current = Boolean(menuOrganization);
|
|
10
|
+
}, [menuOrganization]);
|
|
3
11
|
const { isMobile } = useViewportType();
|
|
4
12
|
const hasMenu = Boolean(profile?.menu || profile?.menuList);
|
|
5
13
|
const isShowProfile = (Boolean(profile) && !isMobile) || (hasMenu && isMobile);
|
|
6
14
|
const isShowExitButton = isMobile && !hasMenu && Boolean(profile?.exitButton);
|
|
7
|
-
return {
|
|
15
|
+
return {
|
|
16
|
+
isShowExitButton,
|
|
17
|
+
isShowProfile,
|
|
18
|
+
isMobile,
|
|
19
|
+
isFocusedMode,
|
|
20
|
+
isLoading,
|
|
21
|
+
collapsedIn,
|
|
22
|
+
onToggleSidebar,
|
|
23
|
+
};
|
|
8
24
|
};
|
|
@@ -3,9 +3,7 @@ import { forwardRef } from 'react';
|
|
|
3
3
|
import { DashboardSidebarSkeleton } from '../DashboardSidebarSkeleton';
|
|
4
4
|
import { NavMenu } from '../NavMenu';
|
|
5
5
|
import { PinButton } from '../PinButton';
|
|
6
|
-
import { classNames } from '../utils/classNames';
|
|
7
6
|
import { getInertProps } from '../utils/getInertProps';
|
|
8
|
-
import { dashboardSidebarClassnames } from './constants';
|
|
9
7
|
import { SidebarNav } from './SidebarNav';
|
|
10
8
|
import { Footer, SidebarContent, SidebarHeader, SidebarRoot, StyledPaper, Wrapper, } from './styles';
|
|
11
9
|
import { useLogic } from './useLogic';
|
|
@@ -13,9 +11,9 @@ import { useLogic } from './useLogic';
|
|
|
13
11
|
* Основной sidebar приложения
|
|
14
12
|
*/
|
|
15
13
|
export const DashboardSidebar = forwardRef((props, ref) => {
|
|
16
|
-
const { isPinned, isMobile, collapsedIn, onTogglePin, onMouseEnter, onMouseLeave, alertHeight,
|
|
14
|
+
const { isPinned, isMobile, collapsedIn, onTogglePin, onMouseEnter, onMouseLeave, alertHeight, classnames, wrapperClassnames, menu, header, isLoading, } = useLogic(props);
|
|
17
15
|
if (isLoading) {
|
|
18
16
|
return _jsx(DashboardSidebarSkeleton, {});
|
|
19
17
|
}
|
|
20
|
-
return (_jsx(Wrapper, { "$isPinned": isPinned, "$alertHeight": alertHeight, children: _jsx(SidebarRoot, { ref: ref, "$isPinned": isPinned, "$collapsedIn": collapsedIn, className:
|
|
18
|
+
return (_jsx(Wrapper, { "$isPinned": isPinned, "$alertHeight": alertHeight, className: wrapperClassnames, children: _jsx(SidebarRoot, { ref: ref, "$isPinned": isPinned, "$collapsedIn": collapsedIn, className: classnames, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, ...getInertProps(isMobile && !isPinned), children: _jsxs(StyledPaper, { variant: "outlined", children: [_jsxs(SidebarContent, { "$collapsedIn": collapsedIn, "$isPinned": isPinned, "$hasHeader": Boolean(header), children: [header && _jsx(SidebarHeader, { children: header }), _jsx(SidebarNav, { menu: _jsx(NavMenu, { collapsedIn: collapsedIn, items: menu.items }) })] }), _jsx(Footer, { children: _jsx(PinButton, { isPinned: isPinned, collapsedIn: collapsedIn, onClick: onTogglePin }) })] }) }) }));
|
|
21
19
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createUIKitClassname } from '../utils/createUIKitClassname';
|
|
2
2
|
export const dashboardSidebarClassnames = {
|
|
3
3
|
root: createUIKitClassname('dashboard-layout-sidebar'),
|
|
4
|
+
hasMenuOrganization: createUIKitClassname('dashboard-layout-sidebar_has-menu-organization'),
|
|
4
5
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { HEADER_HEIGHT_MOBILE } from '../DashboardLayout/constants';
|
|
2
|
+
import { MOBILE_BUTTON_HEIGHT } from '../MenuOrganization/OrganizationButton';
|
|
2
3
|
import { Paper } from '../Paper';
|
|
3
4
|
import { pinButtonClassnames } from '../PinButton';
|
|
4
5
|
import { styled } from '../styled';
|
|
6
|
+
import { dashboardSidebarClassnames } from './constants';
|
|
5
7
|
export const Wrapper = styled('div', {
|
|
6
8
|
shouldForwardProp: (prop) => !['$isPinned', '$alertHeight'].includes(prop),
|
|
7
9
|
}) `
|
|
@@ -29,6 +31,10 @@ export const Wrapper = styled('div', {
|
|
|
29
31
|
duration: theme.transitions.duration.standard,
|
|
30
32
|
});
|
|
31
33
|
}};
|
|
34
|
+
|
|
35
|
+
&.${dashboardSidebarClassnames.hasMenuOrganization} {
|
|
36
|
+
top: ${({ $alertHeight }) => `calc(${$alertHeight}px + ${HEADER_HEIGHT_MOBILE} + ${MOBILE_BUTTON_HEIGHT}) `};
|
|
37
|
+
}
|
|
32
38
|
}
|
|
33
39
|
`;
|
|
34
40
|
export const StyledPaper = styled(Paper) `
|
|
@@ -8,7 +8,6 @@ export declare const useLogic: (props: DashboardSidebarProps) => {
|
|
|
8
8
|
onMouseEnter: () => void;
|
|
9
9
|
onMouseLeave: () => void;
|
|
10
10
|
alertHeight: number;
|
|
11
|
-
className: string | undefined;
|
|
12
11
|
menu: {
|
|
13
12
|
items: [key: string, value: {
|
|
14
13
|
icon: import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
@@ -28,4 +27,6 @@ export declare const useLogic: (props: DashboardSidebarProps) => {
|
|
|
28
27
|
};
|
|
29
28
|
header: import("react").ReactNode;
|
|
30
29
|
isLoading: boolean;
|
|
30
|
+
classnames: string;
|
|
31
|
+
wrapperClassnames: string;
|
|
31
32
|
};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { useContext, useEffect, useRef } from 'react';
|
|
1
|
+
import { useContext, useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import { DashboardContext } from '../../DashboardContext';
|
|
3
3
|
import { dashboardLayoutHeaderClassnames } from '../../DashboardLayout/Header';
|
|
4
4
|
import { dashboardLayoutMainClassnames } from '../../DashboardLayout/Main';
|
|
5
5
|
import { DashboardSidebarContext } from '../../DashboardSidebarProvider';
|
|
6
6
|
import { useTheme } from '../../theme/hooks/useTheme';
|
|
7
7
|
import { useViewportType } from '../../useViewportType';
|
|
8
|
+
import { classNames } from '../../utils/classNames';
|
|
9
|
+
import { dashboardSidebarClassnames } from '../constants';
|
|
8
10
|
export const useLogic = (props) => {
|
|
9
11
|
const { className, menu, header, isLoading } = props;
|
|
10
12
|
const { onToggleSidebar, isPinned, onTogglePin, collapsedIn, setIsPopupOpen, } = useContext(DashboardSidebarContext);
|
|
11
|
-
const { alertHeight, isLoading: isDashboardLoading } = useContext(DashboardContext);
|
|
13
|
+
const { alertHeight, isLoading: isDashboardLoading, hasMenuOrganizationRef, } = useContext(DashboardContext);
|
|
12
14
|
const { isMobile } = useViewportType();
|
|
13
15
|
const hoverTimerRef = useRef(null);
|
|
14
16
|
const theme = useTheme();
|
|
@@ -78,6 +80,10 @@ export const useLogic = (props) => {
|
|
|
78
80
|
}
|
|
79
81
|
};
|
|
80
82
|
}, [collapsedIn, isPinned]);
|
|
83
|
+
const wrapperClassnames = useMemo(() => classNames({
|
|
84
|
+
[dashboardSidebarClassnames.hasMenuOrganization]: hasMenuOrganizationRef.current,
|
|
85
|
+
}), [hasMenuOrganizationRef.current]);
|
|
86
|
+
const classnames = classNames(className, dashboardSidebarClassnames.root);
|
|
81
87
|
return {
|
|
82
88
|
isPinned,
|
|
83
89
|
isMobile,
|
|
@@ -86,9 +92,10 @@ export const useLogic = (props) => {
|
|
|
86
92
|
onMouseEnter,
|
|
87
93
|
onMouseLeave,
|
|
88
94
|
alertHeight,
|
|
89
|
-
className,
|
|
90
95
|
menu,
|
|
91
96
|
header,
|
|
92
97
|
isLoading: isLoading || isDashboardLoading,
|
|
98
|
+
classnames,
|
|
99
|
+
wrapperClassnames,
|
|
93
100
|
};
|
|
94
101
|
};
|
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Button } from '../Button';
|
|
3
3
|
import { ContentState } from '../ContentState';
|
|
4
|
-
import { Popover } from '../Popover';
|
|
5
4
|
import { SearchField } from '../SearchField';
|
|
6
|
-
import { menuOrganizationClassnames } from './constants';
|
|
5
|
+
import { menuOrganizationClassnames, POPOVER_TITLE } from './constants';
|
|
7
6
|
import { MenuOrganizationSkeleton } from './MenuOrganizationSkeleton';
|
|
8
7
|
import { NoData } from './NoData';
|
|
9
8
|
import { OrganizationButton } from './OrganizationButton';
|
|
10
9
|
import { OrganizationList } from './OrganizationList';
|
|
11
10
|
import { OrganizationListSkeleton } from './OrganizationListSkeleton';
|
|
12
|
-
import { ActionWrapper, OrganizationsWrapper, SearchWrapper, StyledTypography, } from './styles';
|
|
11
|
+
import { ActionWrapper, ButtonWrapper, OrganizationsWrapper, SearchWrapper, StyledPopover, StyledTypography, } from './styles';
|
|
13
12
|
import { useLogic } from './useLogic';
|
|
14
13
|
export const MenuOrganization = (props) => {
|
|
15
14
|
const { anchorOrigin = { vertical: 'bottom', horizontal: 'right' }, transformOrigin = { vertical: 'top', horizontal: 'right' }, } = props;
|
|
16
|
-
const {
|
|
15
|
+
const { actionButtonProps, hasAction, isLoading, isError, onRetry, isComponentLoading, isShowOrganizationList, searchProps, popoverProps, organizationListProps, organizationButtonProps, isShowSearchField, isMobile, classnames, alertHeight, } = useLogic(props);
|
|
17
16
|
if (isComponentLoading) {
|
|
18
17
|
return _jsx(MenuOrganizationSkeleton, {});
|
|
19
18
|
}
|
|
20
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrganizationButton, { ...organizationButtonProps }), _jsxs(
|
|
19
|
+
return (_jsxs(_Fragment, { children: [_jsx(ButtonWrapper, { className: classnames, "$alertHeight": alertHeight, children: _jsx(OrganizationButton, { ...organizationButtonProps }) }), _jsxs(StyledPopover, { ...popoverProps, anchorOrigin: anchorOrigin, transformOrigin: transformOrigin, title: POPOVER_TITLE, children: [isShowSearchField && (_jsx(SearchWrapper, { children: _jsx(SearchField, { fullWidth: true, ...searchProps }) })), _jsx(OrganizationsWrapper, { "$isLoading": isLoading, className: menuOrganizationClassnames.root, children: _jsx(ContentState, { isLoading: isLoading, isCustom: isError, customState: {
|
|
21
20
|
title: (_jsx(StyledTypography, { children: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435" })),
|
|
22
21
|
Actions: (_jsx(Button, { variant: "light", color: "grey", onClick: onRetry, children: "\u041F\u043E\u043F\u0440\u043E\u0431\u043E\u0432\u0430\u0442\u044C \u0441\u043D\u043E\u0432\u0430" })),
|
|
23
22
|
className: menuOrganizationClassnames.errorPlaceholder,
|
|
24
|
-
}, loadingContent: _jsx(OrganizationListSkeleton, {}), children: isShowOrganizationList ? (_jsx(OrganizationList, { ...organizationListProps })) : (_jsx(NoData, {})) }) }),
|
|
23
|
+
}, loadingContent: _jsx(OrganizationListSkeleton, {}), children: isShowOrganizationList ? (_jsx(OrganizationList, { ...organizationListProps })) : (_jsx(NoData, {})) }) }), hasAction && (_jsx(ActionWrapper, { children: _jsx(Button, { fullWidth: true, ...actionButtonProps, size: isMobile ? 'large' : 'medium', children: actionButtonProps.text }) }))] })] }));
|
|
25
24
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MOBILE_BUTTON_HEIGHT = "68px";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MOBILE_BUTTON_HEIGHT = '68px';
|
|
@@ -2,6 +2,7 @@ import { Button } from '../../Button';
|
|
|
2
2
|
import { Chevron } from '../../Chevron';
|
|
3
3
|
import { styled } from '../../styled/styled';
|
|
4
4
|
import { Typography } from '../../Typography';
|
|
5
|
+
import { MOBILE_BUTTON_HEIGHT } from './constants';
|
|
5
6
|
export const StyledButton = styled(Button) `
|
|
6
7
|
display: flex;
|
|
7
8
|
align-items: center;
|
|
@@ -22,6 +23,27 @@ export const StyledButton = styled(Button) `
|
|
|
22
23
|
|
|
23
24
|
background-color: ${({ theme }) => theme.palette.primary[100]};
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
28
|
+
justify-content: space-between;
|
|
29
|
+
|
|
30
|
+
max-width: unset;
|
|
31
|
+
height: ${MOBILE_BUTTON_HEIGHT};
|
|
32
|
+
padding: ${({ theme }) => theme.spacing(3, 4)};
|
|
33
|
+
|
|
34
|
+
border-bottom: 1px solid ${({ theme }) => theme.palette.grey[300]};
|
|
35
|
+
border-radius: 0;
|
|
36
|
+
|
|
37
|
+
&:hover {
|
|
38
|
+
background-color: initial;
|
|
39
|
+
border-bottom: 1px solid ${({ theme }) => theme.palette.grey[300]};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&:active {
|
|
43
|
+
background-color: ${({ theme }) => theme.palette.primary[100]};
|
|
44
|
+
border-bottom: 1px solid ${({ theme }) => theme.palette.grey[300]};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
25
47
|
`;
|
|
26
48
|
export const StyledChevron = styled(Chevron) `
|
|
27
49
|
width: 24px;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
export declare const StyledMenuItem: import("../../styled").StyledComponent<import("../..").WithoutEmotionSpecific<Omit<import("@mui/material").MenuItemProps, "component">> & {
|
|
2
|
+
export declare const StyledMenuItem: import("../../styled").StyledComponent<import("../..").WithoutEmotionSpecific<Omit<import("@mui/material/MenuItem").MenuItemProps, "component">> & {
|
|
3
3
|
disabledReason?: string | undefined;
|
|
4
4
|
note?: string | undefined;
|
|
5
5
|
tooltipPlacement?: "bottom" | "left" | "right" | "top" | "bottom-end" | "bottom-start" | "left-end" | "left-start" | "right-end" | "right-start" | "top-end" | "top-start" | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { menuItemClasses } from '@mui/material/MenuItem';
|
|
1
2
|
import { Button } from '../../Button';
|
|
2
3
|
import { MenuItem } from '../../MenuItem';
|
|
3
4
|
import { styled } from '../../styled';
|
|
@@ -6,6 +7,14 @@ export const StyledMenuItem = styled(MenuItem) `
|
|
|
6
7
|
user-select: ${({ selected }) => (selected ? 'auto' : 'unset')};
|
|
7
8
|
|
|
8
9
|
padding: ${({ theme }) => theme.microSpacing(3, 6)};
|
|
10
|
+
|
|
11
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
12
|
+
padding: ${({ theme }) => theme.microSpacing(5, 6)};
|
|
13
|
+
|
|
14
|
+
&.${menuItemClasses.selected} {
|
|
15
|
+
padding: ${({ theme }) => theme.microSpacing(3, 6)};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
9
18
|
`;
|
|
10
19
|
export const StyledButton = styled(Button) `
|
|
11
20
|
justify-content: flex-start;
|
|
@@ -6,6 +6,12 @@ export const Item = styled.div `
|
|
|
6
6
|
|
|
7
7
|
width: 100%;
|
|
8
8
|
padding: ${({ theme }) => theme.spacing(0, 2)};
|
|
9
|
+
|
|
10
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
11
|
+
gap: ${({ theme }) => theme.spacing(3)};
|
|
12
|
+
|
|
13
|
+
padding: ${({ theme }) => theme.spacing(3)};
|
|
14
|
+
}
|
|
9
15
|
`;
|
|
10
16
|
export const Wrapper = styled.div `
|
|
11
17
|
overflow: hidden;
|
|
@@ -15,6 +21,12 @@ export const Wrapper = styled.div `
|
|
|
15
21
|
|
|
16
22
|
width: 100%;
|
|
17
23
|
padding: ${({ theme }) => theme.microSpacing(5, 0)};
|
|
24
|
+
|
|
25
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
26
|
+
gap: ${({ theme }) => theme.spacing(2)};
|
|
27
|
+
|
|
28
|
+
padding: 0;
|
|
29
|
+
}
|
|
18
30
|
`;
|
|
19
31
|
export const OrganizationInfoWrapper = styled.div `
|
|
20
32
|
display: flex;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const DEFAULT_LINK_BUTTON_NAME = "\u041F\u0435\u0440\u0435\u0439\u0442\u0438 \u043A \u0434\u0430\u043D\u043D\u044B\u043C \u043E\u0440\u0433\u0430\u043D\u0438\u0437\u0430\u0446\u0438\u0438";
|
|
2
|
+
export declare const POPOVER_TITLE = "\u0412\u044B\u0431\u043E\u0440 \u043E\u0440\u0433\u0430\u043D\u0438\u0437\u0430\u0446\u0438\u0438";
|
|
2
3
|
export declare const PLACEHOLDER_HEIGHT = "108px";
|
|
3
4
|
export declare const menuOrganizationClassnames: {
|
|
4
5
|
root: string;
|
|
5
6
|
errorPlaceholder: string;
|
|
7
|
+
mobileVisible: string;
|
|
6
8
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { createUIKitClassname } from '../utils/createUIKitClassname';
|
|
2
2
|
export const DEFAULT_LINK_BUTTON_NAME = 'Перейти к данным организации';
|
|
3
|
+
export const POPOVER_TITLE = 'Выбор организации';
|
|
3
4
|
export const PLACEHOLDER_HEIGHT = '108px';
|
|
4
5
|
export const menuOrganizationClassnames = {
|
|
5
6
|
root: createUIKitClassname('menu-organization'),
|
|
6
7
|
errorPlaceholder: createUIKitClassname('menu-organization__error-placeholder'),
|
|
8
|
+
mobileVisible: createUIKitClassname('menu-organization_visible'),
|
|
7
9
|
};
|
|
@@ -25,3 +25,14 @@ export declare const StyledTypography: import("../styled").StyledComponent<impor
|
|
|
25
25
|
} & import("react").HTMLAttributes<HTMLParagraphElement> & import("react").RefAttributes<HTMLSpanElement> & {
|
|
26
26
|
theme?: import("@emotion/react").Theme | undefined;
|
|
27
27
|
}, {}, {}>;
|
|
28
|
+
export declare const ButtonWrapper: import("../styled").StyledComponent<{
|
|
29
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
30
|
+
as?: import("react").ElementType<any, keyof import("react").JSX.IntrinsicElements> | undefined;
|
|
31
|
+
} & {
|
|
32
|
+
$alertHeight?: number | undefined;
|
|
33
|
+
}, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
|
|
34
|
+
export declare const StyledPopover: import("../styled").StyledComponent<import("..").WithoutEmotionSpecific<import("@mui/material").PopoverProps> & {
|
|
35
|
+
title?: string | undefined;
|
|
36
|
+
} & {
|
|
37
|
+
theme?: import("@emotion/react").Theme | undefined;
|
|
38
|
+
}, {}, {}>;
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { bottomDrawerClassnames } from '../BottomDrawer';
|
|
2
|
+
import { OFFSET_TOP_SCREEN } from '../BottomDrawer/constants';
|
|
3
|
+
import { HEADER_HEIGHT_MOBILE } from '../DashboardLayout/constants';
|
|
1
4
|
import { Grid } from '../Grid';
|
|
5
|
+
import { Popover } from '../Popover';
|
|
6
|
+
import { loadingPlaceholderClassnames } from '../placeholders/LoadingPlaceholder';
|
|
7
|
+
import { placeholderClassnames } from '../placeholders/Placeholder';
|
|
2
8
|
import { styled } from '../styled';
|
|
3
9
|
import { Typography } from '../Typography';
|
|
4
10
|
import { menuOrganizationClassnames, PLACEHOLDER_HEIGHT } from './constants';
|
|
@@ -6,12 +12,21 @@ export const ActionWrapper = styled.div `
|
|
|
6
12
|
padding: ${({ theme }) => theme.spacing(2)};
|
|
7
13
|
|
|
8
14
|
border-top: 1px solid ${({ theme }) => theme.palette.grey[300]};
|
|
15
|
+
|
|
16
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
17
|
+
padding: ${({ theme }) => theme.spacing(4)};
|
|
18
|
+
}
|
|
9
19
|
`;
|
|
10
20
|
export const SearchWrapper = styled.div `
|
|
11
21
|
max-width: 300px;
|
|
12
22
|
padding: ${({ theme }) => theme.spacing(2, 3)};
|
|
13
23
|
|
|
14
24
|
border-bottom: ${({ theme }) => `1px solid ${theme.palette.grey['300']}`};
|
|
25
|
+
|
|
26
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
27
|
+
max-width: unset;
|
|
28
|
+
padding: ${({ theme }) => theme.spacing(3, 4)};
|
|
29
|
+
}
|
|
15
30
|
`;
|
|
16
31
|
export const OrganizationsWrapper = styled.div `
|
|
17
32
|
overflow-y: auto;
|
|
@@ -25,6 +40,7 @@ export const OrganizationsWrapper = styled.div `
|
|
|
25
40
|
max-height: 328px;
|
|
26
41
|
|
|
27
42
|
& .${menuOrganizationClassnames.errorPlaceholder} {
|
|
43
|
+
display: flex;
|
|
28
44
|
gap: ${({ theme }) => theme.spacing(1)};
|
|
29
45
|
|
|
30
46
|
height: ${PLACEHOLDER_HEIGHT};
|
|
@@ -32,6 +48,27 @@ export const OrganizationsWrapper = styled.div `
|
|
|
32
48
|
|
|
33
49
|
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
34
50
|
width: 100%;
|
|
51
|
+
height: 100%;
|
|
52
|
+
max-height: unset;
|
|
53
|
+
|
|
54
|
+
& .${loadingPlaceholderClassnames.root} {
|
|
55
|
+
justify-content: unset;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
& .${menuOrganizationClassnames.errorPlaceholder} {
|
|
59
|
+
gap: ${({ theme }) => theme.spacing(6)};
|
|
60
|
+
justify-content: center;
|
|
61
|
+
|
|
62
|
+
height: 100%;
|
|
63
|
+
|
|
64
|
+
& .${placeholderClassnames.title} {
|
|
65
|
+
margin-bottom: unset;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
& .${placeholderClassnames.footer} {
|
|
69
|
+
margin-top: unset;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
35
72
|
}
|
|
36
73
|
`;
|
|
37
74
|
export const OrganizationData = styled(Grid) `
|
|
@@ -43,3 +80,48 @@ export const OrganizationData = styled(Grid) `
|
|
|
43
80
|
export const StyledTypography = styled(Typography) `
|
|
44
81
|
color: ${({ theme }) => theme.palette.grey[600]};
|
|
45
82
|
`;
|
|
83
|
+
export const ButtonWrapper = styled.div `
|
|
84
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
85
|
+
position: absolute;
|
|
86
|
+
z-index: ${({ theme }) => theme.zIndex.appBar - 1};
|
|
87
|
+
top: ${({ $alertHeight }) => `calc(${$alertHeight}px + ${HEADER_HEIGHT_MOBILE}) `};
|
|
88
|
+
left: 0;
|
|
89
|
+
|
|
90
|
+
/* Необходимо для анимации компонента вместе с sidebar */
|
|
91
|
+
transform: translateX(-100vw);
|
|
92
|
+
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
|
|
96
|
+
width: 100vw;
|
|
97
|
+
|
|
98
|
+
background-color: ${({ theme }) => theme.palette.background.default};
|
|
99
|
+
|
|
100
|
+
transition: ${({ theme }) => {
|
|
101
|
+
return theme.transitions.create(['transform'], {
|
|
102
|
+
duration: theme.transitions.duration.standard,
|
|
103
|
+
});
|
|
104
|
+
}};
|
|
105
|
+
|
|
106
|
+
&.${menuOrganizationClassnames.mobileVisible} {
|
|
107
|
+
transform: translateX(0);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
export const StyledPopover = styled(Popover) `
|
|
112
|
+
|
|
113
|
+
${({ theme }) => theme.breakpoints.down('sm')} {
|
|
114
|
+
& .${bottomDrawerClassnames.content} {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-direction: column;
|
|
117
|
+
|
|
118
|
+
height: calc(100vh - ${OFFSET_TOP_SCREEN});
|
|
119
|
+
|
|
120
|
+
@supports (height: 100dvh) {
|
|
121
|
+
height: calc(100dvh - ${OFFSET_TOP_SCREEN});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
`;
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
import { type ChangeEvent, type SyntheticEvent } from 'react';
|
|
1
|
+
import { type ChangeEvent, type MouseEvent, type SyntheticEvent } from 'react';
|
|
2
2
|
import { type MenuOrganizationProps, type Organization } from '../types';
|
|
3
3
|
type UseLogicParams<TData extends Organization & Record<string, unknown>> = MenuOrganizationProps<TData>;
|
|
4
4
|
export declare const useLogic: <TData extends Organization & Record<string, unknown>>({ organizations, onChangeSearch, onChange, currentOrganizationGroupLabel, currentOrganization, groupBy, onClose, onOpen, isOpen: isOpenPopover, isDisabled, disabledReason, isHidePersonalData, action, isLoading, isError, onRetry, renderItem, renderPreview, }: UseLogicParams<TData>) => {
|
|
5
|
-
|
|
6
|
-
text
|
|
7
|
-
|
|
5
|
+
actionButtonProps: {
|
|
6
|
+
text?: string | undefined;
|
|
7
|
+
component?: import("react").ElementType | undefined;
|
|
8
|
+
href?: string | undefined;
|
|
9
|
+
variant?: "light" | "link" | "text" | "contained" | "outlined" | undefined;
|
|
10
|
+
endIcon?: import("react").ReactNode;
|
|
11
|
+
startIcon?: import("react").ReactNode;
|
|
12
|
+
onClick: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
13
|
+
};
|
|
14
|
+
hasAction: boolean;
|
|
8
15
|
isLoading: boolean | undefined;
|
|
9
16
|
isError: boolean | undefined;
|
|
10
17
|
onRetry: () => void;
|
|
@@ -53,5 +60,8 @@ export declare const useLogic: <TData extends Organization & Record<string, unkn
|
|
|
53
60
|
hasSearch: boolean;
|
|
54
61
|
};
|
|
55
62
|
isShowSearchField: boolean;
|
|
63
|
+
isMobile: boolean;
|
|
64
|
+
classnames: string;
|
|
65
|
+
alertHeight: number;
|
|
56
66
|
};
|
|
57
67
|
export {};
|