@campxdev/react-blueprint 1.8.5 → 1.8.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/react-blueprint",
3
- "version": "1.8.5",
3
+ "version": "1.8.6",
4
4
  "main": "./export.ts",
5
5
  "dependencies": {
6
6
  "@emotion/react": "^11.13.3",
@@ -1,19 +1,20 @@
1
1
  import {
2
+ AccordionDetails,
3
+ AccordionSummary,
2
4
  Box,
3
- Accordion as MuiAccordion,
4
- AccordionDetails as MuiAccordionDetails,
5
5
  AccordionProps as MuiAccordionProps,
6
- AccordionSummary as MuiAccordionSummary,
7
6
  Stack,
8
7
  } from '@mui/material';
9
8
  import { ReactNode } from 'react';
10
9
  import { Icons, Typography } from '../../export';
10
+ import { StyledMuiAccordion } from './styles';
11
11
 
12
12
  export type AccordionProps = {
13
13
  title: ReactNode;
14
14
  content: ReactNode;
15
15
  actions?: ReactNode;
16
16
  index?: number;
17
+ errorKeys?: string[];
17
18
  expanded?: boolean | number;
18
19
  } & Omit<
19
20
  MuiAccordionProps,
@@ -25,29 +26,29 @@ export const Accordion = (props: AccordionProps) => {
25
26
  props;
26
27
 
27
28
  return (
28
- <MuiAccordion
29
+ <StyledMuiAccordion
29
30
  key={index}
30
31
  onChange={onChange}
31
32
  expanded={typeof expanded == 'number' ? expanded === index : expanded}
32
33
  {...restProps}
33
34
  >
34
35
  <Stack direction="row" justifyContent="space-between" alignItems="center">
35
- <MuiAccordionSummary expandIcon={<Icons.AccordionArrow />}>
36
+ <AccordionSummary expandIcon={<Icons.AccordionArrow />}>
36
37
  {typeof title === 'string' ? (
37
38
  <Typography variant="subtitle2">{title}</Typography>
38
39
  ) : (
39
40
  title
40
41
  )}
41
- </MuiAccordionSummary>
42
+ </AccordionSummary>
42
43
  <Box>{actions}</Box>
43
44
  </Stack>
44
- <MuiAccordionDetails>
45
+ <AccordionDetails>
45
46
  {typeof content === 'string' ? (
46
47
  <Typography variant="label1">{content}</Typography>
47
48
  ) : (
48
49
  content
49
50
  )}
50
- </MuiAccordionDetails>
51
- </MuiAccordion>
51
+ </AccordionDetails>
52
+ </StyledMuiAccordion>
52
53
  );
53
54
  };
@@ -0,0 +1,10 @@
1
+ import { Accordion as MuiAccordion, styled } from '@mui/material';
2
+
3
+ export const StyledMuiAccordion = styled(MuiAccordion)(() => ({
4
+ '&:before': {
5
+ display: 'none',
6
+ },
7
+ '&.Mui-expanded': {
8
+ margin: '0px',
9
+ },
10
+ }));
@@ -1,14 +1,35 @@
1
- import { Box, SxProps } from '@mui/material';
2
- import { SyntheticEvent, useState } from 'react';
1
+ import { SxProps } from '@mui/material';
2
+ import { SyntheticEvent, useEffect, useState } from 'react';
3
3
  import { Accordion, AccordionProps } from '../Accordion/Accordion';
4
+ import { StyledAccordionContainer } from './styles';
4
5
 
5
6
  type AccordionGroupProps = {
6
7
  data: AccordionProps[];
7
8
  containerSx?: SxProps;
9
+ defaultExpandedIndex?: number;
10
+ errorField?: string;
8
11
  };
9
12
 
10
- export const AccordionGroup = ({ data, containerSx }: AccordionGroupProps) => {
11
- const [expanded, setExpanded] = useState<number | false>(false);
13
+ export const AccordionGroup = ({
14
+ data,
15
+ containerSx,
16
+ defaultExpandedIndex,
17
+ errorField,
18
+ }: AccordionGroupProps) => {
19
+ const [expanded, setExpanded] = useState<number | false>(
20
+ defaultExpandedIndex ?? false,
21
+ );
22
+
23
+ useEffect(() => {
24
+ if (errorField) {
25
+ const errorIndex = data.findIndex((item) =>
26
+ Array.isArray(item.errorKeys)
27
+ ? item.errorKeys.includes(errorField)
28
+ : false,
29
+ );
30
+ if (errorIndex !== -1) setExpanded(errorIndex);
31
+ }
32
+ }, [errorField, data]);
12
33
 
13
34
  const handleChange =
14
35
  (panel: number) => (event: SyntheticEvent, isExpanded: boolean) => {
@@ -16,16 +37,16 @@ export const AccordionGroup = ({ data, containerSx }: AccordionGroupProps) => {
16
37
  };
17
38
 
18
39
  return (
19
- <Box sx={{ ...containerSx }}>
40
+ <StyledAccordionContainer sx={{ ...containerSx }}>
20
41
  {data?.map((itemProps, index) => (
21
42
  <Accordion
22
43
  elevation={0}
23
- {...itemProps}
24
44
  expanded={expanded}
45
+ {...itemProps}
25
46
  index={index}
26
47
  onChange={handleChange(index)}
27
48
  />
28
49
  ))}
29
- </Box>
50
+ </StyledAccordionContainer>
30
51
  );
31
52
  };
@@ -0,0 +1,8 @@
1
+ import { Box, styled } from '@mui/material';
2
+
3
+ export const StyledAccordionContainer = styled(Box)(({ theme }) => ({
4
+ display: 'flex',
5
+ gap: '4px',
6
+ flexDirection: 'column',
7
+ backgroundColor: theme.palette.surface.defaultBackground,
8
+ }));
@@ -1,8 +1,9 @@
1
1
  import { TimelineContent, TimelineItem, TimelineSeparator } from '@mui/lab';
2
- import { Box, Stack, Typography, useTheme } from '@mui/material';
2
+ import { Box, Stack, SxProps, Typography, useTheme } from '@mui/material';
3
3
  import { format, isToday } from 'date-fns';
4
4
  import _ from 'lodash';
5
5
  import { useState } from 'react';
6
+ import { AddSquare } from '../../Assets/Icons/IconComponents/AddSquare';
6
7
  import { Button, DatePicker, Spinner } from '../../export';
7
8
  import { EmptyIllustration } from '../EmptyIllustration/EmptyIllustration';
8
9
  import {
@@ -14,7 +15,6 @@ import {
14
15
  import {
15
16
  StyledActivityLogViewBox,
16
17
  StyledIconBox,
17
- StyledSectionTitle,
18
18
  StyledSpinnerBox,
19
19
  StyledTimeline,
20
20
  StyledTimelineConnector,
@@ -24,8 +24,8 @@ import {
24
24
  export type ActivityAction = 'create' | 'update' | 'delete';
25
25
 
26
26
  export interface Activity {
27
- userName: string;
28
- action: ActivityAction;
27
+ userName?: string;
28
+ action?: ActivityAction;
29
29
  message: string;
30
30
  timestamp: string;
31
31
  }
@@ -40,6 +40,9 @@ interface ActivityLogProps {
40
40
  setFromDate: (date: Date | null) => void;
41
41
  setToDate: (date: Date | null) => void;
42
42
  isLoading: boolean;
43
+ hideLogFilter?: boolean;
44
+ timelineContentSx?: SxProps;
45
+ timelineSx?: SxProps;
43
46
  }
44
47
 
45
48
  const ActivityLogFilter = ({
@@ -115,6 +118,9 @@ export const ActivityLogView = ({
115
118
  setFromDate,
116
119
  setToDate,
117
120
  isLoading,
121
+ hideLogFilter = false,
122
+ timelineContentSx = {},
123
+ timelineSx = {},
118
124
  }: ActivityLogProps) => {
119
125
  const theme = useTheme();
120
126
  const lastItemRef = useIntersectionObserver(() => {
@@ -134,14 +140,14 @@ export const ActivityLogView = ({
134
140
  });
135
141
 
136
142
  const renderMessage = (activity: Activity) =>
137
- activity.message.split('\n').map((part, index) => (
138
- <Typography key={index} component="div">
139
- {index === 0 && (
143
+ activity.message?.split('\n').map((part, index) => (
144
+ <Typography key={index} variant="body1" sx={{ fontWeight: 500 }}>
145
+ {index === 0 && activity.userName && (
140
146
  <span style={{ color: theme.palette.text.primary }}>
141
147
  {activity.userName}
142
148
  </span>
143
149
  )}{' '}
144
- {part.split(/('[^']*')/g).map((text, idx) => {
150
+ {part?.split(/('[^']*')/g).map((text, idx) => {
145
151
  const isQuotedText = text.startsWith("'") && text.endsWith("'");
146
152
  return (
147
153
  <span
@@ -161,14 +167,16 @@ export const ActivityLogView = ({
161
167
 
162
168
  return (
163
169
  <StyledActivityLogViewBox className="scrollable-activity-log">
164
- <ActivityLogFilter
165
- fromDate={fromDate}
166
- toDate={toDate}
167
- setFromDate={setFromDate}
168
- setToDate={setToDate}
169
- fetchNextPage={fetchNextPage}
170
- isLoading={isLoading}
171
- />
170
+ {!hideLogFilter && (
171
+ <ActivityLogFilter
172
+ fromDate={fromDate}
173
+ toDate={toDate}
174
+ setFromDate={setFromDate}
175
+ setToDate={setToDate}
176
+ fetchNextPage={fetchNextPage}
177
+ isLoading={isLoading}
178
+ />
179
+ )}
172
180
 
173
181
  {loading ? (
174
182
  <StyledSpinnerBox>
@@ -179,8 +187,8 @@ export const ActivityLogView = ({
179
187
  ) : (
180
188
  Object.entries(groupedActivities).map(([section, activities]) => (
181
189
  <Box key={section}>
182
- <StyledSectionTitle>{section}</StyledSectionTitle>
183
- <StyledTimeline>
190
+ <Typography variant="caption">{section}</Typography>
191
+ <StyledTimeline sx={{ ...timelineSx }}>
184
192
  {activities.map((activity, index) => (
185
193
  <TimelineItem
186
194
  key={index}
@@ -189,7 +197,11 @@ export const ActivityLogView = ({
189
197
  <TimelineSeparator>
190
198
  <StyledTimelineDot>
191
199
  <StyledIconBox>
192
- <ActivityIcon type={activity.action} />
200
+ {activity.action ? (
201
+ <ActivityIcon type={activity.action} />
202
+ ) : (
203
+ <AddSquare />
204
+ )}
193
205
  </StyledIconBox>
194
206
  </StyledTimelineDot>
195
207
  {index < activities.length - 1 && (
@@ -201,9 +213,12 @@ export const ActivityLogView = ({
201
213
  display: 'flex',
202
214
  justifyContent: 'space-between',
203
215
  marginTop: 1,
216
+ ...timelineContentSx,
204
217
  }}
205
218
  >
206
- <Typography>{renderMessage(activity)}</Typography>
219
+ <Typography variant="body1" sx={{ fontWeight: 500 }}>
220
+ {renderMessage(activity)}
221
+ </Typography>
207
222
  <Typography variant="caption">
208
223
  {format(
209
224
  convertUTCtoIST(activity.timestamp),
@@ -22,6 +22,8 @@ export const StyledTimeline = styled(Timeline)({
22
22
  [`& .${timelineItemClasses.root}:not(:first-of-type)`]: {
23
23
  marginTop: '0px',
24
24
  },
25
+ padding: 0,
26
+ margin: 0,
25
27
  });
26
28
 
27
29
  export const StyledTimelineDot = styled(TimelineDot)(({ theme }) => ({
@@ -1,17 +1,24 @@
1
- import { Box, styled, Theme, useTheme } from '@mui/material';
2
- import { Typography } from '../../export';
1
+ import { Box, styled, SxProps, Theme, useTheme } from '@mui/material';
2
+ import { Typography, TypographyProps } from '../../export';
3
3
 
4
4
  export type StatusCardProps = {
5
5
  color: 'green' | 'red' | 'orange' | 'yellow' | 'blue' | 'pink';
6
6
  text: string;
7
+ containerSx?: SxProps;
8
+ typographyVariant?: TypographyProps['variant'];
7
9
  };
8
10
 
9
- export const StatusCard = ({ color, text }: StatusCardProps) => {
11
+ export const StatusCard = ({
12
+ color,
13
+ text,
14
+ containerSx = {},
15
+ typographyVariant = 'label2',
16
+ }: StatusCardProps) => {
10
17
  const theme = useTheme();
11
18
  const { textColor, backgroundColor } = getStatusColor(color, theme);
12
19
  return (
13
- <StatusContainer backgroundColor={backgroundColor}>
14
- <Typography variant="label2" color={textColor}>
20
+ <StatusContainer backgroundColor={backgroundColor} sx={containerSx}>
21
+ <Typography variant={typographyVariant} color={textColor}>
15
22
  {text}
16
23
  </Typography>
17
24
  </StatusContainer>
@@ -2,7 +2,7 @@ import { Stack, StackProps } from '@mui/material';
2
2
  import { ResponsiveStyleValue } from '@mui/system';
3
3
  import { ReactNode } from 'react';
4
4
  import { LabelWrapper } from '../LabelWrapper/LabelWrapper';
5
- import { SingleCheckBox } from '../SingleCheckBox/SIngleCheckBox';
5
+ import { SingleCheckBox } from '../SingleCheckBox/SingleCheckBox';
6
6
 
7
7
  export type MultiCheckboxProps = {
8
8
  containerProps?: StackProps;
@@ -3,6 +3,7 @@ import {
3
3
  FormControlLabelProps,
4
4
  Checkbox as MuiCheckbox,
5
5
  CheckboxProps as MuiCheckboxProps,
6
+ SxProps,
6
7
  useTheme,
7
8
  } from '@mui/material';
8
9
  import { ReactNode } from 'react';
@@ -97,6 +97,7 @@ export const SingleFilter = ({
97
97
  sx: {
98
98
  padding: '0px',
99
99
  width: '250px',
100
+ minWidth: 'max-content',
100
101
  },
101
102
  }}
102
103
  anchor={({ open }: { open: (e: any) => void }) => (
@@ -109,6 +110,10 @@ export const SingleFilter = ({
109
110
  sx={{
110
111
  gap: '1px',
111
112
  borderRadius: '20px',
113
+ textWrap: 'nowrap',
114
+ textOverflow: 'ellipsis',
115
+ overflow: 'hidden',
116
+ minWidth: 'max-content',
112
117
  }}
113
118
  variant="contained"
114
119
  background={
@@ -11,7 +11,7 @@ export * from './PasswordField/PasswordField';
11
11
  export * from './RadioGroup/RadioGroup';
12
12
  export * from './SearchBar/SearchBar';
13
13
  export * from './Select/Select';
14
- export * from './SingleCheckBox/SIngleCheckBox';
14
+ export * from './SingleCheckBox/SingleCheckBox';
15
15
  export * from './SingleSelect/SingleSelect';
16
16
  export * from './Switch/Switch';
17
17
  export * from './TextField/TextField';
@@ -28,6 +28,7 @@ interface PageHeaderProps {
28
28
  actions?: ReactNode[];
29
29
  columns?: GridColDef[];
30
30
  searchText?: string;
31
+ defaultShowLabels?: string[];
31
32
  }
32
33
 
33
34
  const ViewTab = ({ title }: { title: string }) => {
@@ -59,13 +60,23 @@ export const PageHeader = ({
59
60
  uniqueId,
60
61
  actions = [],
61
62
  filterComponents = [],
63
+ defaultShowLabels = [],
62
64
  columns,
63
65
  viewsSlot = <Box></Box>,
64
66
  searchText = 'Search',
65
67
  }: PageHeaderProps) => {
66
68
  const [expanded, setExpanded] = useState(false);
67
69
 
68
- const [hiddenLabels, setHiddenLabels] = useState<string[]>([]);
70
+ const allFilterLabels = filterComponents.map(
71
+ (filter) => filter.props['label'] || 'Label Not Found',
72
+ );
73
+
74
+ const initialHiddenLabels = allFilterLabels.filter(
75
+ (label) => !defaultShowLabels.includes(label),
76
+ );
77
+
78
+ const [hiddenLabels, setHiddenLabels] =
79
+ useState<string[]>(initialHiddenLabels);
69
80
 
70
81
  const dispatch = useDispatch();
71
82
 
@@ -188,7 +199,7 @@ export const PageHeader = ({
188
199
  }
189
200
  }}
190
201
  handleReset={() => {
191
- setHiddenLabels([]);
202
+ setHiddenLabels(initialHiddenLabels);
192
203
  }}
193
204
  />
194
205
  </Stack>
@@ -51,7 +51,7 @@ export const TabsContainer = ({
51
51
 
52
52
  useEffect(() => {
53
53
  setCurrentTab(tabs[currentTabIndex]?.key);
54
- }, []);
54
+ }, [tabs, currentTabIndex]);
55
55
 
56
56
  return (
57
57
  <>
@@ -3,7 +3,7 @@ import { useState } from 'react';
3
3
  import {
4
4
  CheckboxProps,
5
5
  SingleCheckBox,
6
- } from '../../components/Input/SingleCheckBox/SIngleCheckBox';
6
+ } from '../../components/Input/SingleCheckBox/SingleCheckBox';
7
7
 
8
8
  export default {
9
9
  title: 'Input/SingleCheckBox',
@@ -91,14 +91,11 @@ export const getCommonTheme = (mode: Theme) => {
91
91
  },
92
92
  },
93
93
  },
94
- // MuiAccordian: {
95
- // root: {},
96
- // },
97
94
  MuiAccordionSummary: {
98
95
  styleOverrides: {
99
96
  root: {
100
97
  justifyContent: 'flex-start',
101
- paddingLeft: '20px',
98
+ padding: '0px 16px',
102
99
  '&.Mui-expanded': {
103
100
  minHeight: '0px',
104
101
  },
@@ -118,6 +115,13 @@ export const getCommonTheme = (mode: Theme) => {
118
115
  },
119
116
  },
120
117
  },
118
+ MuiAccordionDetails: {
119
+ styleOverrides: {
120
+ root: {
121
+ padding: '0px 16px',
122
+ },
123
+ },
124
+ },
121
125
  MuiStepLabel: {
122
126
  styleOverrides: {
123
127
  root: {