@campxdev/react-blueprint 1.7.2 → 1.7.4

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 (61) hide show
  1. package/export.ts +1 -0
  2. package/package.json +1 -1
  3. package/src/assets/export.ts +2 -0
  4. package/src/assets/fonts/export.ts +2 -0
  5. package/src/assets/images/export.ts +2 -0
  6. package/src/assets/images/gif/index.ts +1 -1
  7. package/src/assets/images/svg/index.ts +12 -12
  8. package/src/components/Assets/ErrorPages/InternalServerError.tsx +5 -5
  9. package/src/components/Assets/ErrorPages/NoInternetConnection.tsx +5 -5
  10. package/src/components/Assets/ErrorPages/NoItemFound.tsx +6 -5
  11. package/src/components/Assets/ErrorPages/PageNotFound.tsx +5 -5
  12. package/src/components/Assets/ErrorPages/UnAuthorized.tsx +5 -5
  13. package/src/components/Assets/ErrorPages/styles.tsx +1 -1
  14. package/src/components/Assets/Icons/IconComponents/CautionIcon.tsx +37 -0
  15. package/src/components/Assets/Icons/IconComponents/ClearIcon.tsx +37 -0
  16. package/src/components/Assets/Icons/IconComponents/DoneSquare.tsx +2 -2
  17. package/src/components/Assets/Icons/IconComponents/DownArrow.tsx +32 -0
  18. package/src/components/Assets/Icons/IconComponents/LIneDivider.tsx +23 -0
  19. package/src/components/Assets/Icons/IconComponents/PrintDesignerIcon.tsx +47 -0
  20. package/src/components/Assets/Icons/IconComponents/RedirectIcon.tsx +15 -7
  21. package/src/components/Assets/Icons/IconComponents/SettlementsIcon.tsx +53 -0
  22. package/src/components/Assets/Icons/Icons.tsx +12 -0
  23. package/src/components/DataDisplay/ActivityLogView/ActivityLogView.tsx +2 -2
  24. package/src/components/DataDisplay/ActivityLogView/service.tsx +1 -19
  25. package/src/components/DataDisplay/DataTable/DataTable.tsx +62 -39
  26. package/src/components/DataDisplay/DataTable/TablePagination.tsx +20 -12
  27. package/src/components/DataDisplay/EmptyIllustration/EmptyIllustration.tsx +40 -0
  28. package/src/components/DataDisplay/export.ts +1 -0
  29. package/src/components/Feedback/Alert/Alert.tsx +2 -3
  30. package/src/components/Feedback/Spinner/Spinner.css +13 -25
  31. package/src/components/Input/RadioGroup/RadioGroup.tsx +6 -2
  32. package/src/components/Input/SearchBar/SearchBar.tsx +17 -14
  33. package/src/components/Input/SingleSelect/SingleSelect.tsx +2 -1
  34. package/src/components/Input/SingleSelect/components/MenuFooter.tsx +24 -0
  35. package/src/components/Input/SingleSelect/components/OptionsLoader.tsx +14 -0
  36. package/src/components/Input/SingleSelect/components/SingleFilter.tsx +69 -62
  37. package/src/components/Input/SingleSelect/components/SingleInput.tsx +45 -18
  38. package/src/components/Input/TextField/TextField.tsx +4 -1
  39. package/src/components/Input/styles.tsx +5 -5
  40. package/src/components/Layout/PageContent/PageContent.tsx +4 -3
  41. package/src/components/Layout/PageHeader/PageHeader.tsx +22 -69
  42. package/src/components/Layout/PageHeader/components/SearchBar.tsx +69 -26
  43. package/src/components/Layout/PageHeader/components/TableColumnsSelector/TableColumnsSelector.tsx +125 -23
  44. package/src/components/Navigation/Breadcrumbs/Breadcrumbs.tsx +1 -0
  45. package/src/components/Navigation/ConfirmDialog/ConfirmDialog.tsx +3 -3
  46. package/src/components/Navigation/DropDownMenu/DropDownMenu.tsx +2 -2
  47. package/src/components/Navigation/PreviewFiles/PreviewFiles.tsx +56 -81
  48. package/src/components/Navigation/Sidebar/styles.tsx +2 -1
  49. package/src/components/Navigation/TabsContainer/TabsContainer.tsx +1 -1
  50. package/src/components/Navigation/UploadDialog/LoadingUploadDialogContainer.tsx +3 -3
  51. package/src/components/Navigation/UploadDialog/UploadDialog.tsx +46 -33
  52. package/src/components/Navigation/UploadDialog/UploadDialogContainer.tsx +2 -2
  53. package/src/redux/slices/pageHeaderSlice.ts +4 -1
  54. package/src/stories/Navigation/PreviewFiles.stories.tsx +43 -9
  55. package/src/themes/commonTheme.ts +30 -5
  56. package/src/themes/customCssBaseline.ts +3 -2
  57. package/src/components/DataDisplay/styles.tsx +0 -6
  58. package/src/components/Input/components/OptionsLoader.tsx +0 -22
  59. /package/src/assets/images/svg/{Emptylistmage.svg → empty.svg} +0 -0
  60. /package/src/assets/images/svg/{error-cactus.svg → error-image.svg} +0 -0
  61. /package/src/assets/images/svg/{Internalserverimage.svg → server-error.svg} +0 -0
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  AutocompleteCloseReason,
3
3
  Box,
