@campxdev/react-blueprint 1.7.3 → 1.7.5

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 (45) hide show
  1. package/package.json +1 -1
  2. package/src/assets/images/svg/index.ts +13 -13
  3. package/src/components/Assets/ErrorPages/InternalServerError.tsx +5 -5
  4. package/src/components/Assets/ErrorPages/NoInternetConnection.tsx +5 -5
  5. package/src/components/Assets/ErrorPages/NoItemFound.tsx +6 -5
  6. package/src/components/Assets/ErrorPages/PageNotFound.tsx +5 -5
  7. package/src/components/Assets/ErrorPages/UnAuthorized.tsx +5 -5
  8. package/src/components/Assets/ErrorPages/styles.tsx +1 -1
  9. package/src/components/Assets/Icons/IconComponents/ClearIcon.tsx +37 -0
  10. package/src/components/Assets/Icons/IconComponents/DoneSquare.tsx +2 -2
  11. package/src/components/Assets/Icons/IconComponents/DownArrow.tsx +32 -0
  12. package/src/components/Assets/Icons/IconComponents/LIneDivider.tsx +23 -0
  13. package/src/components/Assets/Icons/IconComponents/RedirectIcon.tsx +1 -1
  14. package/src/components/Assets/Icons/Icons.tsx +6 -0
  15. package/src/components/DataDisplay/ActivityLogView/ActivityLogView.tsx +2 -2
  16. package/src/components/DataDisplay/ActivityLogView/service.tsx +1 -19
  17. package/src/components/DataDisplay/DataTable/DataTable.tsx +62 -39
  18. package/src/components/DataDisplay/DataTable/TablePagination.tsx +20 -12
  19. package/src/components/DataDisplay/EmptyIllustration/EmptyIllustration.tsx +40 -0
  20. package/src/components/DataDisplay/export.ts +1 -0
  21. package/src/components/Feedback/Spinner/Spinner.css +13 -25
  22. package/src/components/Input/RadioGroup/RadioGroup.tsx +6 -2
  23. package/src/components/Input/SearchBar/SearchBar.tsx +17 -14
  24. package/src/components/Input/SingleSelect/SingleSelect.tsx +2 -1
  25. package/src/components/Input/SingleSelect/components/MenuFooter.tsx +24 -0
  26. package/src/components/Input/SingleSelect/components/OptionsLoader.tsx +14 -0
  27. package/src/components/Input/SingleSelect/components/SingleFilter.tsx +69 -62
  28. package/src/components/Input/SingleSelect/components/SingleInput.tsx +45 -18
  29. package/src/components/Input/TextField/TextField.tsx +4 -1
  30. package/src/components/Input/styles.tsx +5 -5
  31. package/src/components/Layout/PageContent/PageContent.tsx +4 -3
  32. package/src/components/Layout/PageHeader/PageHeader.tsx +22 -69
  33. package/src/components/Layout/PageHeader/components/SearchBar.tsx +69 -26
  34. package/src/components/Layout/PageHeader/components/TableColumnsSelector/TableColumnsSelector.tsx +124 -22
  35. package/src/components/Navigation/Breadcrumbs/Breadcrumbs.tsx +1 -0
  36. package/src/components/Navigation/DropDownMenu/DropDownMenu.tsx +2 -2
  37. package/src/components/Navigation/Sidebar/styles.tsx +2 -1
  38. package/src/components/Navigation/TabsContainer/TabsContainer.tsx +4 -1
  39. package/src/redux/slices/pageHeaderSlice.ts +4 -1
  40. package/src/themes/commonTheme.ts +30 -5
  41. package/src/components/DataDisplay/styles.tsx +0 -6
  42. package/src/components/Input/components/OptionsLoader.tsx +0 -22
  43. /package/src/assets/images/svg/{Emptylistmage.svg → empty.svg} +0 -0
  44. /package/src/assets/images/svg/{error-cactus.svg → error-image.svg} +0 -0
  45. /package/src/assets/images/svg/{Internalserverimage.svg → server-error.svg} +0 -0
@@ -6,39 +6,27 @@
6
6
  animation: rotate 1s linear infinite;
7
7
  scale: 0.4;
8
8
  }
