@campxdev/react-blueprint 1.1.5 → 1.1.7
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/.prettierrc +8 -0
- package/package.json +4 -1
- package/src/App.tsx +26 -10
- package/src/components/Assets/Icons/IconComponents/AcademicIcon.tsx +41 -0
- package/src/components/Assets/Icons/IconComponents/AccordionArrow.tsx +23 -0
- package/src/components/Assets/Icons/IconComponents/DeleteIcon.tsx +58 -0
- package/src/components/Assets/Icons/IconComponents/EditIcon.tsx +43 -0
- package/src/components/Assets/Icons/IconComponents/NoteIcon.tsx +41 -0
- package/src/components/Assets/Icons/IconComponents/RedirectIcon.tsx +36 -0
- package/src/components/Assets/Icons/IconComponents/ViewIcon.tsx +34 -0
- package/src/components/Assets/Icons/Icons.tsx +68 -55
- package/src/components/Charts/BarChart/BarChart.tsx +33 -9
- package/src/components/Charts/LineChart/LineChart.tsx +10 -4
- package/src/components/Charts/PieChart/PieChart.tsx +3 -2
- package/src/components/Charts/TreeMap/TreeMap.tsx +1 -0
- package/src/components/Charts/export.ts +4 -0
- package/src/components/Charts/types/types.ts +12 -2
- package/src/components/DataDisplay/Accordion/Accordion.tsx +42 -46
- package/src/components/DataDisplay/AccordionGroup/AccordionGroup.tsx +30 -0
- package/src/components/DataDisplay/Avatar/Avatar.tsx +18 -29
- package/src/components/DataDisplay/Card/Card.tsx +29 -8
- package/src/components/DataDisplay/Chips/Chips.tsx +91 -0
- package/src/components/DataDisplay/DataTable/DataTable.tsx +14 -6
- package/src/components/DataDisplay/export.ts +6 -5
- package/src/components/DataDisplay/styles.tsx +2 -3
- package/src/components/Feedback/Snackbar/Snackbar.tsx +6 -5
- package/src/components/Input/DatePicker/DatePicker.tsx +58 -0
- package/src/components/Input/FormActions/FormActions.tsx +49 -0
- package/src/components/Input/FormControlWrapper/FormControlWrapper.tsx +70 -0
- package/src/components/Input/IconButtons/IconButtons/DeleteButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons/EditButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons/RedirectButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons/ViewButton.tsx +10 -0
- package/src/components/Input/IconButtons/IconButtons.tsx +11 -0
- package/src/components/Input/LabelWrapper/LabelWrapper.tsx +1 -1
- package/src/components/Input/SingleSelect/SingleSelect.tsx +43 -54
- package/src/components/Input/{Chips/Chips.tsx → Tags/Tags.tsx} +14 -14
- package/src/components/Input/TimePicker/TimePicker.tsx +39 -0
- package/src/components/Input/export.ts +13 -8
- package/src/components/Layout/PageContent/PageContent.tsx +16 -0
- package/src/components/Layout/PageHeader/PageHeader.tsx +46 -0
- package/src/components/Navigation/DropDownMenu/DropDownButton.tsx +5 -5
- package/src/components/Navigation/Sidebar/Components.tsx +97 -0
- package/src/components/Navigation/Sidebar/MenuItem.tsx +76 -104
- package/src/components/Navigation/Sidebar/Sidebar.tsx +150 -55
- package/src/components/Navigation/Sidebar/SubMenuItem.tsx +34 -0
- package/src/components/Navigation/Sidebar/interfaces.ts +35 -12
- package/src/components/Navigation/Sidebar/styles.tsx +2 -2
- package/src/components/Navigation/exports.ts +2 -0
- package/src/components/export.ts +1 -1
- package/src/stories/DataDisplay/AccordionGroup.stories.tsx +131 -0
- package/src/stories/DataDisplay/Chips.stories.tsx +77 -0
- package/src/stories/Input/DatePicker.stories.tsx +138 -0
- package/src/stories/Input/IconButtons.stories.tsx +30 -0
- package/src/stories/Input/{Chips.stories.tsx → Tags.stories.tsx} +17 -17
- package/src/stories/Input/TimePicker.stories.tsx +123 -0
- package/src/themes/commonTheme.ts +171 -155
- package/src/components/DataDisplay/Accordion/utils/StandardImageList.tsx +0 -70
- package/src/components/Navigation/Sidebar/DropdownItem.tsx +0 -34
- package/src/stories/DataDisplay/Accordion.stories.tsx +0 -62
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Box, Stack } from "@mui/material";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { Icons, Tooltip, Typography } from "../../export";
|
|
4
|
+
import {
|
|
5
|
+
DefaultButtonProps,
|
|
6
|
+
InternalMenuButtonProps,
|
|
7
|
+
SubMenuButtonProps,
|
|
8
|
+
TooltipIconProps,
|
|
9
|
+
} from "./interfaces";
|
|
10
|
+
import { createSidebarStyles } from "./styles";
|
|
11
|
+
|
|
12
|
+
export const TooltipIcon = ({ name, icon }: TooltipIconProps) => {
|
|
13
|
+
return (
|
|
14
|
+
<Tooltip title={<Typography variant="label2">{name}</Typography>}>
|
|
15
|
+
{icon}
|
|
16
|
+
</Tooltip>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const DefaultButton = ({
|
|
21
|
+
name,
|
|
22
|
+
icon,
|
|
23
|
+
collapsed,
|
|
24
|
+
}: DefaultButtonProps) => {
|
|
25
|
+
const { StyledListItemButton, StyledListItemIcon } = useMemo(
|
|
26
|
+
() => createSidebarStyles(collapsed),
|
|
27
|
+
[collapsed]
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<StyledListItemButton collapsed={collapsed}>
|
|
32
|
+
<StyledListItemIcon collapsed={collapsed}>{icon}</StyledListItemIcon>
|
|
33
|
+
<Typography variant="button1">{name}</Typography>
|
|
34
|
+
</StyledListItemButton>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const InternalMenuButton = ({
|
|
39
|
+
name,
|
|
40
|
+
icon,
|
|
41
|
+
collapsed,
|
|
42
|
+
}: InternalMenuButtonProps) => {
|
|
43
|
+
const { StyledListItemButton, StyledListItemIcon, HoverIcon } = useMemo(
|
|
44
|
+
() => createSidebarStyles(collapsed),
|
|
45
|
+
[collapsed]
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<StyledListItemButton collapsed={collapsed}>
|
|
50
|
+
<Stack
|
|
51
|
+
width={"100%"}
|
|
52
|
+
direction="row"
|
|
53
|
+
alignItems={"center"}
|
|
54
|
+
justifyContent={"space-between"}
|
|
55
|
+
>
|
|
56
|
+
<Stack direction="row" alignItems={"center"}>
|
|
57
|
+
<StyledListItemIcon collapsed={collapsed}>{icon}</StyledListItemIcon>
|
|
58
|
+
<Typography variant="button1">{name}</Typography>
|
|
59
|
+
</Stack>
|
|
60
|
+
<HoverIcon display={"flex"} className="hoverIcon">
|
|
61
|
+
<Icons.RedoIcon size={18} />
|
|
62
|
+
</HoverIcon>
|
|
63
|
+
</Stack>
|
|
64
|
+
</StyledListItemButton>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const SubMenuButton = ({
|
|
69
|
+
name,
|
|
70
|
+
icon,
|
|
71
|
+
expanded,
|
|
72
|
+
collapsed,
|
|
73
|
+
}: SubMenuButtonProps) => {
|
|
74
|
+
const { StyledListItemButton, StyledListItemIcon } = useMemo(
|
|
75
|
+
() => createSidebarStyles(collapsed),
|
|
76
|
+
[collapsed]
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<StyledListItemButton collapsed={collapsed}>
|
|
81
|
+
<Stack
|
|
82
|
+
width={"100%"}
|
|
83
|
+
direction="row"
|
|
84
|
+
alignItems={"center"}
|
|
85
|
+
justifyContent={"space-between"}
|
|
86
|
+
>
|
|
87
|
+
<Stack direction="row" alignItems={"center"}>
|
|
88
|
+
<StyledListItemIcon collapsed={collapsed}>{icon}</StyledListItemIcon>
|
|
89
|
+
<Typography variant="button1">{name}</Typography>
|
|
90
|
+
</Stack>
|
|
91
|
+
<Box display={"flex"}>
|
|
92
|
+
{expanded ? <Icons.CollapseIcon /> : <Icons.ExpandIcon />}
|
|
93
|
+
</Box>
|
|
94
|
+
</Stack>
|
|
95
|
+
</StyledListItemButton>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
@@ -1,104 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { motion } from
|
|
3
|
-
import { useState } from
|
|
4
|
-
import { useMatch, useResolvedPath } from
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { Stack } from '@mui/material';
|
|
2
|
+
import { motion } from 'framer-motion';
|
|
3
|
+
import { useMemo, useState } from 'react';
|
|
4
|
+
import { useMatch, useResolvedPath } from 'react-router-dom';
|
|
5
|
+
import { SideMenuItemProps } from '../exports';
|
|
6
|
+
import {
|
|
7
|
+
DefaultButton,
|
|
8
|
+
InternalMenuButton,
|
|
9
|
+
SubMenuButton,
|
|
10
|
+
TooltipIcon,
|
|
11
|
+
} from './Components';
|
|
12
|
+
import { InternalMenuClickHandlerProps } from './interfaces';
|
|
13
|
+
import { createSidebarStyles } from './styles';
|
|
14
|
+
import { SidebarSubMenuItem } from './SubMenuItem';
|
|
9
15
|
|
|
10
16
|
export const SideBarMenuItem = ({
|
|
11
|
-
menuItem,
|
|
12
17
|
index,
|
|
13
18
|
collapsed,
|
|
14
|
-
|
|
19
|
+
menuItem,
|
|
20
|
+
currentMenuPath,
|
|
21
|
+
internalMenuClickHandler,
|
|
15
22
|
}: {
|
|
16
|
-
menuItem: MenuItemProps;
|
|
17
23
|
index: number;
|
|
18
24
|
collapsed: boolean;
|
|
19
|
-
|
|
25
|
+
currentMenuPath: string | null;
|
|
26
|
+
menuItem: SideMenuItemProps;
|
|
27
|
+
internalMenuClickHandler: (params: InternalMenuClickHandlerProps) => void;
|
|
20
28
|
}) => {
|
|
21
|
-
const {
|
|
22
|
-
StyledListItem,
|
|
23
|
-
StyledLinkButton,
|
|
24
|
-
StyledListItemButton,
|
|
25
|
-
StyledListItemIcon,
|
|
26
|
-
StyledDropdownButton,
|
|
27
|
-
HoverIcon,
|
|
28
|
-
} = createSidebarStyles(collapsed);
|
|
29
|
+
const { name, path, icon: Icon, menu: internalMenu, subMenu } = menuItem;
|
|
29
30
|
|
|
30
|
-
const
|
|
31
|
+
const newPath = currentMenuPath ? `${currentMenuPath}${path}` : path;
|
|
31
32
|
|
|
32
|
-
let resolved = useResolvedPath(
|
|
33
|
+
let resolved = useResolvedPath(newPath);
|
|
33
34
|
let match = useMatch({ path: resolved.pathname, end: false });
|
|
34
35
|
|
|
35
36
|
let [expanded, setExpanded] = useState(false);
|
|
36
|
-
const
|
|
37
|
+
const subMenuButtonClickHandler = () => {
|
|
37
38
|
setExpanded(!expanded);
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
</Tooltip>
|
|
45
|
-
);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const NewMenuTile = () => {
|
|
49
|
-
return (
|
|
50
|
-
<StyledListItemButton collapsed={collapsed}>
|
|
51
|
-
<Stack
|
|
52
|
-
width={"100%"}
|
|
53
|
-
direction="row"
|
|
54
|
-
alignItems={"center"}
|
|
55
|
-
justifyContent={"space-between"}
|
|
56
|
-
>
|
|
57
|
-
<Stack direction="row" alignItems={"center"}>
|
|
58
|
-
<StyledListItemIcon collapsed={collapsed}>
|
|
59
|
-
{Icon ? Icon : <Icons.HomeIcon />}
|
|
60
|
-
</StyledListItemIcon>
|
|
61
|
-
<Typography variant="button1">{name}</Typography>
|
|
62
|
-
</Stack>
|
|
63
|
-
<HoverIcon display={"flex"} className="hoverIcon">
|
|
64
|
-
<Icons.RedoIcon size={18} />
|
|
65
|
-
</HoverIcon>
|
|
66
|
-
</Stack>
|
|
67
|
-
</StyledListItemButton>
|
|
68
|
-
);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const DropdownMenuTile = () => {
|
|
72
|
-
return (
|
|
73
|
-
<StyledListItemButton collapsed={collapsed}>
|
|
74
|
-
<Stack
|
|
75
|
-
width={"100%"}
|
|
76
|
-
direction="row"
|
|
77
|
-
alignItems={"center"}
|
|
78
|
-
justifyContent={"space-between"}
|
|
79
|
-
>
|
|
80
|
-
<Stack direction="row" alignItems={"center"}>
|
|
81
|
-
<StyledListItemIcon collapsed={collapsed}>
|
|
82
|
-
{Icon ? Icon : <Icons.HomeIcon />}
|
|
83
|
-
</StyledListItemIcon>
|
|
84
|
-
<Typography variant="button1">{name}</Typography>
|
|
85
|
-
</Stack>
|
|
86
|
-
<Box display={"flex"}>
|
|
87
|
-
{expanded ? <Icons.CollapseIcon /> : <Icons.ExpandIcon />}
|
|
88
|
-
</Box>
|
|
89
|
-
</Stack>
|
|
90
|
-
</StyledListItemButton>
|
|
91
|
-
);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const DefaultTile = () => {
|
|
95
|
-
return (
|
|
96
|
-
<StyledListItemButton collapsed={collapsed}>
|
|
97
|
-
<StyledListItemIcon collapsed={collapsed}>{Icon}</StyledListItemIcon>
|
|
98
|
-
<Typography variant="button1">{name}</Typography>
|
|
99
|
-
</StyledListItemButton>
|
|
100
|
-
);
|
|
101
|
-
};
|
|
41
|
+
const { StyledListItem, StyledLinkButton, StyledSubMenuButton } = useMemo(
|
|
42
|
+
() => createSidebarStyles(collapsed),
|
|
43
|
+
[collapsed],
|
|
44
|
+
);
|
|
102
45
|
|
|
103
46
|
return (
|
|
104
47
|
<motion.div
|
|
@@ -107,41 +50,70 @@ export const SideBarMenuItem = ({
|
|
|
107
50
|
animate={{ opacity: 1 }}
|
|
108
51
|
transition={{ duration: 1 }}
|
|
109
52
|
>
|
|
110
|
-
{
|
|
53
|
+
{internalMenu && internalMenu.length > 0 && (
|
|
111
54
|
<StyledListItem key={index} disablePadding className="listItem">
|
|
112
|
-
<
|
|
55
|
+
<StyledSubMenuButton
|
|
113
56
|
match={match}
|
|
114
|
-
onClick={() =>
|
|
57
|
+
onClick={() =>
|
|
58
|
+
internalMenuClickHandler({
|
|
59
|
+
menuTitle: name,
|
|
60
|
+
menuPath: newPath,
|
|
61
|
+
internalMenu,
|
|
62
|
+
})
|
|
63
|
+
}
|
|
115
64
|
>
|
|
116
|
-
{collapsed ?
|
|
117
|
-
|
|
65
|
+
{collapsed ? (
|
|
66
|
+
<TooltipIcon name={name} icon={Icon} />
|
|
67
|
+
) : (
|
|
68
|
+
<InternalMenuButton
|
|
69
|
+
name={name}
|
|
70
|
+
icon={Icon}
|
|
71
|
+
collapsed={collapsed}
|
|
72
|
+
/>
|
|
73
|
+
)}
|
|
74
|
+
</StyledSubMenuButton>
|
|
118
75
|
</StyledListItem>
|
|
119
76
|
)}
|
|
120
|
-
{
|
|
77
|
+
{subMenu && subMenu.length > 0 && (
|
|
121
78
|
<StyledListItem key={index} disablePadding className="listItem">
|
|
122
|
-
<
|
|
79
|
+
<StyledSubMenuButton
|
|
123
80
|
match={match}
|
|
124
|
-
onClick={() =>
|
|
81
|
+
onClick={() => subMenuButtonClickHandler()}
|
|
125
82
|
>
|
|
126
|
-
{collapsed ?
|
|
127
|
-
|
|
83
|
+
{collapsed ? (
|
|
84
|
+
<TooltipIcon name={name} icon={Icon} />
|
|
85
|
+
) : (
|
|
86
|
+
<SubMenuButton
|
|
87
|
+
name={name}
|
|
88
|
+
icon={Icon}
|
|
89
|
+
expanded={expanded}
|
|
90
|
+
collapsed={collapsed}
|
|
91
|
+
/>
|
|
92
|
+
)}
|
|
93
|
+
</StyledSubMenuButton>
|
|
128
94
|
</StyledListItem>
|
|
129
95
|
)}
|
|
130
|
-
{expanded &&
|
|
96
|
+
{expanded && !collapsed && subMenu && subMenu.length > 0 && (
|
|
131
97
|
<Stack>
|
|
132
|
-
{
|
|
133
|
-
<
|
|
134
|
-
|
|
135
|
-
collapsed={collapsed}
|
|
98
|
+
{subMenu?.map((item: any, index: number) => (
|
|
99
|
+
<SidebarSubMenuItem
|
|
100
|
+
key={index}
|
|
136
101
|
index={index}
|
|
102
|
+
collapsed={collapsed}
|
|
103
|
+
subMenuItem={item}
|
|
104
|
+
subMenuButtonPath={newPath}
|
|
137
105
|
/>
|
|
138
106
|
))}
|
|
139
107
|
</Stack>
|
|
140
108
|
)}
|
|
141
|
-
{!
|
|
142
|
-
<StyledListItem key={
|
|
143
|
-
<StyledLinkButton to={
|
|
144
|
-
{collapsed ?
|
|
109
|
+
{!internalMenu && !subMenu && (
|
|
110
|
+
<StyledListItem key={index} disablePadding className="listItem">
|
|
111
|
+
<StyledLinkButton to={newPath} match={match}>
|
|
112
|
+
{collapsed ? (
|
|
113
|
+
<TooltipIcon name={name} icon={Icon} />
|
|
114
|
+
) : (
|
|
115
|
+
<DefaultButton name={name} icon={Icon} collapsed={collapsed} />
|
|
116
|
+
)}
|
|
145
117
|
</StyledLinkButton>
|
|
146
118
|
</StyledListItem>
|
|
147
119
|
)}
|
|
@@ -1,76 +1,162 @@
|
|
|
1
|
-
import { motion } from
|
|
2
|
-
import { useMemo, useState } from
|
|
3
|
-
import { CampxFullLogoIcon } from
|
|
4
|
-
import { CampxIcon } from
|
|
5
|
-
import { LeftIcon } from
|
|
6
|
-
import { RightIcon } from
|
|
7
|
-
import { Typography } from
|
|
8
|
-
import { Icons } from
|
|
9
|
-
import { SideBarMenuItem } from
|
|
10
|
-
import {
|
|
11
|
-
|
|
1
|
+
import { motion } from 'framer-motion';
|
|
2
|
+
import { ReactElement, useEffect, useMemo, useState } from 'react';
|
|
3
|
+
import { CampxFullLogoIcon } from '../../Assets/Icons/IconComponents/CampxFullLogoIcon';
|
|
4
|
+
import { CampxIcon } from '../../Assets/Icons/IconComponents/CampxIcon';
|
|
5
|
+
import { LeftIcon } from '../../Assets/Icons/IconComponents/LeftIcon';
|
|
6
|
+
import { RightIcon } from '../../Assets/Icons/IconComponents/RightIcon';
|
|
7
|
+
import { Typography } from '../../DataDisplay/Typography/Typography';
|
|
8
|
+
import { Icons } from '../../export';
|
|
9
|
+
import { SideBarMenuItem } from './MenuItem';
|
|
10
|
+
import {
|
|
11
|
+
GetActiveMenuProps,
|
|
12
|
+
InternalMenuClickHandlerProps,
|
|
13
|
+
MenuState,
|
|
14
|
+
} from './interfaces';
|
|
15
|
+
import { createSidebarStyles } from './styles';
|
|
12
16
|
|
|
13
17
|
export const Sidebar = ({
|
|
14
18
|
menu,
|
|
15
19
|
collapsed,
|
|
16
20
|
setCollapsed,
|
|
17
21
|
}: {
|
|
18
|
-
menu:
|
|
22
|
+
menu: SideMenuItemProps[];
|
|
19
23
|
collapsed: boolean;
|
|
20
24
|
setCollapsed: any;
|
|
21
25
|
}) => {
|
|
22
|
-
const [history, setHistory] = useState<MenuHistory[]>([]);
|
|
23
|
-
const [currentMenu, setCurrentMenu] = useState<MenuItemProps[] | null>(menu);
|
|
24
|
-
const [currentMenuTitle, setCurrentMenuTitle] = useState<string | null>(null);
|
|
25
26
|
const [menuPosition, setMenuPosition] = useState(0);
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const [history, setHistory] = useState<MenuState[]>([]);
|
|
29
|
+
const [currentMenuState, setCurrentMenuState] = useState<MenuState>({
|
|
30
|
+
menu: menu,
|
|
31
|
+
title: null,
|
|
32
|
+
path: null,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const toggleSidebar = () => {
|
|
36
|
+
setMenuPosition(0);
|
|
37
|
+
setCollapsed(!collapsed);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const internalMenuClickHandler = ({
|
|
41
|
+
menuTitle,
|
|
42
|
+
menuPath,
|
|
43
|
+
internalMenu,
|
|
44
|
+
}: InternalMenuClickHandlerProps) => {
|
|
45
|
+
if (menuTitle && menuPath && internalMenu) {
|
|
32
46
|
setHistory((prev) => [
|
|
33
47
|
...prev,
|
|
34
|
-
{
|
|
48
|
+
{
|
|
49
|
+
title: currentMenuState.title,
|
|
50
|
+
path: currentMenuState.path,
|
|
51
|
+
menu: currentMenuState.menu,
|
|
52
|
+
},
|
|
35
53
|
]);
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
setCurrentMenuState({
|
|
56
|
+
title: menuTitle,
|
|
57
|
+
path: menuPath,
|
|
58
|
+
menu: internalMenu,
|
|
59
|
+
});
|
|
60
|
+
|
|
38
61
|
setMenuPosition(collapsed ? 60 : 250);
|
|
39
|
-
setCurrentMenuTitle(newMenuTitle);
|
|
40
62
|
}
|
|
41
63
|
};
|
|
42
64
|
|
|
43
|
-
const
|
|
65
|
+
const previousMenuClickHandler = () => {
|
|
44
66
|
const prev = history && history.length > 0 && history.pop();
|
|
45
67
|
|
|
46
|
-
if (prev) {
|
|
47
|
-
|
|
48
|
-
|
|
68
|
+
if (prev && prev.menu) {
|
|
69
|
+
setCurrentMenuState({
|
|
70
|
+
menu: prev.menu,
|
|
71
|
+
title: prev.title,
|
|
72
|
+
path: prev.path,
|
|
73
|
+
});
|
|
49
74
|
setHistory([...history]);
|
|
50
75
|
setMenuPosition(collapsed ? -60 : -250);
|
|
51
76
|
}
|
|
52
77
|
};
|
|
53
78
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
79
|
+
const getActiveMenu = ({
|
|
80
|
+
menu,
|
|
81
|
+
pathArray,
|
|
82
|
+
previousMenuState,
|
|
83
|
+
}: GetActiveMenuProps): MenuState => {
|
|
84
|
+
setHistory((prevHistory) => [
|
|
85
|
+
...prevHistory,
|
|
86
|
+
{
|
|
87
|
+
title: previousMenuState?.title,
|
|
88
|
+
path: previousMenuState?.path,
|
|
89
|
+
menu: previousMenuState.menu,
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
|
|
93
|
+
const item = menu.find((item: any) => item.path === `/${pathArray[0]}`);
|
|
94
|
+
|
|
95
|
+
if (item) {
|
|
96
|
+
if (!item.menu) {
|
|
97
|
+
return previousMenuState;
|
|
98
|
+
} else if (pathArray.length > 1) {
|
|
99
|
+
return getActiveMenu({
|
|
100
|
+
menu: item.menu,
|
|
101
|
+
pathArray: pathArray.slice(1),
|
|
102
|
+
previousMenuState: {
|
|
103
|
+
title: item.name,
|
|
104
|
+
path: previousMenuState.path
|
|
105
|
+
? previousMenuState.path + item.path
|
|
106
|
+
: item.path,
|
|
107
|
+
menu: item.menu,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
return {
|
|
112
|
+
title: item.name,
|
|
113
|
+
path: previousMenuState.path
|
|
114
|
+
? previousMenuState.path + item.path
|
|
115
|
+
: item.path,
|
|
116
|
+
menu: item.menu,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
return previousMenuState;
|
|
121
|
+
}
|
|
57
122
|
};
|
|
58
123
|
|
|
124
|
+
useEffect(() => {
|
|
125
|
+
const currentPathArray = window.location.pathname.split('/');
|
|
126
|
+
|
|
127
|
+
if (currentPathArray.length > 2) {
|
|
128
|
+
currentPathArray.splice(0, 2);
|
|
129
|
+
currentPathArray.pop();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const activeMenu = getActiveMenu({
|
|
133
|
+
menu: currentMenuState.menu,
|
|
134
|
+
pathArray: currentPathArray,
|
|
135
|
+
previousMenuState: currentMenuState,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
setCurrentMenuState({
|
|
139
|
+
title: activeMenu?.title,
|
|
140
|
+
path: activeMenu.path,
|
|
141
|
+
menu: activeMenu?.menu,
|
|
142
|
+
});
|
|
143
|
+
}, []);
|
|
144
|
+
|
|
59
145
|
const {
|
|
60
146
|
StyledSidebarContainer,
|
|
61
147
|
StyledLogoArea,
|
|
62
148
|
StyledMenuBar,
|
|
63
149
|
StyledCollapsibleSection,
|
|
64
150
|
StyledMenuHeaderButton,
|
|
65
|
-
} = useMemo(() => createSidebarStyles(collapsed), [collapsed]);
|
|
151
|
+
} = useMemo(() => createSidebarStyles(collapsed), [collapsed, menuPosition]);
|
|
66
152
|
|
|
67
153
|
return (
|
|
68
154
|
<motion.div
|
|
69
|
-
animate={{ width: collapsed ?
|
|
70
|
-
transition={{ duration: 0.3, ease:
|
|
155
|
+
animate={{ width: collapsed ? '60px' : '250px' }}
|
|
156
|
+
transition={{ duration: 0.3, ease: 'circOut' }}
|
|
71
157
|
style={{
|
|
72
|
-
margin:
|
|
73
|
-
height:
|
|
158
|
+
margin: '12px',
|
|
159
|
+
height: 'calc(100vh - 24px)',
|
|
74
160
|
}}
|
|
75
161
|
>
|
|
76
162
|
<StyledSidebarContainer
|
|
@@ -78,48 +164,44 @@ export const Sidebar = ({
|
|
|
78
164
|
direction="column"
|
|
79
165
|
className="sidebarContainer"
|
|
80
166
|
>
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
animate={{ opacity: 1 }}
|
|
85
|
-
transition={{ duration: 0.5 }}
|
|
86
|
-
>
|
|
87
|
-
<StyledLogoArea collapsed={collapsed}>
|
|
88
|
-
{collapsed ? <CampxIcon size={32} /> : <CampxFullLogoIcon />}
|
|
89
|
-
</StyledLogoArea>
|
|
90
|
-
</motion.div>
|
|
167
|
+
<StyledLogoArea collapsed={collapsed}>
|
|
168
|
+
{collapsed ? <CampxIcon size={32} /> : <CampxFullLogoIcon />}
|
|
169
|
+
</StyledLogoArea>
|
|
91
170
|
|
|
92
171
|
<motion.div
|
|
93
172
|
initial={{ x: menuPosition }}
|
|
94
173
|
animate={{ x: 0 }}
|
|
95
174
|
transition={{
|
|
96
175
|
duration: 0.3,
|
|
97
|
-
ease: menuPosition ?
|
|
176
|
+
ease: menuPosition ? 'circOut' : 'circIn',
|
|
98
177
|
}}
|
|
99
178
|
style={{
|
|
100
|
-
height:
|
|
179
|
+
height: '100%',
|
|
101
180
|
}}
|
|
102
181
|
>
|
|
103
182
|
<StyledMenuBar>
|
|
104
|
-
{!collapsed &&
|
|
183
|
+
{!collapsed && currentMenuState.title && (
|
|
105
184
|
<StyledMenuHeaderButton
|
|
106
185
|
direction="row"
|
|
107
|
-
onClick={() =>
|
|
186
|
+
onClick={() => previousMenuClickHandler()}
|
|
108
187
|
>
|
|
109
188
|
<Icons.ArrowBackIcon size={20} />
|
|
110
189
|
|
|
111
|
-
<Typography variant="button1">
|
|
190
|
+
<Typography variant="button1">
|
|
191
|
+
{currentMenuState.title}
|
|
192
|
+
</Typography>
|
|
112
193
|
</StyledMenuHeaderButton>
|
|
113
194
|
)}
|
|
114
|
-
{
|
|
115
|
-
|
|
116
|
-
|
|
195
|
+
{currentMenuState.menu &&
|
|
196
|
+
currentMenuState.menu.length > 0 &&
|
|
197
|
+
currentMenuState.menu?.map((item: any, index: number) => (
|
|
117
198
|
<SideBarMenuItem
|
|
199
|
+
currentMenuPath={currentMenuState.path}
|
|
118
200
|
menuItem={item}
|
|
119
201
|
index={index}
|
|
120
202
|
key={index}
|
|
121
203
|
collapsed={collapsed}
|
|
122
|
-
|
|
204
|
+
internalMenuClickHandler={internalMenuClickHandler}
|
|
123
205
|
/>
|
|
124
206
|
))}
|
|
125
207
|
</StyledMenuBar>
|
|
@@ -135,4 +217,17 @@ export const Sidebar = ({
|
|
|
135
217
|
);
|
|
136
218
|
};
|
|
137
219
|
|
|
138
|
-
export
|
|
220
|
+
export interface SideMenuItemProps {
|
|
221
|
+
name: string;
|
|
222
|
+
path: string;
|
|
223
|
+
icon: ReactElement;
|
|
224
|
+
permissionKey?: string;
|
|
225
|
+
subMenu?: SubMenuItemProps[];
|
|
226
|
+
menu?: SideMenuItemProps[]; // internalMenu
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export interface SubMenuItemProps {
|
|
230
|
+
name: string;
|
|
231
|
+
path: string;
|
|
232
|
+
permissionKey?: string;
|
|
233
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useMatch, useResolvedPath } from 'react-router-dom';
|
|
2
|
+
import { SubMenuItemProps, Typography } from '../../export';
|
|
3
|
+
import { createSidebarStyles } from './styles';
|
|
4
|
+
|
|
5
|
+
export const SidebarSubMenuItem = ({
|
|
6
|
+
index,
|
|
7
|
+
collapsed,
|
|
8
|
+
subMenuItem,
|
|
9
|
+
subMenuButtonPath,
|
|
10
|
+
}: {
|
|
11
|
+
index: number;
|
|
12
|
+
collapsed: boolean;
|
|
13
|
+
subMenuItem: SubMenuItemProps;
|
|
14
|
+
subMenuButtonPath: string;
|
|
15
|
+
}) => {
|
|
16
|
+
const { name, path } = subMenuItem;
|
|
17
|
+
|
|
18
|
+
const newPath = `${subMenuButtonPath}${path}`;
|
|
19
|
+
|
|
20
|
+
let resolved = useResolvedPath(newPath);
|
|
21
|
+
let match = useMatch({ path: resolved.pathname, end: false });
|
|
22
|
+
|
|
23
|
+
const { StyledListItem, StyledLinkButton, StyledListItemButton } = createSidebarStyles(collapsed);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<StyledListItem key={index} disablePadding className="listItem">
|
|
27
|
+
<StyledLinkButton to={newPath} match={match}>
|
|
28
|
+
<StyledListItemButton collapsed={collapsed}>
|
|
29
|
+
<Typography variant="button1">{name}</Typography>
|
|
30
|
+
</StyledListItemButton>
|
|
31
|
+
</StyledLinkButton>
|
|
32
|
+
</StyledListItem>
|
|
33
|
+
);
|
|
34
|
+
};
|