4
+ InputAdornment,
4
5
  Autocomplete as MuiAutocomplete,
5
6
  Paper,
6
7
  } from '@mui/material';
7
8
  import { debounce, startCase } from 'lodash';
8
9
  import { SyntheticEvent, useMemo } from 'react';
9
10
  import { Typography } from '../../../DataDisplay/Typography/Typography';
10
- import { SingleSelectProps, Spinner } from '../../../export';
11
+ import { Icons, SingleSelectProps, Spinner } from '../../../export';
11
12
  import { TextField } from '../../TextField/TextField';
12
- import { OptionsLoader } from '../../components/OptionsLoader';
13
- import { OptionContainer } from '../../styles';
14
13
  import { SingleSelectState } from '../singleSelectReducer';
14
+ import { OptionsLoader } from './OptionsLoader';
15
15
 
16
16
  declare module '@mui/material/Autocomplete' {
17
17
  interface AutocompletePaperSlotPropsOverrides {
@@ -29,7 +29,7 @@ const CustomPaper = (props: any) => (
29
29
  }}
30
30
  >
31
31
  {props.children}
32
- <OptionsLoader loading={props.loadingOptions} isSearch={props.isSearch} />
32
+ {props.loadingOptions ? <OptionsLoader isSearch={props.isSearch} /> : <></>}
33
33
  </Paper>
34
34
  );
35
35
 
