@smartbooks-ai/layout 0.0.6 → 0.0.8

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.
Files changed (67) hide show
  1. package/dist/components/PageWithMenuLayout/AppSelect/index.d.ts +0 -1
  2. package/dist/components/PageWithMenuLayout/AppSelect/index.d.ts.map +1 -1
  3. package/dist/components/PageWithMenuLayout/AppSelect/index.js +2 -2
  4. package/dist/components/PageWithMenuLayout/PageWithMenuLayout.d.ts +0 -1
  5. package/dist/components/PageWithMenuLayout/PageWithMenuLayout.d.ts.map +1 -1
  6. package/dist/components/PageWithMenuLayout/PageWithMenuLayout.js +2 -2
  7. package/dist/index.d.ts +0 -1
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +0 -1
  10. package/dist/theme/colorPrimitives.d.ts +1 -1
  11. package/dist/theme/colorPrimitives.d.ts.map +1 -1
  12. package/dist/theme/index.d.ts.map +1 -1
  13. package/dist/theme/typography.d.ts.map +1 -1
  14. package/package.json +35 -32
  15. package/src/components/PageHeader/PageHeader.tsx +0 -15
  16. package/src/components/PageHeader/index.ts +0 -1
  17. package/src/components/PageHeader/styles.ts +0 -34
  18. package/src/components/PageWithMenuLayout/AppSelect/index.tsx +0 -66
  19. package/src/components/PageWithMenuLayout/AppSelect/styles.ts +0 -33
  20. package/src/components/PageWithMenuLayout/LogoHeaderImage.tsx +0 -44
  21. package/src/components/PageWithMenuLayout/LogoHeaderText.tsx +0 -48
  22. package/src/components/PageWithMenuLayout/MenuItemWithChildren/MenuItemWithChildren.tsx +0 -149
  23. package/src/components/PageWithMenuLayout/MenuItemWithChildren/styles.ts +0 -179
  24. package/src/components/PageWithMenuLayout/MenuSelect/index.tsx +0 -78
  25. package/src/components/PageWithMenuLayout/MenuSelect/styles.ts +0 -97
  26. package/src/components/PageWithMenuLayout/MultiSubscriptionsMenuItems/ConsolidationIcon.tsx +0 -6
  27. package/src/components/PageWithMenuLayout/MultiSubscriptionsMenuItems/MultiSubscriptionsMenuItems.tsx +0 -120
  28. package/src/components/PageWithMenuLayout/MultiSubscriptionsMenuItems/consolidation.svg +0 -8
  29. package/src/components/PageWithMenuLayout/MultiSubscriptionsMenuItems/index.ts +0 -1
  30. package/src/components/PageWithMenuLayout/MultiSubscriptionsMenuItems/styles.ts +0 -10
  31. package/src/components/PageWithMenuLayout/PageWithMenuLayout.tsx +0 -103
  32. package/src/components/PageWithMenuLayout/UserProfileSelect/index.tsx +0 -64
  33. package/src/components/PageWithMenuLayout/UserProfileSelect/styles.ts +0 -8
  34. package/src/components/PageWithMenuLayout/index.ts +0 -8
  35. package/src/components/PageWithMenuLayout/styles.ts +0 -110
  36. package/src/components/PageWithMenuLayout/types.ts +0 -7
  37. package/src/components/PageWithMenuLayout/useMenuToggle.ts +0 -19
  38. package/src/components/index.ts +0 -3
  39. package/src/emotion.d.ts +0 -76
  40. package/src/hooks/index.ts +0 -2
  41. package/src/hooks/useIsAuthorized.ts +0 -35
  42. package/src/hooks/useToggle.ts +0 -27
  43. package/src/index.ts +0 -7
  44. package/src/package-isolation.test.ts +0 -60
  45. package/src/security/AuthorizedContent/index.tsx +0 -77
  46. package/src/security/AuthorizedContent/state.ts +0 -8
  47. package/src/security/AuthorizedContent/useAuthorizationState.ts +0 -42
  48. package/src/security/ProfileContext/ProfileContext.tsx +0 -37
  49. package/src/security/ProfileContext/index.ts +0 -4
  50. package/src/security/ProfileContext/types.ts +0 -7
  51. package/src/security/ProfileContext/useProfile.tsx +0 -7
  52. package/src/security/UserProfile.ts +0 -48
  53. package/src/security/index.ts +0 -2
  54. package/src/theme/colorPrimitives.ts +0 -107
  55. package/src/theme/colors.ts +0 -78
  56. package/src/theme/font.ts +0 -27
  57. package/src/theme/globalStyles.tsx +0 -55
  58. package/src/theme/index.tsx +0 -228
  59. package/src/theme/radius.ts +0 -12
  60. package/src/theme/spacing.ts +0 -12
  61. package/src/theme/typography.ts +0 -40
  62. package/src/utils/assertNever.ts +0 -14
  63. package/src/utils/index.ts +0 -2
  64. package/src/utils/shouldNotForwardPropsWithKeys.ts +0 -7
  65. package/tsconfig.json +0 -34
  66. package/tsconfig.layout.tsbuildinfo +0 -1
  67. package/vitest.config.ts +0 -10