9
- .spinner::before,
10
- .spinner::after {
11
- content: '';
9
+ .spinner::before , .spinner::after {
10
+ content: "";
12
11
  box-sizing: border-box;
13
12
  position: absolute;
14
13
  inset: 0px;
15
14
  border-radius: 50%;
16
- border: 5px solid #7d60d9;
17
- animation: prixClipFix 1.5s linear infinite;
15
+ border: 5px solid #7D60D9;
16
+ animation: prixClipFix 1.5s linear infinite ;
18
17
  }
19
- .spinner::after {
20
- transform: rotate3d(90, 90, 0, 180deg);
21
- border-color: #ff3d00;
18
+ .spinner::after{
19
+ transform: rotate3d(90, 90, 0, 180deg );
20
+ border-color: #FF3D00;
22
21
  }
23
22
 
24
23
  @keyframes rotate {
25
- 0% {
26
- transform: rotate(0deg);
27
- }
28
- 100% {
29
- transform: rotate(360deg);
30
- }
24
+ 0% {transform: rotate(0deg)}
25
+ 100% {transform: rotate(360deg)}
31
26
  }
32
27
 
33
28
  @keyframes prixClipFix {
34
- 0% {
35
- clippath: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0);
36
- }
37
- 50% {
38
- clippath: polygon(50% 50%, 0 0, 100% 0, 100% 0, 100% 0, 100% 0);
39
- }
40
- 75%,
41
- 100% {
42
- clippath: polygon(50% 50%, 0 0, 100% 0, 100% 100%, 100% 100%, 100% 100%);
43
- }
44
- }
29
+ 0% {clip-path:polygon(50% 50%,0 0,0 0,0 0,0 0,0 0)}
30
+ 50% {clip-path:polygon(50% 50%,0 0,100% 0,100% 0,100% 0,100% 0)}
31
+ 75%, 100% {clip-path:polygon(50% 50%,0 0,100% 0,100% 100%,100% 100%,100% 100%)}
32
+ }
@@ -36,7 +36,12 @@ export const RadioGroup = ({
36
36
  name={name}
37
37
  containerProps={containerProps}
38
38
  >
39
- <MuiRadioGroup onChange={onChange} name={name} {...rest}>
39
+ <MuiRadioGroup
40
+ onChange={onChange}
41
+ name={name}
42
+ {...rest}
43
+ sx={{ height: '100%', ...rest.sx }}
44
+ >
40
45
  {options?.map((item, index) => (
41
46
  <FormControlLabel
42
47
  key={index}
@@ -49,7 +54,6 @@ export const RadioGroup = ({
49
54
  />
50
55
  }
51
56
  label={<Typography variant="body2">{item.label}</Typography>}
52
- sx={{ marginBottom: '32px' }}
53
57
  />
54
58
  ))}
55
59
  </MuiRadioGroup>
@@ -1,4 +1,5 @@
1
1
  import {
2
+ Box,
2
3
  InputAdornment,
3
4
  TextField,
4
5
  TextFieldProps,
@@ -34,20 +35,22 @@ export const SearchBar = ({
34
35
  };
35
36
 
36
37
  return (
37
- <StyledTextField
38
- placeholder={placeholder}
39
- label={label}
40
- value={search}
41
- InputProps={{
42
- endAdornment: (
43
- <InputAdornment position="end">
44
- <SearchIcon />
45
- </InputAdornment>
46
- ),
47
- }}
48
- {...rest}
49
- onChange={handleChange}
50
- />
38
+ <Box margin="8px">
39
+ <StyledTextField
40
+ placeholder={placeholder}
41
+ label={label}
42
+ value={search}
43
+ InputProps={{
44
+ endAdornment: (
45
+ <InputAdornment position="end">
46
+ <SearchIcon />
47
+ </InputAdornment>
48
+ ),
49
+ }}
50
+ {...rest}
51
+ onChange={handleChange}
52
+ />
53
+ </Box>
51
54
  );
52
55
  };
53
56
 
@@ -51,11 +51,12 @@ export type SingleSelectProps = {
51
51
  error?: any;
52
52
  helperText?: string;
53
53
  type?: 'input' | 'filter';
54
+ disableClear?: boolean;
54
55
  } & Omit<
55
56
  AutocompleteProps<
56
57
  { label: string; subLabel?: string; value: any } | any,
57
58
  false,
58
- false,
59
+ true,
59
60
  false
60
61
  >,
61
62
  | 'options'
@@ -0,0 +1,24 @@
1
+ import { useTheme } from '@mui/material';
2
+ import { Button } from '../../export';
3
+ import { FooterContainer } from '../../styles';
4
+
5
+ export const MenuFooter = ({ onClick }: { onClick: () => void }) => {
6
+ const theme = useTheme();
7
+ return (
8
+ <FooterContainer direction="row" alignItems="center">
9
+ <Button
10
+ variant="text"
11
+ onClick={onClick}
12
+ sx={{
13
+ fontFamily: 'Heebo',
14
+ minWidth: '0px',
15
+ margin: '0px 16px',
16
+ }}
17
+ disableRipple
18
+ color={theme.palette.text.tertiary}
19
+ >
20
+ Clear
21
+ </Button>
22
+ </FooterContainer>
23
+ );
24
+ };
@@ -0,0 +1,14 @@
1
+ import { Typography } from '../../../DataDisplay/Typography/Typography';
2
+ import { Spinner } from '../../../Feedback/Spinner/Spinner';
3
+ import { FooterContainer } from '../../styles';
4
+
5
+ export const OptionsLoader = ({ isSearch }: { isSearch: boolean }) => {
6
+ return (
7
+ <FooterContainer direction="row" alignItems="center">
8
+ <Spinner />
9
+ <Typography variant="caption">
10
+ {isSearch ? 'Searching' : 'Loading Options'}
11
+ </Typography>
12
+ </FooterContainer>
13
+ );
14
+ };
@@ -3,12 +3,12 @@ import {
3
3
  AutocompleteCloseReason,
4
4
  FormControlLabel,
5
5
  RadioGroup as MuiRadioGroup,
6
- Paper,
7
6
  Radio,
8
7
  useTheme,
9
8
  } from '@mui/material';
10
9
  import { startCase } from 'lodash';
11
10
  import { SyntheticEvent, useState } from 'react';
11
+ import { EmptyIllustration } from '../../../DataDisplay/EmptyIllustration/EmptyIllustration';
12
12
  import {
13
13
  Button,
14
14
  DropdownMenu,
@@ -17,9 +17,10 @@ import {
17
17
  SingleSelectProps,
18
18
  Typography,
19
19
  } from '../../../export';
20
- import { OptionsLoader } from '../../components/OptionsLoader';
21
- import { OptionContainer } from '../../styles';
20
+ import { FilterOptionContainer } from '../../styles';
22
21
  import { SingleSelectState } from '../singleSelectReducer';
22
+ import { MenuFooter } from './MenuFooter';
23
+ import { OptionsLoader } from './OptionsLoader';
23
24
 
24
25
  declare module '@mui/material/Autocomplete' {
25
26
  interface AutocompletePaperSlotPropsOverrides {
@@ -28,19 +29,6 @@ declare module '@mui/material/Autocomplete' {
28
29
  }
29
30
  }
30
31
 
31
- const CustomPaper = (props: any) => (
32
- <Paper
33
- {...props}
34
- sx={{
35
- boxShadow: 'none',
36
- borderRadius: '0px 0px 4px 4px',
37
- }}
38
- >
39
- {props.children}
40
- <OptionsLoader loading={props.loadingOptions} isSearch={props.isSearch} />
41
- </Paper>
42
- );
43
-
44
32
  export type SingleFilterProps = {
45
33
  onChange: (value: any) => void;
46
34
  searchDb: (searchValue: string) => Promise<void>;
@@ -81,6 +69,7 @@ export const SingleFilter = ({
81
69
  handleClose,
82
70
  handleScroll,
83
71
  state,
72
+ disableClear = false,
84
73
  ...restProps
85
74
  }: SingleFilterProps) => {
86
75
  const {
@@ -106,7 +95,7 @@ export const SingleFilter = ({
106
95
  <DropdownMenu
107
96
  menuListProps={{
108
97
  sx: {
109
- padding: '12px',
98
+ padding: '0px',
110
99
  width: '250px',
111
100
  },
112
101
  }}
@@ -159,15 +148,28 @@ export const SingleFilter = ({
159
148
  />
160
149
  }
161
150
  menuListContainerSx={{
162
- gap: '10px',
163
- minHeight: '310px',
164
- maxHeight: '310px',
165
- overflow: 'scroll',
166
- overflowY: 'auto',
167
- marginTop: '10px',
151
+ margin: '10px 5px 0px 5px',
152
+ height: '310px',
153
+ overflowY: 'scroll',
168
154
  }}
169
155
  handleMenuScroll={handleScroll}
170
156
  menuSlot={({ close }) => {
157
+ const filteredOptions = internalOptions?.filter(
158
+ (option) =>
159
+ (localSearch && option.label.includes(localSearch)) ||
160
+ !localSearch,
161
+ );
162
+
163
+ if (filteredOptions.length === 0 && !loadingInitialInternalOptions)
164
+ return (
165
+ <EmptyIllustration
166
+ message="No Options Found"
167
+ imageSize="100px"
168
+ containerProps={{
169
+ height: '310px',
170
+ }}
171
+ />
172
+ );
171
173
  return (
172
174
  <MuiRadioGroup
173
175
  onChange={(e) => {
@@ -176,50 +178,55 @@ export const SingleFilter = ({
176
178
  name={name}
177
179
  value={value}
178
180
  >
179
- {internalOptions
180
- ?.filter(
181
- (option) =>
182
- (localSearch && option.label.includes(localSearch)) ||
183
- !localSearch,
184
- )
185
- ?.map((option, index) => (
186
- <FormControlLabel
187
- sx={{
188
- margin: '0px',
181
+ {filteredOptions?.map((option, index) => (
182
+ <FormControlLabel
183
+ sx={{
184
+ margin: '0px',
185
+ width: '100%',
186
+ '.MuiFormControlLabel-label': {
189
187
  width: '100%',
190
- '.MuiFormControlLabel-label': {
191
- width: '100%',
192
- },
193
- }}
194
- key={index}
195
- value={option.value}
196
- control={
197
- <Radio
198
- checkedIcon={<Icons.CheckedRadioIcon />}
199
- icon={<Icons.UnCheckedRadioIcon />}
200
- />
201
- }
202
- label={
203
- <OptionContainer>
204
- <Typography variant="subtitle3">
205
- {dbLabelProps.useLabelStartCase
206
- ? startCase(option.label)
207
- : option.label}
208
- </Typography>
209
- <Typography variant="caption">
210
- {dbLabelProps.useSubLabelStartCase
211
- ? startCase(option?.subLabel)
212
- : option?.subLabel}
213
- </Typography>
214
- </OptionContainer>
215
- }
216
- />
217
- ))}
188
+ },
189
+ }}
190
+ key={index}
191
+ value={option.value}
192
+ control={
193
+ <Radio
194
+ checkedIcon={<Icons.CheckedRadioIcon />}
195
+ icon={<Icons.UnCheckedRadioIcon />}
196
+ checked={value == option.value}
197
+ />
198
+ }
199
+ label={
200
+ <FilterOptionContainer>
201
+ <Typography variant="subtitle3">
202
+ {dbLabelProps.useLabelStartCase
203
+ ? startCase(option.label)
204
+ : option.label}
205
+ </Typography>
206
+ <Typography variant="caption">
207
+ {dbLabelProps.useSubLabelStartCase
208
+ ? startCase(option?.subLabel)
209
+ : option?.subLabel}
210
+ </Typography>
211
+ </FilterOptionContainer>
212
+ }
213
+ />
214
+ ))}
218
215
  </MuiRadioGroup>
219
216
  );
220
217
  }}
221
218
  menuFooter={
222
- <OptionsLoader loading={loadingInternalOptions} isSearch={!!search} />
219
+ loadingInternalOptions ? (
220
+ <OptionsLoader isSearch={!!search} />
221
+ ) : disableClear ? (
222
+ <></>
223
+ ) : (
224
+ <MenuFooter
225
+ onClick={() => {
226
+ onChange(null);
227
+ }}
228
+ />
229
+ )
223
230
  }
224
231
  useMenuSlot
225
232
  />
@@ -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
  };