@@ -62,6 +62,7 @@ export const SingleInput = ({
62
62
  handleClose,
63
63
  handleScroll,
64
64
  state,
65
+ disableClear = false,
65
66
  ...restProps
66
67
  }: SingleInputProps) => {
67
68
  const {
@@ -98,15 +99,18 @@ export const SingleInput = ({
98
99
  />
99
100
  );
100
101
  }
102
+
101
103
  return (
102
104
  <MuiAutocomplete
103
105
  {...restProps}
106
+ disableClearable
107
+ forcePopupIcon={false}
104
108
  onChange={(e, value) => {
105
109
  onChange(getValue ? getValue(value) : value?.value);
106
110
  }}
107
111
  onInputCapture={handleSearch}
108
112
  open={open}
109
- autoFocus={true}
113
+ autoFocus={false}
110
114
  filterOptions={(options, state) => {
111
115
  if (optionsApiEndPoint) {
112
116
  return options;
@@ -119,19 +123,17 @@ export const SingleInput = ({
119
123
  PaperComponent={CustomPaper}
120
124
  renderOption={(props, option: any) => {
121
125
  return (
122
- <Box component="li" {...props} key={option.value}>
123
- <OptionContainer>
124
- <Typography variant="label1">
125
- {dbLabelProps.useLabelStartCase
126
- ? startCase(option.label)
127
- : option.label}
128
- </Typography>
129
- <Typography variant="caption">
130
- {dbLabelProps.useSubLabelStartCase
131
- ? startCase(option?.subLabel)
132
- : option?.subLabel}
133
- </Typography>
134
- </OptionContainer>
126
+ <Box component="li" {...props} margin="4px 0px" key={option.value}>
127
+ <Typography variant="subtitle3">
128
+ {dbLabelProps.useLabelStartCase
129
+ ? startCase(option.label)
130
+ : option.label}
131
+ </Typography>
132
+ <Typography variant="caption">
133
+ {dbLabelProps.useSubLabelStartCase
134
+ ? startCase(option?.subLabel)
135
+ : option?.subLabel}
136
+ </Typography>
135
137
  </Box>
136
138
  );
137
139
  }}
@@ -158,6 +160,31 @@ export const SingleInput = ({
158
160
  name={name}
159
161
  error={error}
160
162
  helperText={helperText}
163
+ fullWidth
164
+ slotProps={{
165
+ input: {
166
+ ...params.InputProps,
167
+ sx: {
168
+ paddingRight: '18px',
169
+ },
170
+ endAdornment: (
171
+ <InputAdornment position="end">
172
+ <Icons.DownArrow
173
+ disabled={params.disabled}
174
+ onClick={
175
+ params.disabled
176
+ ? () => {}
177
+ : open
178
+ ? (e) => {
179
+ handleClose(e, 'escape');
180
+ }
181
+ : handleOpen
182
+ }
183
+ />
184
+ </InputAdornment>
185
+ ),
186
+ },
187
+ }}
161
188
  />
162
189
  )}
163
190
  />
@@ -26,7 +26,10 @@ export const TextField = ({
26
26
  label={label}
27
27
  required={required}
28
28
  name={name}
29
- containerProps={containerProps}
29
+ containerProps={{
30
+ ...(rest.fullWidth && { width: '100%' }),
31
+ ...containerProps,
32
+ }}
30
33
  >
31
34
  <MuiTextField
32
35
  required={required}
@@ -1,14 +1,14 @@
1
1
  import { Box, Stack, styled } from '@mui/material';
2
2
 
3
- export const OptionContainer = styled(Box)(({ theme }) => ({
3
+ export const FilterOptionContainer = styled(Box)(({ theme }) => ({
4
4
  display: 'flex',
5
5
  flexDirection: 'column',
6
6
  borderBottom: `1px solid ${theme.palette.secondary.main}`,
7
7
  width: '100%',
8
- padding: '4px 0px',
9
8
  }));
10
9
 
11
- export const FetchingOptionsLoaderContainer = styled(Stack)(({ theme }) => ({
12
- backgroundColor: theme.palette.background.default,
13
- maxHeight: '32px',
10
+ export const FooterContainer = styled(Stack)(({ theme }) => ({
11
+ backgroundColor: theme.palette.surface.defaultBackground,
12
+ borderRadius: '4px',
13
+ height: '40px',
14
14
  }));
@@ -4,8 +4,7 @@ const PageContentContainer = styled(Box)(({ theme }) => ({
4
4
  display: 'flex',
5
5
  flexDirection: 'column',
6
6
  overflowY: 'auto',
7
- padding: '16px',
8
- gap: '16px',
7
+ padding: '12px',
9
8
  backgroundColor: theme.palette.surface.paperBackground,
10
9
  height: 'calc(100vh - 148px)',
11
10
  width: '100%',
@@ -14,6 +13,8 @@ const PageContentContainer = styled(Box)(({ theme }) => ({
14
13
 
15
14
  export const PageContent = (props: BoxProps) => {
16
15
  return (
17
- <PageContentContainer {...props}>{props.children}</PageContentContainer>
16
+ <PageContentContainer gap="12px" {...props}>
17
+ {props.children}
18
+ </PageContentContainer>
18
19
  );
19
20
  };
@@ -1,6 +1,6 @@
1
1
  import { Box, Divider, Stack, useTheme } from '@mui/material';
2
2
  import { GridColDef } from '@mui/x-data-grid';
3
- import { AnimatePresence, motion } from 'framer-motion';
3
+ import { motion } from 'framer-motion';
4
4
  import {
5
5
  cloneElement,
6
6
  Fragment,
@@ -8,19 +8,16 @@ import {
8
8
  ReactNode,
9
9
  useState,
10
10
  } from 'react';
11
- import { useDispatch } from 'react-redux';
11
+ import { useDispatch, useSelector } from 'react-redux';
12
12
  import { setFilterByNameForUniqueId } from '../../../redux/slices/pageHeaderSlice';
13
+ import { RootState } from '../../../redux/store';
13
14
  import {
14
15
  DensitySelector,
15
16
  Icons,
16
17
  TableColumnsSelector,
17
18
  Typography,
18
19
  } from '../../export';
19
- import {
20
- ColumnsAnchor,
21
- FiltersAnchor,
22
- SearchAnchor,
23
- } from './components/Anchors';
20
+ import { FiltersAnchor } from './components/Anchors';
24
21
  import { SearchBar } from './components/SearchBar';
25
22
 
26
23
  interface PageHeaderProps {
@@ -36,7 +33,7 @@ const ViewTab = ({ title }: { title: string }) => {
36
33
  const theme = useTheme();
37
34
  return (
38
35
  <Stack>
39
- <Stack direction="row" gap={1} alignItems="center" padding="8px">
36
+ <Stack direction="row" gap={1} alignItems="center" padding="8px 0px">
40
37
  <Icons.ViewsIcon />
41
38
  <Typography variant="subtitle3">{title}</Typography>
42
39
  </Stack>
@@ -54,7 +51,7 @@ const ViewTab = ({ title }: { title: string }) => {
54
51
 
55
52
  const motionDivVariants = {
56
53
  collapsed: { height: '48px' },
57
- expanded: { height: '102px' },
54
+ expanded: { height: '108px' },
58
55
  };
59
56
 
60
57
  export const PageHeader = ({
@@ -66,7 +63,7 @@ export const PageHeader = ({
66
63
  searchText = 'Search',
67
64
  }: PageHeaderProps) => {
68
65
  const [expanded, setExpanded] = useState(false);
69
- const [expandedSearch, setExpandedSearch] = useState(false);
66
+
70
67
  const dispatch = useDispatch();
71
68
 
72
69
  const wrapProps = (element: ReactElement): ReactElement => {
@@ -89,13 +86,17 @@ export const PageHeader = ({
89
86
 
90
87
  const theme = useTheme();
91
88
 
92
- const handleSearchClick = () => {
93
- setExpandedSearch(true);
94
- };
89
+ const filters = useSelector((state: RootState) =>
90
+ uniqueId ? state.pageHeader[uniqueId]?.filters : undefined,
91
+ );
95
92
 
96
- const handleSearchBlur = () => {
97
- setExpandedSearch(false);
98
- };
93
+ const hasFilters =
94
+ !!filters &&
95
+ Object.entries(filters).some(([key, value]) => {
96
+ return (
97
+ !['search', 'limit', 'offset', 'skip'].includes(key) && value !== null
98
+ );
99
+ });
99
100
 
100
101
  const isTableMode = columns && uniqueId;
101
102
 
@@ -104,10 +105,8 @@ export const PageHeader = ({
104
105
  style={{
105
106
  display: 'flex',
106
107
  flexDirection: 'column',
107
- gap: '10px',
108
- margin: '8px 0px',
109
- padding: '0px 16px',
110
108
  height: '48px',
109
+ gap: '8px',
111
110
  }}
112
111
  variants={motionDivVariants}
113
112
  animate={expanded ? 'expanded' : 'collapsed'}
@@ -118,6 +117,7 @@ export const PageHeader = ({
118
117
  width="100%"
119
118
  alignItems="center"
120
119
  justifyContent="space-between"
120
+ height="48px"
121
121
  >
122
122
  {isTableMode ? <ViewTab title="Default View" /> : viewsSlot}
123
123
 
@@ -127,48 +127,14 @@ export const PageHeader = ({
127
127
  handleClick={() => {
128
128
  setExpanded(!expanded);
129
129
  }}
130
- showDot={false}
130
+ showDot={hasFilters}
131
131
  />
132
132
  )}
133
133
  {isTableMode && (
134
- <ColumnsAnchor
135
- handleClick={() => {
136
- setExpanded(!expanded);
137
- }}
138
- showDot={false}
139
- />
134
+ <TableColumnsSelector columns={columns} uniqueId={uniqueId} />
140
135
  )}
141
136
  {isTableMode && (
142
- <AnimatePresence mode="wait">
143
- {expandedSearch ? (
144
- <motion.div
145
- key="searchBar"
146
- initial={{ opacity: 0, x: -20, scale: 0.95 }}
147
- animate={{ opacity: 1, x: 0, scale: 1 }}
148
- exit={{ opacity: 0, x: 20, scale: 0.95 }}
149
- transition={{ duration: 0.3 }}
150
- >
151
- <SearchBar
152
- searchText={searchText}
153
- handleSearchBlur={handleSearchBlur}
154
- uniqueId={uniqueId}
155
- />
156
- </motion.div>
157
- ) : (
158
- <motion.div
159
- key="searchAnchor"
160
- initial={{ opacity: 0, x: 20, scale: 0.95 }}
161
- animate={{ opacity: 1, x: 0, scale: 1 }}
162
- exit={{ opacity: 0, x: -20, scale: 0.95 }}
163
- transition={{ duration: 0.3 }}
164
- >
165
- <SearchAnchor
166
- handleClick={handleSearchClick}
167
- showDot={false}
168
- />
169
- </motion.div>
170
- )}
171
- </AnimatePresence>
137
+ <SearchBar searchText={searchText} uniqueId={uniqueId} />
172
138
  )}
173
139
  {isTableMode && <DensitySelector uniqueId={uniqueId} />}
174
140
  {actions.map((action, index) => action)}
@@ -183,18 +149,6 @@ export const PageHeader = ({
183
149
  )}
184
150
  {expanded && (
185
151
  <Stack direction="row" width="100%" alignItems="center" gap={2}>
186
- {isTableMode && (
187
- <>
188
- <TableColumnsSelector columns={columns} uniqueId={uniqueId} />
189
- <Divider
190
- orientation="vertical"
191
- style={{
192
- height: '20px',
193
- background: theme.palette.border.primary,
194
- }}
195
- />
196
- </>
197
- )}
198
152
  {filterComponents.map((filter, index) => (
199
153
  <Fragment key={index}>
200
154
  {wrapProps(filter)}
@@ -209,7 +163,6 @@ export const PageHeader = ({
209
163
  )}
210
164
  </Fragment>
211
165
  ))}
212
- <Stack direction="row"></Stack>
213
166
  </Stack>
214
167
  )}
215
168
  </motion.div>
@@ -1,28 +1,34 @@
1
- import { InputAdornment } from '@mui/material';
1
+ import { InputAdornment, Stack } from '@mui/material';
2
+ import { AnimatePresence, motion } from 'framer-motion';
2
3
  import { debounce } from 'lodash';
3
- import React, { useMemo } from 'react';
4
+ import React, { useMemo, useState } from 'react';
4
5
  import { useDispatch, useSelector } from 'react-redux';
5
6
  import { setSearchForUniqueId } from '../../../../redux/slices/pageHeaderSlice';
6
7
  import { RootState } from '../../../../redux/store';
7
8
  import { Icons, TextField } from '../../../export';
9
+ import { SearchAnchor } from './Anchors';
8
10
 
9
11
  export const SearchBar = ({
10
- handleSearchBlur,
11
12
  uniqueId,
12
13
  searchText,
13
14
  }: {
14
- handleSearchBlur: () => void;
15
15
  uniqueId: string;
16
16
  searchText: string;
17
17
  }) => {
18
18
  const dispatch = useDispatch();
19
19
 
20
+ const [expandedSearch, setExpandedSearch] = useState(false);
21
+
22
+ const handleSearchClick = () => {
23
+ setExpandedSearch(true);
24
+ };
25
+
20
26
  const search = useSelector(
21
27
  (state: RootState) => state.pageHeader[uniqueId]?.filters?.search,
22
28
  );
23
29
 
24
30
  // Wrap onSearch in useCallback
25
- const onSearch = (value: string) => {
31
+ const onSearch = (value: string | null) => {
26
32
  dispatch(
27
33
  setSearchForUniqueId({
28
34
  uniqueId: uniqueId,
@@ -31,36 +37,73 @@ export const SearchBar = ({
31
37
  );
32
38
  };
33
39
 
34
- // Now we can memoize a debounced version of onSearch
35
40
  const debouncedSendRequest = useMemo(
36
41
  () => debounce(onSearch, 300),
37
42
  [onSearch],
38
43
  );
39
44
 
40
- // Pass the updated value to the debounced function in onChange
41
45
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
42
46
  debouncedSendRequest(e.target.value);
43
47
  };
44
48
 
49
+ const handleClearClick = (e: any) => {
50
+ onSearch(null);
51
+ setExpandedSearch(false);
52
+ };
53
+
45
54
  return (
46
- <TextField
47
- containerProps={{
48
- margin: '0px',
49
- width: '300px',
50
- }}
51
- size="small"
52
- placeholder={searchText}
53
- defaultValue={search || ''}
54
- onChange={handleChange}
55
- InputProps={{
56
- startAdornment: (
57
- <InputAdornment position="start">
58
- <Icons.SearchIcon />
59
- </InputAdornment>
60
- ),
61
- }}
62
- onBlur={handleSearchBlur}
63
- autoFocus
64
- />
55
+ <AnimatePresence mode="wait">
56
+ {expandedSearch ? (
57
+ <motion.div
58
+ key="searchBar"
59
+ initial={{ opacity: 0, x: -20, scale: 0.95 }}
60
+ animate={{ opacity: 1, x: 0, scale: 1 }}
61
+ exit={{ opacity: 0, x: 20, scale: 0.95 }}
62
+ transition={{ duration: 0.3 }}
63
+ >
64
+ <TextField
65
+ containerProps={{
66
+ margin: '0px',
67
+ width: '300px',
68
+ }}
69
+ sx={{
70
+ input: {
71
+ padding: '9px 9px 9px 4px',
72
+ },
73
+ }}
74
+ size="small"
75
+ placeholder={searchText}
76
+ defaultValue={search || ''}
77
+ onChange={handleChange}
78
+ InputProps={{
79
+ startAdornment: (
80
+ // <InputAdornment position="start">
81
+ <Stack direction="row" alignItems="center" gap="4px">
82
+ <Icons.SearchIcon />
83
+ <Icons.LineDividerIcon />
84
+ </Stack>
85
+ // </InputAdornment>
86
+ ),
87
+ endAdornment: (
88
+ <InputAdornment position="end">
89
+ <Icons.ClearIcon onClick={handleClearClick} />
90
+ </InputAdornment>
91
+ ),
92
+ }}
93
+ autoFocus
94
+ />
95
+ </motion.div>
96
+ ) : (
97
+ <motion.div
98
+ key="searchAnchor"
99
+ initial={{ opacity: 0, x: 20, scale: 0.95 }}
100
+ animate={{ opacity: 1, x: 0, scale: 1 }}
101
+ exit={{ opacity: 0, x: -20, scale: 0.95 }}
102
+ transition={{ duration: 0.3 }}
103
+ >
104
+ <SearchAnchor handleClick={handleSearchClick} showDot={false} />
105
+ </motion.div>
106
+ )}
107
+ </AnimatePresence>
65
108
  );
66
109
  };
@@ -1,12 +1,25 @@
1
- import { KeyboardArrowDown } from '@mui/icons-material';
2
- import { MenuListProps, MenuProps, Typography, useTheme } from '@mui/material';
1
+ import {
2
+ MenuListProps,
3
+ MenuProps,
4
+ Stack,
5
+ styled,
6
+ Typography,
7
+ useTheme,
8
+ } from '@mui/material';
3
9
  import { GridColDef, GridColumnVisibilityModel } from '@mui/x-data-grid';
4
10
  import { useState } from 'react';
5
11
  import { useDispatch, useSelector } from 'react-redux';
6
12
  import { setColumnVisibilityModelForUniqueId } from '../../../../../redux/slices/pageHeaderSlice';
7
13
  import { RootState } from '../../../../../redux/store';
8
- import { Button, Icons, SearchBar, SingleCheckBox } from '../../../../export';
14
+ import {
15
+ Button,
16
+ EmptyIllustration,
17
+ Icons,
18
+ SearchBar,
19
+ SingleCheckBox,
20
+ } from '../../../../export';
9
21
  import { DropdownMenu } from '../../../../Navigation/export';
22
+ import { ColumnsAnchor } from '../Anchors';
10
23
 
11
24
  export type TableColumnsSelectorProps = {
12
25
  columns: GridColDef[];
@@ -15,6 +28,37 @@ export type TableColumnsSelectorProps = {
15
28
  uniqueId: string;
16
29
  };
17
30
 
31
+ export const FooterContainerContainer = styled(Stack)(({ theme }) => ({
32
+ backgroundColor: theme.palette.surface.defaultBackground,
33
+ borderRadius: '4px',
34
+ height: '40px',
35
+ }));
36
+
37
+ export const TableColumnsSelectorMenuFooter = ({
38
+ onClick,
39
+ }: {
40
+ onClick: () => void;
41
+ }) => {
42
+ const theme = useTheme();
43
+ return (
44
+ <FooterContainerContainer direction="row" alignItems="center">
45
+ <Button
46
+ variant="text"
47
+ onClick={onClick}
48
+ sx={{
49
+ fontFamily: 'Heebo',
50
+ minWidth: '0px',
51
+ margin: '0px 16px',
52
+ }}
53
+ disableRipple
54
+ color={theme.palette.text.tertiary}
55
+ >
56
+ Reset
57
+ </Button>
58
+ </FooterContainerContainer>
59
+ );
60
+ };
61
+
18
62
  export const TableColumnsSelector = ({
19
63
  columns,
20
64
  uniqueId,
@@ -36,7 +80,7 @@ export const TableColumnsSelector = ({
36
80
  const theme = useTheme();
37
81
 
38
82
  const filteredOptions = columns.filter((option) =>
39
- option.field.toLowerCase().includes(search.toLowerCase()),
83
+ option.headerName?.toLowerCase().includes(search.toLowerCase()),
40
84
  );
41
85
 
42
86
  const handleCheckboxChange = (column: GridColDef, checked: boolean) => {
@@ -56,26 +100,16 @@ export const TableColumnsSelector = ({
56
100
  <DropdownMenu
57
101
  menuListProps={{
58
102
  sx: {
59
- padding: '12px',
103
+ padding: '0px',
60
104
  width: '250px',
61
105
  },
62
106
  ...props.menuListProps,
63
107
  }}
64
108
  anchor={({ open }: { open: (e: any) => void }) => (
65
- <Button
66
- onClick={open}
67
- sx={{
68
- gap: '1px',
69
- borderRadius: '20px',
70
- }}
71
- variant="contained"
72
- background={theme.palette.surface.grey}
73
- hoverBackground={theme.palette.surface.grey}
74
- color={theme.palette.text.primary}
75
- endIcon={<KeyboardArrowDown />}
76
- >
77
- Columns
78
- </Button>
109
+ <ColumnsAnchor
110
+ handleClick={open}
111
+ showDot={Object.values(columnVisibilityModel).includes(false)}
112
+ />
79
113
  )}
80
114
  menuProps={{
81
115
  ...props.menuProps,
@@ -99,9 +133,9 @@ export const TableColumnsSelector = ({
99
133
  />
100
134
  }
101
135
  menuListContainerSx={{
102
- margin: '10px 5px 0px 5px',
103
- gap: 1,
104
- maxHeight: '350px',
136
+ margin: '12px 12px 0px 12px',
137
+ height: '310px',
138
+ overflowY: 'scroll',
105
139
  }}
106
140
  menu={filteredOptions.map((item, index) => (
107
141
  <SingleCheckBox
@@ -111,7 +145,11 @@ export const TableColumnsSelector = ({
111
145
  sx: {
112
146
  display: 'flex',
113
147
  justifyContent: 'space-between',
114
- marginLeft: '0px',
148
+ margin: '0px',
149
+ width: '100%',
150
+ '.MuiFormControlLabel-label': {
151
+ width: '100%',
152
+ },
115
153
  },
116
154
  }}
117
155
  icon={<Icons.VisibilityIcon />}
@@ -134,6 +172,70 @@ export const TableColumnsSelector = ({
134
172
  }}
135
173
  />
136
174
  ))}
175
+ menuSlot={({ close }) => {
176
+ if (filteredOptions.length === 0)
177
+ return (
178
+ <EmptyIllustration
179
+ message="No Options Found"
180
+ imageSize="100px"
181
+ containerProps={{
182
+ height: '310px',
183
+ }}
184
+ />
185
+ );
186
+ return filteredOptions.map((item, index) => (
187
+ <SingleCheckBox
188
+ key={index}
189
+ formControlLabelProps={{
190
+ labelPlacement: 'start',
191
+ sx: {
192
+ display: 'flex',
193
+ justifyContent: 'space-between',
194
+ margin: '0px',
195
+ width: '100%',
196
+ '.MuiFormControlLabel-label': {
197
+ width: '100%',
198
+ },
199
+ borderBottom: `1px solid ${theme.palette.secondary.main}`,
200
+ },
201
+ }}
202
+ icon={<Icons.VisibilityIcon />}
203
+ checkedIcon={<Icons.VisibilityOffIcon />}
204
+ checked={!columnVisibilityModel[item.field]}
205
+ label={
206
+ <Typography
207
+ color={
208
+ !columnVisibilityModel[item.field]
209
+ ? theme.palette.text.tertiary
210
+ : theme.palette.text.primary
211
+ }
212
+ variant="subtitle3"
213
+ >
214
+ {item.headerName}
215
+ </Typography>
216
+ }
217
+ onChange={(e) => {
218
+ handleCheckboxChange(item, e.target.checked);
219
+ }}
220
+ />
221
+ ));
222
+ }}
223
+ useMenuSlot
224
+ menuFooter={
225
+ <TableColumnsSelectorMenuFooter
226
+ onClick={() => {
227
+ dispatch(
228
+ setColumnVisibilityModelForUniqueId({
229
+ uniqueId: uniqueId,
230
+ columnVisibilityModel: columns.reduce((acc, column) => {
231
+ acc[column.field] = true;
232
+ return acc;
233
+ }, {} as GridColumnVisibilityModel),
234
+ }),
235
+ );
236
+ }}
237
+ />
238
+ }
137
239
  />
138
240
  </>
139
241
  );