@@ -1,179 +0,0 @@
1
- import { css } from '@emotion/react';
2
- import styled from '@emotion/styled';
3
- import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDownRounded';
4
- import MuiListItemIcon from '@mui/material/ListItemIcon';
5
- import MuiListItemText, { listItemTextClasses } from '@mui/material/ListItemText';
6
- import MuiMenuItem, { menuItemClasses } from '@mui/material/MenuItem';
7
- import MuiMenuList from '@mui/material/MenuList';
8
- import { rem } from 'polished';
9
-
10
- import { shouldNotForwardPropsWithKeys } from '../../../utils/shouldNotForwardPropsWithKeys';
11
-
12
- const iconMargin = rem(-2);
13
-
14
- type MenuItemProps = {
15
- isHighlighted: boolean;
16
- elevation?: number;
17
- isMenuOpen: boolean;
18
- isTitle: boolean;
19
- };
20
- export const MenuItem = styled(
21
- MuiMenuItem,
22
- shouldNotForwardPropsWithKeys<MenuItemProps>(['isHighlighted', 'elevation', 'isMenuOpen', 'isTitle']),
23
- )<MenuItemProps>(
24
- ({ theme, elevation = 0, isHighlighted, isMenuOpen, isTitle, disabled }) => css`
25
- display: flex;
26
-
27
- align-items: center;
28
-
29
- padding: ${theme.my.spacing.xxs};
30
- padding-left: 0;
31
- margin-top: ${elevation === 0 && isMenuOpen && isTitle && theme.my.spacing.sm};
32
- margin-left: ${!isMenuOpen ? `calc(${theme.my.spacing.xxs} - ${iconMargin})` : 0};
33
-
34
- font: ${isHighlighted ? theme.my.font.nav2 : theme.my.font.nav1};
35
-
36
- color: ${theme.my.colors.text.white};
37
-
38
- transition:
39
- font-weight 0.3s,
40
- margin 0.3s;
41
-
42
- &:hover {
43
- background-color: ${theme.my.colors.background.hover};
44
- }
45
-
46
- ${disabled &&
47
- css`
48
- &.${menuItemClasses.disabled} {
49
- text-transform: uppercase;
50
-
51
- pointer-events: initial;
52
-
53
- background-color: initial;
54
-
55
- opacity: 1;
56
- }
57
- `};
58
- `,
59
- );
60
-
61
- export const ListItemIcon = styled(MuiListItemIcon)`
62
- /* Icons from MUI have small paddings, so we need to artificially move them 2px ⬅︎ */
63
- margin-left: ${iconMargin};
64
-
65
- /* Increasing specificity */
66
- &&& {
67
- min-width: 1.75rem;
68
- }
69
-
70
- color: ${({ theme }) => theme.my.colors.text.white};
71
- `;
72
-
73
- type ListItemTextProps = {
74
- isHighlighted: boolean;
75
- isTitle: boolean;
76
- elevation: number;
77
- };
78
- export const ListItemText = styled(
79
- MuiListItemText,
80
- shouldNotForwardPropsWithKeys<ListItemTextProps>(['isHighlighted', 'elevation', 'isTitle']),
81
- )<ListItemTextProps>(
82
- ({ theme, isHighlighted, elevation, isTitle }) => css`
83
- margin-top: 0;
84
- margin-bottom: 0;
85
-
86
- white-space: nowrap;
87
-
88
- .${listItemTextClasses.primary} {
89
- padding-left: calc(${Math.max(elevation - 1, 0)} * ${theme.my.spacing.xxs});
90
-
91
- overflow: hidden;
92
- text-overflow: ellipsis;
93
-
94
- font: ${isHighlighted ? theme.my.font.nav2 : theme.my.font.nav1};
95
-
96
- transition: font 0.3s;
97
-
98
- ${isTitle &&
99
- css`
100
- font-weight: 800;
101
- `};
102
- }
103
- `,
104
- );
105
-
106
- export const ListItem = styled.section`
107
- display: flex;
108
-
109
- width: 100%;
110
-
111
- overflow: hidden;
112
- `;
113
-
114
- type ArrowDownIconProps = {
115
- isExpanded: boolean;
116
- isVisible: boolean;
117
- };
118
- export const ArrowDownIcon = styled(
119
- ArrowDropDownIcon,
120
- shouldNotForwardPropsWithKeys<ArrowDownIconProps>(['isExpanded', 'isVisible']),
121
- )<ArrowDownIconProps>(
122
- ({ isExpanded, isVisible, theme }) => css`
123
- color: ${isExpanded ? theme.my.colors.primitives.common.white : theme.my.colors.primitives.darkNavy[300]};
124
-
125
- opacity: ${isVisible ? 1 : 0};
126
-
127
- transform: rotate(${isExpanded ? 180 : 0}deg);
128
-
129
- transition:
130
- transform 0.3s,
131
- color 0.3s,
132
- opacity 0.3s;
133
- `,
134
- );
135
-
136
- type MenuListProps = {
137
- elevation: number;
138
- };
139
- export const MenuList = styled(MuiMenuList, shouldNotForwardPropsWithKeys<MenuListProps>(['elevation']))<MenuListProps>`
140
- padding-top: 0;
141
- padding-bottom: 0;
142
-
143
- overflow: auto;
144
-
145
- background-color: ${({ elevation, theme }) =>
146
- [
147
- theme.my.colors.primitives.darkNavy[900],
148
- theme.my.colors.primitives.darkNavy[800],
149
- theme.my.colors.primitives.darkNavy[700],
150
- ][elevation]};
151
- border-radius: ${({ elevation, theme }) => elevation === 1 && theme.my.radius.md};
152
- `;
153
-
154
- type ActiveMenuItemIndicatorProps = {
155
- visible: boolean;
156
- isMenuOpen: boolean;
157
- };
158
- export const ActiveMenuItemIndicator = styled(
159
- 'div',
160
- shouldNotForwardPropsWithKeys<ActiveMenuItemIndicatorProps>(['visible', 'isMenuOpen']),
161
- )<ActiveMenuItemIndicatorProps>(
162
- ({ theme, visible, isMenuOpen }) => css`
163
- display: inline-block;
164
-
165
- width: ${isMenuOpen ? theme.my.spacing.xxxs : 0};
166
- height: 1rem;
167
-
168
- margin-right: ${theme.my.spacing.xxs};
169
-
170
- background-color: transparent;
171
- border-radius: ${theme.my.radius.sm};
172
-
173
- transition: 0.3s;
174
- ${visible &&
175
- css`
176
- background-color: ${theme.my.colors.secondary.main};
177
- `};
178
- `,
179
- );
@@ -1,78 +0,0 @@
1
- import { useState } from 'react';
2
-
3
- import { Fade } from '@mui/material';
4
- import useResizeObserver from 'use-resize-observer';
5
-
6
- import * as Styled from './styles';
7
-
8
- type Props = {
9
- isExpanded: boolean;
10
- renderMenuItems: (params: { closeMenu: () => void }) => React.ReactElement[];
11
- startIcon?: React.ReactNode;
12
- selectedOptionText?: string;
13
- menuPosition?: 'top' | 'bottom';
14
- };
15
-
16
- export const MenuSelect: React.FC<Props> = ({
17
- isExpanded,
18
- renderMenuItems,
19
- startIcon,
20
- selectedOptionText,
21
- menuPosition = 'bottom',
22
- }) => {
23
- const openMenu: React.MouseEventHandler<HTMLElement> = (event) => {
24
- setAnchorEl(event.currentTarget);
25
- };
26
- const closeMenu = () => {
27
- setAnchorEl(undefined);
28
- };
29
- const [anchorEl, setAnchorEl] = useState<HTMLElement>();
30
- const isMenuOpen = Boolean(anchorEl);
31
-
32
- const menuItems = renderMenuItems({ closeMenu });
33
-
34
- const { height: bodyHeight } = useResizeObserver({ ref: document.body });
35
-
36
- return (
37
- <>
38
- <Styled.SelectorButton
39
- isMenuExpanded={isExpanded}
40
- variant="outlined"
41
- aria-haspopup="true"
42
- disableElevation={true}
43
- onClick={openMenu}
44
- endIcon={<Styled.UnfoldMoreIcon />}
45
- fullWidth={true}
46
- startIcon={startIcon}
47
- disabled={!menuItems.length}
48
- >
49
- <Fade in={isExpanded}>
50
- <Styled.SelectedOptionText>{selectedOptionText}</Styled.SelectedOptionText>
51
- </Fade>
52
- </Styled.SelectorButton>
53
-
54
- <Styled.Menu
55
- anchorEl={anchorEl}
56
- open={isMenuOpen}
57
- onClose={closeMenu}
58
- sx={{ top: menuPosition === 'top' ? -4 : 4 }}
59
- slotProps={{
60
- paper: {
61
- style: {
62
- maxHeight:
63
- anchorEl && bodyHeight ? bodyHeight - anchorEl?.getBoundingClientRect().bottom - 16 : undefined,
64
- },
65
- },
66
- }}
67
- anchorOrigin={
68
- menuPosition === 'top' ? { horizontal: 'left', vertical: 'top' } : { horizontal: 'left', vertical: 'bottom' }
69
- }
70
- transformOrigin={
71
- menuPosition === 'top' ? { horizontal: 'left', vertical: 'bottom' } : { horizontal: 'left', vertical: 'top' }
72
- }
73
- >
74
- {menuItems}
75
- </Styled.Menu>
76
- </>
77
- );
78
- };
@@ -1,97 +0,0 @@
1
- import { css } from '@emotion/react';
2
- import styled from '@emotion/styled';
3
- import MuiUnfoldMoreIcon from '@mui/icons-material/UnfoldMoreRounded';
4
- import Button, { buttonClasses } from '@mui/material/Button';
5
- import MuiMenu, { menuClasses } from '@mui/material/Menu';
6
-
7
- import { shouldNotForwardPropsWithKeys } from '../../../utils/shouldNotForwardPropsWithKeys';
8
-
9
- type SelectorButtonProps = {
10
- isMenuExpanded: boolean;
11
- };
12
- export const SelectorButton = styled(
13
- Button,
14
- shouldNotForwardPropsWithKeys<SelectorButtonProps>(['isMenuExpanded']),
15
- )<SelectorButtonProps>(
16
- ({ theme, isMenuExpanded, disabled }) => css`
17
- display: ${disabled && 'none'};
18
-
19
- justify-content: flex-start;
20
-
21
- min-width: 0;
22
- height: 2.375rem;
23
-
24
- padding-right: calc(${theme.my.spacing.xxxs} - 0.0625rem);
25
- padding-left: calc(${theme.my.spacing.xxxs} - 0.0625rem);
26
-
27
- text-overflow: ellipsis;
28
-
29
- color: ${theme.my.colors.primitives.common.white};
30
-
31
- white-space: nowrap;
32
-
33
- border-radius: ${theme.my.radius.md};
34
-
35
- transition:
36
- height 0.3s,
37
- padding 0.3s;
38
-
39
- :hover {
40
- &.${buttonClasses.outlined} {
41
- border-color: ${theme.my.colors.primitives.common.white};
42
- }
43
- }
44
-
45
- ${isMenuExpanded &&
46
- css`
47
- height: 3rem;
48
-
49
- padding-right: ${theme.my.spacing.xxs};
50
- padding-left: ${theme.my.spacing.xxs};
51
- `}
52
-
53
- .${buttonClasses.startIcon} {
54
- width: 1.75rem;
55
- height: 1.75rem;
56
-
57
- margin-right: 0;
58
- margin-left: 0;
59
-
60
- transition: 0.3s;
61
-
62
- ${isMenuExpanded &&
63
- css`
64
- width: 2rem;
65
- height: 2rem;
66
- `}
67
- }
68
-
69
- .${buttonClasses.endIcon} {
70
- margin-right: ${theme.my.spacing.xxxs};
71
- }
72
- `,
73
- );
74
-
75
- export const SelectedOptionText = styled.span`
76
- flex: 1;
77
-
78
- padding-left: ${({ theme }) => theme.my.spacing.xxs};
79
-
80
- overflow: hidden;
81
- text-overflow: ellipsis;
82
-
83
- font: ${({ theme }) => theme.my.font.highlight3};
84
-
85
- text-align: left;
86
- `;
87
-
88
- export const Menu = styled(MuiMenu)`
89
- .${menuClasses.root} {
90
- padding: 0;
91
- }
92
- `;
93
-
94
- export const UnfoldMoreIcon = styled(MuiUnfoldMoreIcon)`
95
- width: 1rem;
96
- height: 1rem;
97
- `;
@@ -1,6 +0,0 @@
1
- const ConsolidationIcon = (props: React.SVGProps<SVGSVGElement>) => (
2
- <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 36 36" {...props}>
3
- <path d="M9.8 18.8h16.4v3.08h1.6V17.2h-9V14h-1.6v3.2h-9v4.68h1.6zM14 23H4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2M4 31v-6h10v6ZM32 23H22a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2m-10 8v-6h10v6ZM13 13h10a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H13a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2m0-8h10v6H13Z" />
4
- </svg>
5
- );
6
- export default ConsolidationIcon;
@@ -1,120 +0,0 @@
1
- import { Fragment, useEffect, useState } from 'react';
2
-
3
- import {
4
- Business as BusinessIcon,
5
- ExpandLess as ExpandLessIcon,
6
- ExpandMore as ExpandMoreIcon,
7
- } from '@mui/icons-material';
8
- import { Collapse, Divider, List, ListItemIcon, MenuItem, Tooltip } from '@mui/material';
9
- import { AvailableCompany, AvailableTenant } from '@smartbooks-ai/api-client';
10
-
11
- import ConsolidationIcon from './ConsolidationIcon';
12
- import * as Styled from './styles';
13
-
14
- import { assertNever } from '../../../utils/assertNever';
15
-
16
- type Props = {
17
- selectedTenant?: AvailableTenant;
18
- tenants: AvailableTenant[];
19
- onCompanySelected: (company: AvailableCompany) => void;
20
- selectedCompanyCode: string | undefined;
21
- };
22
-
23
- export const MultiSubscriptionsMenuItems: React.FC<Props> = ({
24
- selectedTenant,
25
- tenants,
26
- onCompanySelected,
27
- selectedCompanyCode,
28
- }) => {
29
- const [openTenants, setOpenTenants] = useState<string[]>([]);
30
-
31
- const toggleTenant = (tenantCode: string) => {
32
- if (openTenants.includes(tenantCode)) {
33
- setOpenTenants(openTenants.filter((a) => a !== tenantCode));
34
- } else {
35
- setOpenTenants([...openTenants, tenantCode]);
36
- }
37
- };
38
-
39
- useEffect(() => {
40
- if (selectedTenant) {
41
- setOpenTenants([selectedTenant.code]);
42
- }
43
- }, [selectedTenant]);
44
-
45
- const sortedTenants = tenants.toSorted((a, b) => (a.description || '').localeCompare(b.description || ''));
46
-
47
- const [highlightedCompanyMenuItem, setHighlightedCompanyMenuItem] = useState<HTMLElement | null>(null);
48
-
49
- return (
50
- <>
51
- {sortedTenants.map((tenant) => {
52
- const sortedCompanies = tenant.companies.toSorted((a, b) =>
53
- a.companyType === 'consolidation' && b.companyType !== 'consolidation'
54
- ? -1
55
- : a.companyType !== 'consolidation' && b.companyType === 'consolidation'
56
- ? 1
57
- : (a.description || '').localeCompare(b.description || ''),
58
- );
59
- const isOpen = tenants.length === 1 || openTenants.includes(tenant.code);
60
-
61
- return (
62
- <Fragment key={tenant.code}>
63
- {tenants.length > 1 && (
64
- <MenuItem onClick={() => toggleTenant(tenant.code)}>
65
- {tenant.description}
66
-
67
- <ListItemIcon sx={{ marginLeft: '1em' }}>
68
- {isOpen ? <ExpandLessIcon fontSize="small" /> : <ExpandMoreIcon fontSize="small" />}
69
- </ListItemIcon>
70
- </MenuItem>
71
- )}
72
- <Collapse
73
- in={isOpen}
74
- timeout="auto"
75
- unmountOnExit={true}
76
- onEntered={() => {
77
- if (tenant.code === selectedTenant?.code)
78
- highlightedCompanyMenuItem?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
79
- }}
80
- >
81
- <List component="div" disablePadding={true}>
82
- <Divider />
83
-
84
- {sortedCompanies.map((company) => (
85
- <MenuItem
86
- key={company.code}
87
- onClick={() => onCompanySelected(company)}
88
- selected={company.code === selectedCompanyCode}
89
- autoFocus={company.code === selectedCompanyCode}
90
- ref={(el) => {
91
- if (company.code === selectedCompanyCode) setHighlightedCompanyMenuItem(el);
92
- }}
93
- >
94
- <ListItemIcon>
95
- {company.companyType === 'consolidation' ? (
96
- <Tooltip title="Consolidation" disableInteractive={true}>
97
- <Styled.IconContainer>
98
- <ConsolidationIcon fontSize="inherit" />
99
- </Styled.IconContainer>
100
- </Tooltip>
101
- ) : company.companyType === 'regular' ? (
102
- <Styled.IconContainer>
103
- <BusinessIcon fontSize="inherit" />
104
- </Styled.IconContainer>
105
- ) : (
106
- assertNever(company.companyType)
107
- )}
108
- </ListItemIcon>
109
-
110
- {company.description}
111
- </MenuItem>
112
- ))}
113
- </List>
114
- </Collapse>
115
- </Fragment>
116
- );
117
- })}
118
- </>
119
- );
120
- };
@@ -1,8 +0,0 @@
1
- <svg fill="currentColor" viewBox="0 0 36 36" xmlns="http://www.w3.org/2000/svg">
2
- <polygon
3
- points="9.8 18.8 26.2 18.8 26.2 21.88 27.8 21.88 27.8 17.2 18.8 17.2 18.8 14 17.2 14 17.2 17.2 8.2 17.2 8.2 21.88 9.8 21.88 9.8 18.8">
4
- </polygon>
5
- <path d="M14,23H4a2,2,0,0,0-2,2v6a2,2,0,0,0,2,2H14a2,2,0,0,0,2-2V25A2,2,0,0,0,14,23ZM4,31V25H14v6Z"></path>
6
- <path d="M32,23H22a2,2,0,0,0-2,2v6a2,2,0,0,0,2,2H32a2,2,0,0,0,2-2V25A2,2,0,0,0,32,23ZM22,31V25H32v6Z"></path>
7
- <path d="M13,13H23a2,2,0,0,0,2-2V5a2,2,0,0,0-2-2H13a2,2,0,0,0-2,2v6A2,2,0,0,0,13,13Zm0-8H23v6H13Z"></path>
8
- </svg>
@@ -1 +0,0 @@
1
- export { MultiSubscriptionsMenuItems } from './MultiSubscriptionsMenuItems';
@@ -1,10 +0,0 @@
1
- import styled from '@emotion/styled';
2
-
3
- export const IconContainer = styled.div`
4
- position: relative;
5
-
6
- width: 1.25rem;
7
- height: 1.25rem;
8
-
9
- font-size: 1.25rem;
10
- `;
@@ -1,103 +0,0 @@
1
- import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
2
- import Fade from '@mui/material/Fade';
3
- import MenuList from '@mui/material/MenuList';
4
- import { AvailableCompany } from '@smartbooks-ai/api-client';
5
- import { createPortal } from 'react-dom';
6
- import { NavLink, Outlet } from 'react-router';
7
-
8
- import LogoHeaderImage from './LogoHeaderImage';
9
- import LogoHeaderText from './LogoHeaderText';
10
- import { AppSelect, MenuItemWithChildren, UserProfileSelect } from './index';
11
- import * as Styled from './styles';
12
- import { MenuStructure } from './types';
13
- import { useMenuToggle } from './useMenuToggle';
14
-
15
- import { UserProfile } from '../../security/UserProfile';
16
-
17
- export type PageWithMenuLayoutProps = {
18
- resolvedCompanyCode?: string;
19
- topMenu?: MenuStructure;
20
- bottomMenu: MenuStructure;
21
- profile: UserProfile | null;
22
- tenantCode?: string;
23
- switchToCompany: (company: AvailableCompany) => Promise<void>;
24
- logout: () => void;
25
- additionalOutletContent?: React.ReactNode;
26
- };
27
-
28
- export const PageWithMenuLayout: React.FC<PageWithMenuLayoutProps> = ({
29
- resolvedCompanyCode,
30
- topMenu,
31
- bottomMenu,
32
- profile,
33
- tenantCode,
34
- switchToCompany,
35
- logout,
36
- additionalOutletContent,
37
- }) => {
38
- const { isExpanded, openMenu, toggleIsExpanded } = useMenuToggle();
39
-
40
- return (
41
- <>
42
- <Styled.LockMenuButton onClick={toggleIsExpanded} isExpanded={isExpanded}>
43
- <KeyboardArrowLeftIcon fontSize="inherit" />
44
- </Styled.LockMenuButton>
45
-
46
- {createPortal(
47
- <Styled.Drawer open={isExpanded} variant="permanent">
48
- <Styled.Header>
49
- <Styled.LogoContainer>
50
- <NavLink to="/">
51
- <LogoHeaderImage height={24} />
52
- </NavLink>
53
- </Styled.LogoContainer>
54
-
55
- <Fade in={isExpanded}>
56
- <NavLink to="/">
57
- <LogoHeaderText height={12} />
58
- </NavLink>
59
- </Fade>
60
- </Styled.Header>
61
- <AppSelect
62
- tenantCode={tenantCode}
63
- companyCode={resolvedCompanyCode}
64
- isExpanded={isExpanded}
65
- profile={profile}
66
- onCompanyClicked={switchToCompany}
67
- />
68
-
69
- <Styled.TopMenuList>
70
- {topMenu?.map((firstLevelItem) => (
71
- <MenuItemWithChildren
72
- key={firstLevelItem.title}
73
- menuItem={firstLevelItem}
74
- isMenuOpen={isExpanded}
75
- openMenu={openMenu}
76
- />
77
- ))}
78
- </Styled.TopMenuList>
79
-
80
- <MenuList disablePadding={true}>
81
- {bottomMenu?.map((firstLevelItem) => (
82
- <MenuItemWithChildren
83
- key={firstLevelItem.title}
84
- menuItem={firstLevelItem}
85
- isMenuOpen={isExpanded}
86
- openMenu={openMenu}
87
- />
88
- ))}
89
- </MenuList>
90
-
91
- <UserProfileSelect isTextVisible={isExpanded} profile={profile} logout={logout} />
92
- </Styled.Drawer>,
93
- document.body,
94
- )}
95
-
96
- <Styled.Main isLocked={isExpanded}>
97
- <Outlet />
98
-
99
- {additionalOutletContent}
100
- </Styled.Main>
101
- </>
102
- );
103
- };
@@ -1,64 +0,0 @@
1
- import { useState } from 'react';
2
-
3
- import AccountCircleRoundedIcon from '@mui/icons-material/AccountCircleRounded';
4
- import { Fade } from '@mui/material';
5
- import MenuItem from '@mui/material/MenuItem';
6
- import { GlobalRole } from '@smartbooks-ai/api-client';
7
-
8
- import * as Styled from './styles';
9
-
10
- import { useIsAuthorized } from '../../../hooks/useIsAuthorized';
11
- import { useToggle } from '../../../hooks/useToggle';
12
- import { UserProfile } from '../../../security/ProfileContext';
13
- import * as MenuItemWithChildrenStyled from '../MenuItemWithChildren/styles';
14
-
15
- type Props = {
16
- isTextVisible: boolean;
17
- profile: UserProfile | null;
18
- logout: () => void;
19
- };
20
-
21
- export const UserProfileSelect: React.FC<Props> = ({ isTextVisible, profile, logout }) => {
22
- const { value: isMenuOpen, switchOn: openMenu, switchOff: closeMenu } = useToggle();
23
- const getIsAuthorized = useIsAuthorized();
24
-
25
- const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
26
-
27
- return (
28
- <>
29
- <MenuItemWithChildrenStyled.MenuItem
30
- isTitle={false}
31
- isMenuOpen={isTextVisible}
32
- ref={setAnchorEl}
33
- isHighlighted={false}
34
- onClick={openMenu}
35
- >
36
- <MenuItemWithChildrenStyled.ListItemIcon>
37
- <AccountCircleRoundedIcon fontSize="small" />
38
- </MenuItemWithChildrenStyled.ListItemIcon>
39
-
40
- <Fade in={isTextVisible}>
41
- <MenuItemWithChildrenStyled.ListItemText elevation={0} isHighlighted={false} isTitle={false}>
42
- {profile?.displayName ?? 'My account'}
43
- </MenuItemWithChildrenStyled.ListItemText>
44
- </Fade>
45
-
46
- <MenuItemWithChildrenStyled.ArrowDownIcon isExpanded={isMenuOpen} isVisible={isTextVisible} />
47
- </MenuItemWithChildrenStyled.MenuItem>
48
-
49
- <Styled.Menu
50
- anchorOrigin={{ horizontal: 'left', vertical: 'top' }}
51
- transformOrigin={{ horizontal: 'left', vertical: 'bottom' }}
52
- anchorEl={anchorEl}
53
- open={isMenuOpen}
54
- onClose={closeMenu}
55
- >
56
- <MenuItem disabled={true}>{profile?.email}</MenuItem>
57
- {getIsAuthorized({ globalRole: GlobalRole.GlobalAdmin }) && (
58
- <MenuItem onClick={() => window.open('/ac/ga', '_blank')}>System admin</MenuItem>
59
- )}
60
- <MenuItem onClick={logout}>Logout</MenuItem>
61
- </Styled.Menu>
62
- </>
63
- );
64
- };
@@ -1,8 +0,0 @@
1
- import styled from '@emotion/styled';
2
- import MuiMenu, { menuClasses } from '@mui/material/Menu';
3
-
4
- export const Menu = styled(MuiMenu)`
5
- .${menuClasses.root} {
6
- padding: 0;
7
- }
8
- `;
@@ -1,8 +0,0 @@
1
- export { AppSelect } from './AppSelect';
2
- export { MenuSelect } from './MenuSelect';
3
- export { MultiSubscriptionsMenuItems } from './MultiSubscriptionsMenuItems';
4
- export { MenuItemWithChildren } from './MenuItemWithChildren/MenuItemWithChildren';
5
- export { UserProfileSelect } from './UserProfileSelect';
6
- export { PageWithMenuLayout } from './PageWithMenuLayout';
7
- export { default as LogoHeaderImage } from './LogoHeaderImage';
8
- export { default as LogoHeaderText } from './LogoHeaderText';