@campxdev/shared 1.10.63 → 1.10.65

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/shared",
3
- "version": "1.10.63",
3
+ "version": "1.10.65",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -16,6 +16,7 @@ export interface ITimePicker {
16
16
  placeholder?: string
17
17
  inputProps?: TextFieldProps
18
18
  size?: 'medium' | 'small'
19
+ disabled?: boolean
19
20
  }
20
21
 
21
22
  export default function TimePicker({
@@ -28,6 +29,7 @@ export default function TimePicker({
28
29
  value,
29
30
  placeholder,
30
31
  size = 'medium',
32
+ disabled,
31
33
  ...rest
32
34
  }: ITimePicker) {
33
35
  return (
@@ -68,6 +70,7 @@ export default function TimePicker({
68
70
  </InputAdornment>
69
71
  ),
70
72
  }}
73
+ disabled={disabled}
71
74
  {...rest.inputProps}
72
75
  />
73
76
  )
@@ -0,0 +1,218 @@
1
+ import {
2
+ Box,
3
+ IconButton,
4
+ ListItemIcon,
5
+ Table as MuiTable,
6
+ TableBody,
7
+ TableCell,
8
+ TableContainer,
9
+ TableHead,
10
+ TableRow,
11
+ alpha,
12
+ styled,
13
+ } from '@mui/material'
14
+ import _ from 'lodash'
15
+ import { useEffect, useState } from 'react'
16
+ import Spinner from '../../Spinner'
17
+ import TableFooter from '../BasicTable/TableFooter'
18
+ import NoRecordsFound from '../common/NoRecordsFound'
19
+ import { SortAscIcon, SortDescIcon, SortIcon } from '../common/icons'
20
+
21
+ export interface ColumnProps {
22
+ dataIndex: string
23
+ key: string
24
+ title: any
25
+ render?: (cellData: any, row: any, index: number) => any
26
+ textColor?: string
27
+ sort?: boolean
28
+ width?: string //pixels
29
+ }
30
+
31
+ interface TableProps {
32
+ columns: Array<ColumnProps>
33
+ rowKey?: string
34
+ dataSource?: any[]
35
+ loading?: boolean
36
+ onRowClick?: (row: any) => void
37
+ pagination?: {
38
+ page: number
39
+ limit: number
40
+ totalCount: number
41
+ onChange: (v: number) => void
42
+ onChangeLimit?: (v: number) => void
43
+ }
44
+ onSort?: (sort: any) => void
45
+ dense?: boolean
46
+ isLastRowColorChange?: boolean
47
+ }
48
+
49
+ type Order = 'asc' | 'desc' | ''
50
+ type Sort = {}
51
+
52
+ export default function MobileTable({
53
+ columns,
54
+ dataSource,
55
+ onRowClick,
56
+ pagination,
57
+ loading,
58
+ onSort,
59
+ dense = false,
60
+ isLastRowColorChange = false,
61
+ }: TableProps) {
62
+ const [sort, setSort] = useState<Sort>({})
63
+
64
+ const handleSortClick = (sortBykey) => {
65
+ setSort((prev) => {
66
+ if (prev[sortBykey]) {
67
+ if (prev[sortBykey] === 'desc') return { ...prev, [sortBykey]: 'asc' }
68
+ if (prev[sortBykey] === 'asc') {
69
+ delete prev[sortBykey]
70
+ return { ...prev }
71
+ }
72
+ } else {
73
+ return {
74
+ ...prev,
75
+ [sortBykey]: 'desc',
76
+ }
77
+ }
78
+ })
79
+ }
80
+
81
+ useEffect(() => {
82
+ if (!onSort) return
83
+
84
+ onSort({
85
+ sortBy: Object.keys(sort).join(','),
86
+ sortOrder: Object.keys(sort)
87
+ .map((item) => sort[item])
88
+ .join(','),
89
+ })
90
+ }, [sort])
91
+
92
+ return (
93
+ <StyledTableContainer>
94
+ <>
95
+ <StyledMuiTable>
96
+ <TableHead>
97
+ <TableRow>
98
+ {columns.map((col, index) => (
99
+ <TableCell
100
+ key={index}
101
+ sx={{
102
+ ...(col?.width && {
103
+ width: col?.width,
104
+ }),
105
+ borderRightColor: '#1212121A',
106
+ borderRightStyle: 'solid',
107
+ }}
108
+ >
109
+ <Box sx={{ fontWeight: 500, fontSize: '14px' }}>
110
+ {col.title}
111
+ </Box>
112
+ {col.sort && (
113
+ <IconButton onClick={() => handleSortClick(col.dataIndex)}>
114
+ <ListItemIcon>
115
+ {sort[col.dataIndex] === 'asc' ? (
116
+ <SortAscIcon />
117
+ ) : sort[col.dataIndex] === 'desc' ? (
118
+ <SortDescIcon />
119
+ ) : (
120
+ <SortIcon />
121
+ )}
122
+ </ListItemIcon>
123
+ </IconButton>
124
+ )}
125
+ </TableCell>
126
+ ))}
127
+ </TableRow>
128
+ </TableHead>
129
+ {!loading ? (
130
+ <>
131
+ {dataSource?.length ? (
132
+ <TableBody>
133
+ {dataSource?.map((row, index) => (
134
+ <StyledTableRow
135
+ canRowClick={!!onRowClick}
136
+ hover={!!onRowClick}
137
+ key={index}
138
+ onClick={() => {
139
+ return onRowClick && onRowClick(row)
140
+ }}
141
+ isLastRowColorChange={isLastRowColorChange}
142
+ >
143
+ {columns.map((col, colIndex) => (
144
+ <TableCell
145
+ sx={{
146
+ color: col.textColor,
147
+ padding: dense ? '10px' : '15px',
148
+ font: 'avenir',
149
+ fontSize: '14px',
150
+ borderRightColor: '#1212121A',
151
+ borderRightStyle: 'solid',
152
+ }}
153
+ key={colIndex}
154
+ >
155
+ <>
156
+ {col?.render
157
+ ? col.render(row[col.dataIndex], row, index)
158
+ : _.get(row, col.dataIndex)}
159
+ </>
160
+ </TableCell>
161
+ ))}
162
+ </StyledTableRow>
163
+ ))}
164
+ </TableBody>
165
+ ) : (
166
+ <>
167
+ <NoRecordsFound colLength={columns?.length} />
168
+ </>
169
+ )}
170
+ </>
171
+ ) : (
172
+ <Spinner />
173
+ )}
174
+ </StyledMuiTable>
175
+ </>
176
+ <>
177
+ {pagination && (
178
+ <TableFooter
179
+ page={pagination.page + 1}
180
+ limit={pagination.limit}
181
+ totalCount={pagination.totalCount ?? 0}
182
+ handlePagination={pagination.onChange}
183
+ handlePageLimit={pagination.onChangeLimit}
184
+ />
185
+ )}
186
+ </>
187
+ </StyledTableContainer>
188
+ )
189
+ }
190
+
191
+ const StyledTableContainer = styled(TableContainer)<{}>(({ theme }) => ({
192
+ width: '100%',
193
+ overflowX: 'auto',
194
+ borderRadius: '10px 10px 10px 10px',
195
+ border: '1px solid #1212121A',
196
+ }))
197
+
198
+ const StyledMuiTable = styled(MuiTable)<{}>(({ theme }) => ({
199
+ border: 'none',
200
+ }))
201
+
202
+ const StyledTableRow = styled(TableRow, {
203
+ shouldForwardProp: (prop) => prop !== 'canRowClick',
204
+ })<{ canRowClick: boolean; isLastRowColorChange?: boolean }>(
205
+ ({ canRowClick, isLastRowColorChange }) => ({
206
+ ...(canRowClick && {
207
+ cursor: 'pointer',
208
+ '&.MuiTableRow-hover:hover': {
209
+ backgroundColor: alpha('#f2f2f2', 0.4),
210
+ },
211
+ }),
212
+ ...(isLastRowColorChange && {
213
+ '&:last-child': {
214
+ backgroundColor: '#F2F2F2',
215
+ },
216
+ }),
217
+ }),
218
+ )
@@ -0,0 +1 @@
1
+ export { default } from './MobileTable'
@@ -1,24 +1,31 @@
1
1
  import { Tab } from '@mui/material'
2
2
  import { ChangeEvent, ReactNode, useEffect, useState } from 'react'
3
- import { StyledComponentWrapper, StyledContainer, StyledTabs } from './styles'
4
3
  import ErrorBoundary from '../ErrorBoundary'
4
+ import { StyledComponentWrapper, StyledContainer, StyledTabs } from './styles'
5
5
 
6
6
  export interface TabsContainerProps {
7
7
  tabs: {
8
8
  key: string
9
9
  label: string
10
10
  component: ReactNode
11
+ highlight?: boolean
11
12
  }[]
12
13
  size?: 'small' | 'medium'
13
- conatinerVariant?: 'box' | 'page'
14
+ containerVariant?: 'box' | 'page'
14
15
  onTabChange?: (tabKey: string) => void
16
+ isMobile?: boolean
17
+ tabUnderlineColor?: string
18
+ tabMobileUnderlineColor?: string
15
19
  }
16
20
 
17
21
  export default function TabsContainer({
18
22
  tabs,
19
23
  size = 'small',
20
- conatinerVariant = 'box',
24
+ containerVariant = 'box',
25
+ isMobile = false,
21
26
  onTabChange,
27
+ tabUnderlineColor,
28
+ tabMobileUnderlineColor,
22
29
  }: TabsContainerProps) {
23
30
  const [currentTab, setCurrentTab] = useState(tabs[0].key)
24
31
 
@@ -33,7 +40,7 @@ export default function TabsContainer({
33
40
  return (
34
41
  <StyledContainer>
35
42
  <StyledTabs
36
- containerVariant={conatinerVariant}
43
+ containerVariant={containerVariant}
37
44
  size={size}
38
45
  onChange={handleTabsChange}
39
46
  value={currentTab}
@@ -41,12 +48,21 @@ export default function TabsContainer({
41
48
  scrollButtons="auto"
42
49
  textColor="primary"
43
50
  indicatorColor="primary"
51
+ isMobile={isMobile}
52
+ underlineColor={tabUnderlineColor}
53
+ mobileUnderlineColor={tabMobileUnderlineColor}
44
54
  >
45
55
  {tabs.map((tab) => (
46
- <Tab key={tab.key} label={tab.label} value={tab.key} />
56
+ <Tab
57
+ key={tab.key}
58
+ label={tab.label}
59
+ value={tab.key}
60
+ icon={tab.highlight ? <span>{'.'}</span> : null}
61
+ iconPosition="end"
62
+ />
47
63
  ))}
48
64
  </StyledTabs>
49
- <StyledComponentWrapper containerVariant={conatinerVariant}>
65
+ <StyledComponentWrapper containerVariant={containerVariant}>
50
66
  <ErrorBoundary>
51
67
  {tabs.find((tab) => tab.key === currentTab)?.component}
52
68
  </ErrorBoundary>
@@ -1,39 +1,62 @@
1
1
  import { Box, Stack, styled, Tabs } from '@mui/material'
2
2
 
3
- export const StyledTabs = styled(Tabs)<{
3
+ interface StyledTabsProps {
4
4
  size: 'small' | 'medium'
5
5
  containerVariant?: 'page' | 'box'
6
- }>(({ theme, size, containerVariant }) => ({
7
- borderTopRightRadius: '10px',
8
- borderTopLeftRadius: '10px',
9
- background: theme.palette.secondary.light,
10
- minHeight: '60px',
11
- paddingLeft: '15px',
12
- '& .MuiTabs-indicator': {
13
- backgroundColor: theme.palette.common.yellow,
14
- },
15
- '& .MuiTabs-flexContainer': {
16
- height: '100%',
17
- alignItems: 'end',
18
- },
19
- '& .MuiTab-root': {
20
- textTransform: 'none',
21
- transition: 'color 0.2s ease-in-out',
22
- padding: '5px 15px',
23
- paddingBottom: '8px',
24
- minHeight: 0,
25
- fontSize: size === 'medium' ? '16px' : '14px',
26
- fontWeight: '600',
27
- },
28
- '& .MuiTab-root.Mui-selected': {
29
- color: theme.palette.secondary.main,
30
- },
31
- ...(containerVariant === 'page' && {
32
- background: 'none',
33
- paddingLeft: 0,
34
- borderBottom: theme.borders.grayLight,
6
+ isMobile?: false | true
7
+ underlineColor?: string
8
+ mobileUnderlineColor?: string
9
+ }
10
+
11
+ export const StyledTabs = styled(Tabs)<StyledTabsProps>(
12
+ ({
13
+ theme,
14
+ size,
15
+ containerVariant,
16
+ isMobile,
17
+ underlineColor,
18
+ mobileUnderlineColor,
19
+ }) => ({
20
+ borderTopRightRadius: '10px',
21
+ borderTopLeftRadius: '10px',
22
+ background: theme.palette.secondary.light,
23
+ minHeight: isMobile ? '30px' : '60px',
24
+ paddingLeft: '15px',
25
+ '& .MuiTabs-indicator': {
26
+ backgroundColor: isMobile
27
+ ? mobileUnderlineColor
28
+ : underlineColor ?? theme.palette.common.yellow,
29
+ },
30
+ '& span': {
31
+ color: theme.palette.error.main,
32
+ fontSize: '20px',
33
+ marginTop: '-20px',
34
+ marginLeft: '3px !important',
35
+ },
36
+ '& .MuiTabs-flexContainer': {
37
+ height: '100%',
38
+ alignItems: 'end',
39
+ justifyContent: isMobile ? 'center' : 'flex-start',
40
+ },
41
+ '& .MuiTab-root': {
42
+ textTransform: 'none',
43
+ transition: 'color 0.2s ease-in-out',
44
+ padding: '5px 15px',
45
+ paddingBottom: '8px',
46
+ minHeight: 0,
47
+ fontSize: size === 'medium' ? '16px' : '14px',
48
+ fontWeight: isMobile ? '500' : '600',
49
+ },
50
+ '& .MuiTab-root.Mui-selected': {
51
+ color: theme.palette.secondary.main,
52
+ },
53
+ ...(containerVariant === 'page' && {
54
+ background: 'none',
55
+ paddingLeft: 0,
56
+ borderBottom: theme.borders.grayLight,
57
+ }),
35
58
  }),
36
- }))
59
+ )
37
60
 
38
61
  export const StyledContainer = styled(Stack)(({ theme }) => ({
39
62
  borderRadius: '10px',
@@ -42,7 +42,6 @@ import UploadFileDialog from './UploadFileDialog'
42
42
  export { default as ActionButton } from './ActionButton'
43
43
  export { default as AutocompleteSearch } from './AutocompleteSearch'
44
44
  export { default as Breadcrumbs } from './Breadcrumbs'
45
- export { default as ReportPageHeader } from './ReportPageHeader'
46
45
  export { default as Card } from './Card'
47
46
  export { default as CardsGrid } from './CardsGrid'
48
47
  export { default as DividerHeading } from './DividerHeading'
@@ -56,10 +55,12 @@ export { default as NoDataIllustration } from './NoDataIllustration'
56
55
  export { PageContent } from './PageContent'
57
56
  export { default as PageHeader } from './PageHeader'
58
57
  export { default as useConfirm } from './PopupConfirm/useConfirm'
58
+ export { default as ReportPageHeader } from './ReportPageHeader'
59
59
  export { default as Spinner } from './Spinner'
60
60
  export { default as SwitchButton } from './SwitchButton'
61
61
  export { default as Table } from './Tables/BasicTable'
62
62
  export { default as TableFooter } from './Tables/BasicTable/TableFooter'
63
+ export { default as MobileTable } from './Tables/MobileTable'
63
64
  export { default as ReactTable } from './Tables/ReactTable'
64
65
  export { default as Tabs } from './Tabs/Tabs'
65
66
  export { default as ToastContainer } from './ToastContainer'
@@ -111,5 +112,5 @@ export {
111
112
  export * from './HookForm'
112
113
  export * from './IconButtons'
113
114
  export * from './Input'
114
- export * from './UploadButton/types'
115
115
  export * from './Selectors'
116
+ export * from './UploadButton/types'