@codezee/sixtify-brahma 0.2.2 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/shared-components/src/Actions/ConfigureAction.tsx +13 -0
- package/packages/shared-components/src/Actions/index.ts +2 -1
- package/packages/shared-components/src/AgGrid/ActionCell/ActionCell.tsx +3 -1
- package/packages/shared-components/src/AgGrid/AgGrid.tsx +7 -1
- package/packages/shared-components/src/Card/ProfileCard/ProfileCard.tsx +1 -1
- package/packages/shared-components/src/Card/ProfileCard/ProfileCardItem/ProfileCardBody.tsx +4 -4
- package/packages/shared-components/src/Card/ProfileCard/ProfileCardItem/ProfileCardHeader.tsx +1 -1
- package/packages/shared-components/src/Charts/PieChart.tsx +20 -8
- package/packages/shared-components/src/Charts/Skeleton.tsx +36 -0
- package/packages/shared-components/src/Drawer/Bullet.tsx +1 -1
- package/packages/shared-components/src/Drawer/CloseDrawer/CloseDrawerMenuItem.tsx +8 -1
- package/packages/shared-components/src/Drawer/CloseDrawer/CloseDrawerMenuItemList.tsx +11 -7
- package/packages/shared-components/src/Drawer/CloseDrawer/CloseDrawerSubMenuItemList.tsx +96 -97
- package/packages/shared-components/src/Drawer/CloseDrawer/Popper.tsx +3 -3
- package/packages/shared-components/src/Drawer/Drawer.tsx +1 -1
- package/packages/shared-components/src/Drawer/MenuItem.tsx +8 -2
- package/packages/shared-components/src/Drawer/OpenDrawer/OpenDrawerMenuItemList.tsx +162 -214
- package/packages/shared-components/src/FilterList/FilterListV2.tsx +24 -13
- package/packages/shared-components/src/FilterList/index.ts +2 -0
- package/packages/shared-components/src/FormFields/Autocomplete/Autocomplete.tsx +86 -4
- package/packages/shared-components/src/FormFields/DatePicker/DatePicker.tsx +14 -3
- package/packages/shared-components/src/FormFields/DatePicker/Skeleton.tsx +15 -8
- package/packages/shared-components/src/FormFields/DateTimePicker/DateTimePicker.tsx +9 -4
- package/packages/shared-components/src/FormFields/FileUpload/FileNames.tsx +32 -0
- package/packages/shared-components/src/FormFields/FileUpload/FileUpload.tsx +13 -53
- package/packages/shared-components/src/FormFields/FileUpload/index.ts +1 -0
- package/packages/shared-components/src/FormFields/ListItemButton/ListItemButton.tsx +16 -1
- package/packages/shared-components/src/FormFields/TextField/Skeleton.tsx +13 -8
- package/packages/shared-components/src/FormFields/TextField/TextField.tsx +2 -2
- package/packages/shared-components/src/FormFields/TimePicker/TimePicker.tsx +6 -0
- package/packages/shared-components/src/Indicator/Indicator.tsx +4 -3
- package/packages/shared-components/src/Layouts/FormGridLayout.tsx +27 -0
- package/packages/shared-components/src/Layouts/index.ts +2 -1
- package/packages/shared-components/src/Pagination/Pagination.tsx +42 -0
- package/packages/shared-components/src/Pagination/index.ts +1 -0
- package/packages/shared-components/src/Stepper/Stepper.tsx +1 -1
- package/packages/shared-components/src/Svgs/Drawer/SettingIcon.tsx +17 -37
- package/packages/shared-components/src/Svgs/Drawer/SvgBankConfig.tsx +36 -0
- package/packages/shared-components/src/Svgs/Drawer/SvgConfiguration.tsx +16 -0
- package/packages/shared-components/src/Svgs/Drawer/SvgPayroll.tsx +32 -0
- package/packages/shared-components/src/Svgs/Drawer/SvgsTransaction.tsx +72 -70
- package/packages/shared-components/src/Svgs/Drawer/index.ts +3 -0
- package/packages/shared-components/src/Svgs/ImportExcelSuccessIcon.tsx +54 -0
- package/packages/shared-components/src/Svgs/SvgConfigure.tsx +51 -0
- package/packages/shared-components/src/Svgs/SvgEmail.tsx +24 -0
- package/packages/shared-components/src/Svgs/SvgPhone.tsx +16 -0
- package/packages/shared-components/src/Svgs/SvgsHome.tsx +8 -6
- package/packages/shared-components/src/Svgs/SvgsIndicator.tsx +7 -3
- package/packages/shared-components/src/Svgs/index.ts +3 -1
- package/packages/shared-components/src/Timeline/TimelineTrackSegments.tsx +11 -2
- package/packages/shared-components/src/Tooltip/Tooltip.tsx +1 -1
- package/packages/shared-components/src/UserProfileMenu/UserProfileMenu.styled.tsx +3 -7
- package/packages/shared-components/src/UserProfileMenu/UserProfileMenu.tsx +76 -15
- package/packages/shared-components/src/index.ts +6 -5
- package/packages/shared-components/src/utils/colorVariant.ts +26 -6
- package/packages/shared-components/src/utils/date.ts +19 -5
- package/packages/shared-components/src/utils/index.ts +9 -11
- package/packages/shared-components/src/utils/theme/colorPalette.ts +2 -0
- package/packages/shared-components/src/utils/theme/theme.ts +8 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Box, List, useTheme } from "@mui/material";
|
|
4
4
|
import { isEmpty as _isEmpty } from "lodash";
|
|
5
|
-
import { useEffect, useState } from "react";
|
|
5
|
+
import { type HTMLAttributeAnchorTarget, useEffect, useState } from "react";
|
|
6
6
|
import { urlToNestedObject } from "../../utils/urlToNestedObject";
|
|
7
7
|
import type { MenuItem } from "../Drawer";
|
|
8
8
|
import { OpenDrawerCollapse } from "./OpenDrawerCollapse";
|
|
@@ -13,24 +13,164 @@ type OpenDrawerMenuItemListProps = {
|
|
|
13
13
|
currentPathname: string;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
export type NestedMenuState = {
|
|
17
|
+
[K in MenuItem["key"]]?:
|
|
18
|
+
| boolean
|
|
19
|
+
| {
|
|
20
|
+
[SubK in MenuItem["key"]]?: boolean | NestedMenuState;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type MenuItemRecursiveProps = {
|
|
25
|
+
menuItem: MenuItem;
|
|
26
|
+
level?: number;
|
|
27
|
+
parentPath?: string;
|
|
28
|
+
subMenusOpen: NestedMenuState;
|
|
29
|
+
setSubMenusOpen: (
|
|
30
|
+
value: NestedMenuState | ((prev: NestedMenuState) => NestedMenuState)
|
|
31
|
+
) => void;
|
|
32
|
+
currentPathMenuOpen: NestedMenuState;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const getNestedMenuState = (state: NestedMenuState, path: string[]) => {
|
|
36
|
+
if (path.length === 0) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (typeof state !== "object") {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
23
43
|
|
|
24
|
-
const
|
|
25
|
-
//TODO: jaydip, fix this type
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
-
Record<string, any>
|
|
28
|
-
>({});
|
|
44
|
+
const first = path[0];
|
|
29
45
|
|
|
46
|
+
if (!first) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const rest = path.slice(1);
|
|
51
|
+
|
|
52
|
+
const nextState = state[first];
|
|
53
|
+
|
|
54
|
+
if (rest.length === 0) {
|
|
55
|
+
return Boolean(nextState);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return getNestedMenuState(nextState as NestedMenuState, rest);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const isMenuOpen = (state: NestedMenuState, path: string[]) => {
|
|
62
|
+
const value = getNestedMenuState(state, path);
|
|
63
|
+
|
|
64
|
+
return Boolean(value);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const MenuItemRecursive = ({
|
|
68
|
+
menuItem,
|
|
69
|
+
level = 0,
|
|
70
|
+
parentPath = "",
|
|
71
|
+
subMenusOpen,
|
|
72
|
+
setSubMenusOpen,
|
|
73
|
+
currentPathMenuOpen,
|
|
74
|
+
}: MenuItemRecursiveProps) => {
|
|
30
75
|
const theme = useTheme();
|
|
31
76
|
|
|
77
|
+
if (level === 3) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
32
81
|
const { butterflyBlue, slate } = theme.palette.app.color;
|
|
33
82
|
|
|
83
|
+
const { key, icon, title, onClick, menuItems = [] } = menuItem;
|
|
84
|
+
|
|
85
|
+
const currentPath = parentPath ? `${parentPath}/${key}` : key;
|
|
86
|
+
|
|
87
|
+
const pathArray = currentPath.split("/");
|
|
88
|
+
|
|
89
|
+
const isMenuSelected = isMenuOpen(subMenusOpen, pathArray);
|
|
90
|
+
|
|
91
|
+
const dynamicPadding = level * 3 + 1.5;
|
|
92
|
+
|
|
93
|
+
const handleClick = (target?: HTMLAttributeAnchorTarget) => {
|
|
94
|
+
if (menuItems.length > 0) {
|
|
95
|
+
setSubMenusOpen((prev) => {
|
|
96
|
+
const newState = { ...prev };
|
|
97
|
+
|
|
98
|
+
let current = newState;
|
|
99
|
+
|
|
100
|
+
for (let i = 0; i < pathArray.length - 1; i++) {
|
|
101
|
+
const segment = pathArray[i];
|
|
102
|
+
|
|
103
|
+
if (!segment) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
current[segment] =
|
|
108
|
+
typeof current[segment] === "object" ? current[segment] : {};
|
|
109
|
+
current = current[segment] as NestedMenuState;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const lastSegment = pathArray[pathArray.length - 1];
|
|
113
|
+
|
|
114
|
+
if (lastSegment) {
|
|
115
|
+
current[lastSegment] = !isMenuSelected;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return newState;
|
|
119
|
+
});
|
|
120
|
+
} else if (onClick && !isMenuSelected) {
|
|
121
|
+
const path = key === "home" ? "/" : `/${currentPath}`;
|
|
122
|
+
|
|
123
|
+
onClick(path, target);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<Box key={key}>
|
|
129
|
+
<OpenDrawerMenuItem
|
|
130
|
+
sx={{
|
|
131
|
+
paddingLeft: dynamicPadding,
|
|
132
|
+
":focus-visible": {
|
|
133
|
+
border: `1px solid ${butterflyBlue[900]}`,
|
|
134
|
+
backgroundColor: slate[900],
|
|
135
|
+
},
|
|
136
|
+
}}
|
|
137
|
+
onClick={handleClick}
|
|
138
|
+
icon={level === 0 ? icon : undefined}
|
|
139
|
+
title={title}
|
|
140
|
+
isShowEndAdornment={menuItems.length > 0 && level < 2}
|
|
141
|
+
selected={isMenuSelected}
|
|
142
|
+
/>
|
|
143
|
+
|
|
144
|
+
{menuItems.length > 0 && (
|
|
145
|
+
<OpenDrawerCollapse in={isMenuSelected}>
|
|
146
|
+
<List component="div" disablePadding>
|
|
147
|
+
{menuItems.map((subMenuItem) => (
|
|
148
|
+
<MenuItemRecursive
|
|
149
|
+
key={subMenuItem.key}
|
|
150
|
+
menuItem={subMenuItem}
|
|
151
|
+
level={level + 1}
|
|
152
|
+
parentPath={currentPath}
|
|
153
|
+
subMenusOpen={subMenusOpen}
|
|
154
|
+
setSubMenusOpen={setSubMenusOpen}
|
|
155
|
+
currentPathMenuOpen={currentPathMenuOpen}
|
|
156
|
+
/>
|
|
157
|
+
))}
|
|
158
|
+
</List>
|
|
159
|
+
</OpenDrawerCollapse>
|
|
160
|
+
)}
|
|
161
|
+
</Box>
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const OpenDrawerMenuItemList = ({
|
|
166
|
+
menuItems,
|
|
167
|
+
currentPathname,
|
|
168
|
+
}: OpenDrawerMenuItemListProps) => {
|
|
169
|
+
const [subMenusOpen, setSubMenusOpen] = useState<NestedMenuState>({});
|
|
170
|
+
|
|
171
|
+
const [currentPathMenuOpen, setCurrentPathMenuOpen] =
|
|
172
|
+
useState<NestedMenuState>({});
|
|
173
|
+
|
|
34
174
|
useEffect(() => {
|
|
35
175
|
const obj = urlToNestedObject(currentPathname);
|
|
36
176
|
|
|
@@ -45,205 +185,13 @@ export const OpenDrawerMenuItemList = ({
|
|
|
45
185
|
setCurrentPathMenuOpen(obj);
|
|
46
186
|
}, [currentPathname]);
|
|
47
187
|
|
|
48
|
-
return menuItems.map((menuItem) =>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
sx={{
|
|
58
|
-
":focus-visible": {
|
|
59
|
-
border: `1px solid ${butterflyBlue[900]}`,
|
|
60
|
-
backgroundColor: slate[900],
|
|
61
|
-
},
|
|
62
|
-
}}
|
|
63
|
-
onClick={() => {
|
|
64
|
-
setSubMenusOpen((prev) => ({
|
|
65
|
-
...prev,
|
|
66
|
-
[key1]: !isMenuSelected,
|
|
67
|
-
}));
|
|
68
|
-
}}
|
|
69
|
-
icon={icon}
|
|
70
|
-
title={title}
|
|
71
|
-
isShowEndAdornment
|
|
72
|
-
selected={isMenuSelected}
|
|
73
|
-
key={key1}
|
|
74
|
-
/>
|
|
75
|
-
|
|
76
|
-
<OpenDrawerCollapse in={isMenuSelected}>
|
|
77
|
-
<List component="div" disablePadding key={key1}>
|
|
78
|
-
{menuItems.map(
|
|
79
|
-
({ key: key2, onClick, title, menuItems = [] }) => {
|
|
80
|
-
const isSubMenuSelected = menuItems.length
|
|
81
|
-
? !!subMenusOpen?.[key1]?.[key2] ||
|
|
82
|
-
!!currentPathMenuOpen?.[key1]?.[key2]?.menuItems
|
|
83
|
-
: !!subMenusOpen?.[key1]?.[key2] ||
|
|
84
|
-
!!currentPathMenuOpen?.[key1]?.[key2];
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<Box
|
|
88
|
-
sx={{
|
|
89
|
-
bgcolor:
|
|
90
|
-
isSubMenuSelected && menuItems.length === 0
|
|
91
|
-
? butterflyBlue[900]
|
|
92
|
-
: "",
|
|
93
|
-
}}
|
|
94
|
-
key={key2}
|
|
95
|
-
>
|
|
96
|
-
{menuItems.length > 0 ? (
|
|
97
|
-
<>
|
|
98
|
-
<OpenDrawerMenuItem
|
|
99
|
-
sx={{
|
|
100
|
-
paddingLeft: 4.5,
|
|
101
|
-
":focus-visible": {
|
|
102
|
-
border: `1px solid ${butterflyBlue[900]}`,
|
|
103
|
-
backgroundColor: slate[900],
|
|
104
|
-
},
|
|
105
|
-
}}
|
|
106
|
-
onClick={() => {
|
|
107
|
-
// eslint-disable-next-line sonarjs/no-nested-functions
|
|
108
|
-
setSubMenusOpen((prev) => ({
|
|
109
|
-
...prev,
|
|
110
|
-
[key1]: {
|
|
111
|
-
...(prev?.[key1] || {}),
|
|
112
|
-
[key2]: !isSubMenuSelected,
|
|
113
|
-
},
|
|
114
|
-
}));
|
|
115
|
-
}}
|
|
116
|
-
key={key2}
|
|
117
|
-
title={title}
|
|
118
|
-
isShowEndAdornment
|
|
119
|
-
selected={isSubMenuSelected}
|
|
120
|
-
/>
|
|
121
|
-
<OpenDrawerCollapse in={isSubMenuSelected}>
|
|
122
|
-
<List component="div" disablePadding key={key2}>
|
|
123
|
-
{menuItems.map(
|
|
124
|
-
({ key: key3, title, onClick }) => {
|
|
125
|
-
const menuSelectedItem =
|
|
126
|
-
!!subMenusOpen[key1]?.[key2]?.[key3] ||
|
|
127
|
-
!!currentPathMenuOpen[key1]?.[key2]?.[key3];
|
|
128
|
-
|
|
129
|
-
return (
|
|
130
|
-
<Box
|
|
131
|
-
sx={{
|
|
132
|
-
bgcolor: menuSelectedItem
|
|
133
|
-
? theme.palette.app.color
|
|
134
|
-
.butterflyBlue[900]
|
|
135
|
-
: "",
|
|
136
|
-
}}
|
|
137
|
-
key={key3}
|
|
138
|
-
>
|
|
139
|
-
<OpenDrawerMenuItem
|
|
140
|
-
sx={
|
|
141
|
-
menuSelectedItem
|
|
142
|
-
? {
|
|
143
|
-
paddingLeft: menuItems.length
|
|
144
|
-
? 7.5
|
|
145
|
-
: 4.5,
|
|
146
|
-
}
|
|
147
|
-
: {
|
|
148
|
-
paddingLeft: menuItems.length
|
|
149
|
-
? 7.5
|
|
150
|
-
: 4.5,
|
|
151
|
-
":focus-visible": {
|
|
152
|
-
border: `1px solid ${butterflyBlue[900]}`,
|
|
153
|
-
backgroundColor:
|
|
154
|
-
theme.palette.app.color
|
|
155
|
-
.slate[900],
|
|
156
|
-
},
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
// eslint-disable-next-line sonarjs/no-nested-functions
|
|
160
|
-
onClick={(target) => {
|
|
161
|
-
if (onClick && !menuSelectedItem) {
|
|
162
|
-
onClick(
|
|
163
|
-
`/${key1}/${key2}/${key3}`,
|
|
164
|
-
target
|
|
165
|
-
);
|
|
166
|
-
setSubMenusOpen((prev) => ({
|
|
167
|
-
...prev,
|
|
168
|
-
[key2]: {
|
|
169
|
-
...(prev?.[key2] || {}),
|
|
170
|
-
[key3]: !menuSelectedItem,
|
|
171
|
-
},
|
|
172
|
-
}));
|
|
173
|
-
}
|
|
174
|
-
}}
|
|
175
|
-
key={key3}
|
|
176
|
-
title={title}
|
|
177
|
-
selected={menuSelectedItem}
|
|
178
|
-
/>
|
|
179
|
-
</Box>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
)}
|
|
183
|
-
</List>
|
|
184
|
-
</OpenDrawerCollapse>
|
|
185
|
-
</>
|
|
186
|
-
) : (
|
|
187
|
-
<OpenDrawerMenuItem
|
|
188
|
-
sx={
|
|
189
|
-
isSubMenuSelected
|
|
190
|
-
? { paddingLeft: 4.5 }
|
|
191
|
-
: {
|
|
192
|
-
paddingLeft: 4.5,
|
|
193
|
-
":focus-visible": {
|
|
194
|
-
border: `1px solid ${butterflyBlue[900]}`,
|
|
195
|
-
backgroundColor: slate[900],
|
|
196
|
-
},
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
onClick={(target) => {
|
|
200
|
-
if (onClick && !isSubMenuSelected) {
|
|
201
|
-
onClick(`/${key1}/${key2}`, target);
|
|
202
|
-
}
|
|
203
|
-
}}
|
|
204
|
-
key={key2}
|
|
205
|
-
title={title}
|
|
206
|
-
selected={isSubMenuSelected}
|
|
207
|
-
/>
|
|
208
|
-
)}
|
|
209
|
-
</Box>
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
)}
|
|
213
|
-
</List>
|
|
214
|
-
</OpenDrawerCollapse>
|
|
215
|
-
</Box>
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
return (
|
|
220
|
-
<OpenDrawerMenuItem
|
|
221
|
-
sx={
|
|
222
|
-
isMenuSelected
|
|
223
|
-
? {}
|
|
224
|
-
: {
|
|
225
|
-
":focus-within": {
|
|
226
|
-
border: `1px solid ${butterflyBlue[900]}`,
|
|
227
|
-
backgroundColor: slate[900],
|
|
228
|
-
},
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
onClick={(target) => {
|
|
232
|
-
if (onClick && !isMenuSelected) {
|
|
233
|
-
if (key1 === "home") {
|
|
234
|
-
onClick("/", target);
|
|
235
|
-
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
onClick(`/${key1}`, target);
|
|
240
|
-
}
|
|
241
|
-
}}
|
|
242
|
-
key={key1}
|
|
243
|
-
icon={icon}
|
|
244
|
-
selected={isMenuSelected}
|
|
245
|
-
title={title}
|
|
246
|
-
/>
|
|
247
|
-
);
|
|
248
|
-
});
|
|
188
|
+
return menuItems.map((menuItem) => (
|
|
189
|
+
<MenuItemRecursive
|
|
190
|
+
key={menuItem.key}
|
|
191
|
+
menuItem={menuItem}
|
|
192
|
+
subMenusOpen={subMenusOpen}
|
|
193
|
+
setSubMenusOpen={setSubMenusOpen}
|
|
194
|
+
currentPathMenuOpen={currentPathMenuOpen}
|
|
195
|
+
/>
|
|
196
|
+
));
|
|
249
197
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ExpandMore } from "@mui/icons-material";
|
|
2
2
|
import {
|
|
3
3
|
Accordion,
|
|
4
4
|
AccordionDetails,
|
|
@@ -11,23 +11,25 @@ import {
|
|
|
11
11
|
Typography,
|
|
12
12
|
useTheme,
|
|
13
13
|
} from "@mui/material";
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} from "./FilterPopupWrapper";
|
|
14
|
+
import { ClearIcon } from "@mui/x-date-pickers/icons";
|
|
15
|
+
import { isEmpty } from "lodash";
|
|
16
|
+
import { DateTime } from "luxon";
|
|
17
|
+
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
19
18
|
import type { FieldValues } from "react-hook-form";
|
|
20
19
|
import { useForm, useWatch } from "react-hook-form";
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
20
|
+
import { Button } from "../Button";
|
|
21
|
+
import { FilterPill } from "../Chips/FilterPill";
|
|
22
|
+
import { dateFormats } from "../FormFields";
|
|
23
23
|
import { Switch } from "../FormFields/Switch";
|
|
24
24
|
import { PadBox } from "../PadBox";
|
|
25
|
-
import {
|
|
26
|
-
import { ClearIcon } from "@mui/x-date-pickers/icons";
|
|
25
|
+
import { SvgFilterList } from "../Svgs/SvgFilterList";
|
|
27
26
|
import { Tooltip } from "../Tooltip";
|
|
28
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
FilterPopupWrapper,
|
|
29
|
+
GetFilterPopupComponent,
|
|
30
|
+
} from "./FilterPopupWrapper";
|
|
31
|
+
import type { FilterListType } from "./FilterTypeWrapper";
|
|
29
32
|
import { getFormValue } from "./getFormData";
|
|
30
|
-
import { isEmpty } from "lodash";
|
|
31
33
|
|
|
32
34
|
export type FilterListV2Props = {
|
|
33
35
|
filterListItems: FilterListType[];
|
|
@@ -37,6 +39,7 @@ export type FilterListV2Props = {
|
|
|
37
39
|
onChange: (data: FieldValues, isPopup: boolean) => void;
|
|
38
40
|
onClear: () => void;
|
|
39
41
|
resetFormBasedOnFields?: string;
|
|
42
|
+
dateKeys?: string[];
|
|
40
43
|
};
|
|
41
44
|
export const FilterListV2 = ({
|
|
42
45
|
filterListItems,
|
|
@@ -45,6 +48,7 @@ export const FilterListV2 = ({
|
|
|
45
48
|
onApply,
|
|
46
49
|
onClear,
|
|
47
50
|
onChange,
|
|
51
|
+
dateKeys,
|
|
48
52
|
}: FilterListV2Props) => {
|
|
49
53
|
const theme = useTheme();
|
|
50
54
|
|
|
@@ -170,7 +174,14 @@ export const FilterListV2 = ({
|
|
|
170
174
|
|
|
171
175
|
const item = getFilterItem(key);
|
|
172
176
|
|
|
173
|
-
const keyValue =
|
|
177
|
+
const keyValue =
|
|
178
|
+
item &&
|
|
179
|
+
getFormValue(
|
|
180
|
+
dateKeys?.includes(item?.key)
|
|
181
|
+
? DateTime.fromISO(value).toFormat(dateFormats.dateWithEuropean)
|
|
182
|
+
: value,
|
|
183
|
+
item
|
|
184
|
+
);
|
|
174
185
|
|
|
175
186
|
if (!keyValue) {
|
|
176
187
|
return;
|
|
@@ -16,18 +16,21 @@ import {
|
|
|
16
16
|
useTheme,
|
|
17
17
|
} from "@mui/material";
|
|
18
18
|
import { styled } from "@mui/material/styles";
|
|
19
|
-
import { useMemo, useRef, type KeyboardEvent } from "react";
|
|
19
|
+
import { useMemo, useRef, useState, type KeyboardEvent } from "react";
|
|
20
20
|
import {
|
|
21
|
+
useController,
|
|
21
22
|
type ControllerRenderProps,
|
|
22
23
|
type FieldValues,
|
|
23
24
|
type UseControllerProps,
|
|
24
|
-
useController,
|
|
25
25
|
} from "react-hook-form";
|
|
26
|
+
import { useTranslation } from "react-i18next";
|
|
26
27
|
import { EditAction } from "../../Actions";
|
|
27
|
-
import {
|
|
28
|
+
import { toasts } from "../../Toast";
|
|
28
29
|
import { BoxStyled, CheckStyled } from "../CheckBox/CheckBox.styled";
|
|
30
|
+
import { Skeleton } from "./Skeleton";
|
|
29
31
|
|
|
30
32
|
export type Option = {
|
|
33
|
+
heading?: string;
|
|
31
34
|
label: string;
|
|
32
35
|
value: string | number;
|
|
33
36
|
disabled?: boolean;
|
|
@@ -41,6 +44,7 @@ export type AutocompleteProps<P extends FieldValues> = UseControllerProps<P> &
|
|
|
41
44
|
Omit<
|
|
42
45
|
MuiAutocompleteProps<
|
|
43
46
|
{
|
|
47
|
+
heading?: string;
|
|
44
48
|
label: string;
|
|
45
49
|
value: string | number;
|
|
46
50
|
disabled?: boolean;
|
|
@@ -60,11 +64,14 @@ export type AutocompleteProps<P extends FieldValues> = UseControllerProps<P> &
|
|
|
60
64
|
label?: string;
|
|
61
65
|
helperText?: string;
|
|
62
66
|
error?: boolean;
|
|
67
|
+
withLabel?: boolean;
|
|
63
68
|
placeholder?: string;
|
|
64
69
|
isShowAvatar?: boolean;
|
|
65
70
|
shouldCloseOnSelect?: boolean;
|
|
66
71
|
onAction?: () => void;
|
|
67
72
|
isShowSelectAll?: boolean;
|
|
73
|
+
isShowOptionsOnType?: boolean;
|
|
74
|
+
maxLimit?: number;
|
|
68
75
|
renderOption?: (
|
|
69
76
|
props: React.HTMLProps<HTMLLIElement>,
|
|
70
77
|
option: Option,
|
|
@@ -86,20 +93,27 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
86
93
|
loading = false,
|
|
87
94
|
helperText,
|
|
88
95
|
error,
|
|
96
|
+
withLabel = false,
|
|
89
97
|
placeholder = "",
|
|
90
98
|
freeSolo,
|
|
99
|
+
isShowOptionsOnType = false,
|
|
91
100
|
isShowSelectAll = true,
|
|
92
101
|
isShowAvatar = false,
|
|
93
102
|
shouldCloseOnSelect = false,
|
|
94
103
|
onAction,
|
|
95
104
|
renderOption,
|
|
96
105
|
getOptionLabel,
|
|
106
|
+
maxLimit,
|
|
97
107
|
...restProps
|
|
98
108
|
}: AutocompleteProps<P>) {
|
|
99
109
|
const {
|
|
100
110
|
field: { onChange, value, ...restField },
|
|
101
111
|
} = useController({ name, control, defaultValue, rules });
|
|
102
112
|
|
|
113
|
+
const { t } = useTranslation();
|
|
114
|
+
|
|
115
|
+
const [inputValue, setInputValue] = useState("");
|
|
116
|
+
|
|
103
117
|
const handleSelectAll = (isSelected: boolean) => {
|
|
104
118
|
if (isSelected) {
|
|
105
119
|
const allValues = options.map((option) => option.value);
|
|
@@ -130,6 +144,16 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
130
144
|
];
|
|
131
145
|
}, [multiple, isShowSelectAll, options]);
|
|
132
146
|
|
|
147
|
+
const filteredOptions = useMemo(() => {
|
|
148
|
+
if (inputValue.length < 3) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return options.filter((option) =>
|
|
153
|
+
option.label.toLowerCase().includes(inputValue.toLowerCase())
|
|
154
|
+
);
|
|
155
|
+
}, [inputValue]);
|
|
156
|
+
|
|
133
157
|
// eslint-disable-next-line sonarjs/function-return-type
|
|
134
158
|
const selectedValue = useMemo(() => {
|
|
135
159
|
if (multiple && freeSolo) {
|
|
@@ -140,6 +164,8 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
140
164
|
return selectedOption ? selectedOption.label : val.toString();
|
|
141
165
|
}) || []
|
|
142
166
|
);
|
|
167
|
+
} else if (withLabel) {
|
|
168
|
+
return options.find((option) => option.value === value?.value) ?? null;
|
|
143
169
|
} else if (multiple) {
|
|
144
170
|
return options.filter((option) => value?.includes(option.value));
|
|
145
171
|
} else if (!options.find((option) => option.value === value) && freeSolo) {
|
|
@@ -176,6 +202,19 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
176
202
|
},
|
|
177
203
|
}));
|
|
178
204
|
|
|
205
|
+
const GroupHeader = styled("div")(({ theme }) => ({
|
|
206
|
+
position: "sticky",
|
|
207
|
+
padding: "4px 10px",
|
|
208
|
+
fontSize: "16px",
|
|
209
|
+
fontWeight: 500,
|
|
210
|
+
color: theme.palette.app.color.butterflyBlue[900],
|
|
211
|
+
backgroundColor: theme.palette.app.color.butterflyBlue[500],
|
|
212
|
+
}));
|
|
213
|
+
|
|
214
|
+
const GroupItems = styled("ul")({
|
|
215
|
+
padding: 0,
|
|
216
|
+
});
|
|
217
|
+
|
|
179
218
|
if (loading) {
|
|
180
219
|
return <Skeleton label={label} />;
|
|
181
220
|
}
|
|
@@ -193,6 +232,14 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
193
232
|
}
|
|
194
233
|
|
|
195
234
|
if (selectedValue && Array.isArray(selectedValue)) {
|
|
235
|
+
if (maxLimit && selectedValue.length >= maxLimit) {
|
|
236
|
+
toasts.error({
|
|
237
|
+
title: t("common.autocomplete.limitExceed", { maxLimit }),
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
196
243
|
const valuesArray = selectedValue.map((item) => item.value);
|
|
197
244
|
|
|
198
245
|
if (valuesArray.includes(highlightedOptionRef.current)) {
|
|
@@ -339,15 +386,25 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
339
386
|
...params.InputProps,
|
|
340
387
|
startAdornment,
|
|
341
388
|
}}
|
|
389
|
+
onChange={(e) => {
|
|
390
|
+
if (isShowOptionsOnType) {
|
|
391
|
+
setInputValue(e.target.value);
|
|
392
|
+
}
|
|
393
|
+
}}
|
|
342
394
|
onKeyDown={(e) => handleKeyDown(e)}
|
|
343
395
|
/>
|
|
344
396
|
);
|
|
345
397
|
}}
|
|
346
398
|
multiple={multiple}
|
|
347
|
-
options={memoizedOptions}
|
|
399
|
+
options={isShowOptionsOnType ? filteredOptions : memoizedOptions}
|
|
348
400
|
isOptionEqualToValue={(option, value) =>
|
|
349
401
|
freeSolo ? false : option.value === value.value
|
|
350
402
|
}
|
|
403
|
+
onInputChange={(_, __, reason) => {
|
|
404
|
+
if (reason === "clear") {
|
|
405
|
+
setInputValue("");
|
|
406
|
+
}
|
|
407
|
+
}}
|
|
351
408
|
getOptionLabel={(option) => {
|
|
352
409
|
if (getOptionLabel) {
|
|
353
410
|
return getOptionLabel(option);
|
|
@@ -360,7 +417,25 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
360
417
|
return option.label;
|
|
361
418
|
}}
|
|
362
419
|
value={selectedValue}
|
|
420
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
363
421
|
onChange={(_, newValue) => {
|
|
422
|
+
if (withLabel) {
|
|
423
|
+
return onChange(newValue);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (
|
|
427
|
+
multiple &&
|
|
428
|
+
Array.isArray(newValue) &&
|
|
429
|
+
maxLimit &&
|
|
430
|
+
newValue.length > maxLimit
|
|
431
|
+
) {
|
|
432
|
+
toasts.error({
|
|
433
|
+
title: t("common.autocomplete.limitExceed", { maxLimit }),
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
|
|
364
439
|
if (multiple && isShowSelectAll && Array.isArray(newValue)) {
|
|
365
440
|
const isSelectAllIncluded = newValue.some(
|
|
366
441
|
(option) =>
|
|
@@ -406,6 +481,13 @@ export function Autocomplete<P extends FieldValues>({
|
|
|
406
481
|
|
|
407
482
|
onChange(newValue ? newValue.value : null);
|
|
408
483
|
}}
|
|
484
|
+
groupBy={(option) => option.heading ?? ""}
|
|
485
|
+
renderGroup={(params) => (
|
|
486
|
+
<li key={params.key}>
|
|
487
|
+
<GroupHeader>{params.group}</GroupHeader>
|
|
488
|
+
<GroupItems>{params.children}</GroupItems>
|
|
489
|
+
</li>
|
|
490
|
+
)}
|
|
409
491
|
getOptionDisabled={(option) => !!option.disabled}
|
|
410
492
|
/>
|
|
411
493
|
|