@campxdev/react-blueprint 1.2.15 → 1.2.17
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/src/components/Charts/BarChart/BarChart.tsx +16 -4
- package/src/components/Charts/LineChart/LineChart.tsx +30 -2
- package/src/components/Charts/PieChart/PieChart.tsx +21 -1
- package/src/components/Charts/TreeMap/TreeMap.tsx +16 -1
- package/src/components/Charts/types/types.ts +1 -0
- package/src/components/DataDisplay/Card/Card.tsx +6 -1
- package/src/components/DataDisplay/DataTable/DataTable.tsx +1 -0
- package/src/components/DataDisplay/EditableDataTable/EditableDataTable.tsx +209 -0
- package/src/components/DataDisplay/export.ts +1 -0
- package/src/components/Input/SingleSelect/SingleSelect.tsx +55 -20
- package/src/components/Layout/AppHeader/AppHeader.tsx +10 -2
package/package.json
CHANGED
|
@@ -142,7 +142,10 @@ export const BarChart = ({
|
|
|
142
142
|
type="category"
|
|
143
143
|
dataKey={dataKey}
|
|
144
144
|
stroke={theme.palette.border.primary}
|
|
145
|
-
tick={{
|
|
145
|
+
tick={{
|
|
146
|
+
fill: theme.palette.text.tertiary,
|
|
147
|
+
...baseAxisProps?.xAxis?.tick,
|
|
148
|
+
}}
|
|
146
149
|
angle={baseAxisProps?.xAxis?.angle}
|
|
147
150
|
tickMargin={baseAxisProps?.xAxis?.tickMargin}
|
|
148
151
|
>
|
|
@@ -155,7 +158,10 @@ export const BarChart = ({
|
|
|
155
158
|
<YAxis
|
|
156
159
|
type="number"
|
|
157
160
|
stroke={theme.palette.border.primary}
|
|
158
|
-
tick={{
|
|
161
|
+
tick={{
|
|
162
|
+
fill: theme.palette.text.tertiary,
|
|
163
|
+
...baseAxisProps?.yAxis?.tick,
|
|
164
|
+
}}
|
|
159
165
|
tickMargin={baseAxisProps?.yAxis?.tickMargin}
|
|
160
166
|
domain={domain}
|
|
161
167
|
>
|
|
@@ -176,7 +182,10 @@ export const BarChart = ({
|
|
|
176
182
|
<XAxis
|
|
177
183
|
type="number"
|
|
178
184
|
stroke={theme.palette.border.primary}
|
|
179
|
-
tick={{
|
|
185
|
+
tick={{
|
|
186
|
+
fill: theme.palette.text.tertiary,
|
|
187
|
+
...baseAxisProps?.xAxis?.tick,
|
|
188
|
+
}}
|
|
180
189
|
angle={baseAxisProps?.xAxis?.angle}
|
|
181
190
|
tickMargin={baseAxisProps?.xAxis?.tickMargin}
|
|
182
191
|
>
|
|
@@ -190,7 +199,10 @@ export const BarChart = ({
|
|
|
190
199
|
dataKey={dataKey}
|
|
191
200
|
type="category"
|
|
192
201
|
stroke={theme.palette.border.primary}
|
|
193
|
-
tick={{
|
|
202
|
+
tick={{
|
|
203
|
+
fill: theme.palette.text.tertiary,
|
|
204
|
+
...baseAxisProps?.yAxis?.tick,
|
|
205
|
+
}}
|
|
194
206
|
tickMargin={baseAxisProps?.yAxis?.tickMargin}
|
|
195
207
|
>
|
|
196
208
|
{yLabel && (
|
|
@@ -12,9 +12,11 @@ import {
|
|
|
12
12
|
} from 'recharts';
|
|
13
13
|
import {
|
|
14
14
|
AxisLabelProps,
|
|
15
|
+
BaseAxisProps,
|
|
15
16
|
CartesianGridProps,
|
|
16
17
|
LegendProps,
|
|
17
18
|
MarginProps,
|
|
19
|
+
SubTitleProps,
|
|
18
20
|
TitleProps,
|
|
19
21
|
} from '../types/types';
|
|
20
22
|
import { CurveType } from 'recharts/types/shape/Curve';
|
|
@@ -22,7 +24,10 @@ import { Typography } from '../../export';
|
|
|
22
24
|
|
|
23
25
|
export type LineChartProps = {
|
|
24
26
|
title?: string;
|
|
27
|
+
showSubtitle?: boolean;
|
|
28
|
+
subTitle?: string;
|
|
25
29
|
titleProps?: TitleProps;
|
|
30
|
+
subTitleProps?: SubTitleProps;
|
|
26
31
|
width?: number;
|
|
27
32
|
height?: number;
|
|
28
33
|
dataKey: string;
|
|
@@ -32,6 +37,7 @@ export type LineChartProps = {
|
|
|
32
37
|
showLegend?: boolean;
|
|
33
38
|
cartesianGrid?: CartesianGridProps;
|
|
34
39
|
axisLabelProps?: AxisLabelProps;
|
|
40
|
+
baseAxisProps?: BaseAxisProps;
|
|
35
41
|
legendSx?: LegendProps;
|
|
36
42
|
containerSx?: SxProps;
|
|
37
43
|
margin?: MarginProps;
|
|
@@ -46,6 +52,9 @@ type LineItem = {
|
|
|
46
52
|
|
|
47
53
|
export const LineChart = ({
|
|
48
54
|
title = 'Line Chart',
|
|
55
|
+
showSubtitle = false,
|
|
56
|
+
subTitle = '',
|
|
57
|
+
subTitleProps = { variant: 'caption' },
|
|
49
58
|
titleProps = { variant: 'subtitle2' },
|
|
50
59
|
width = 700,
|
|
51
60
|
height = 500,
|
|
@@ -57,6 +66,7 @@ export const LineChart = ({
|
|
|
57
66
|
showLegend = true,
|
|
58
67
|
cartesianGrid = { showCartesianGrid: false },
|
|
59
68
|
axisLabelProps,
|
|
69
|
+
baseAxisProps,
|
|
60
70
|
legendSx,
|
|
61
71
|
containerSx,
|
|
62
72
|
}: LineChartProps) => {
|
|
@@ -73,6 +83,15 @@ export const LineChart = ({
|
|
|
73
83
|
>
|
|
74
84
|
{title}
|
|
75
85
|
</Typography>
|
|
86
|
+
{showSubtitle && (
|
|
87
|
+
<Typography
|
|
88
|
+
variant={subTitleProps.variant}
|
|
89
|
+
align={'center'}
|
|
90
|
+
sx={subTitleProps.sx}
|
|
91
|
+
>
|
|
92
|
+
{title}
|
|
93
|
+
</Typography>
|
|
94
|
+
)}
|
|
76
95
|
<ReLineChart width={width} height={height} margin={margin} data={data}>
|
|
77
96
|
{showCartesianGrid && (
|
|
78
97
|
<CartesianGrid strokeDasharray={`${size} ${size}`} />
|
|
@@ -98,7 +117,12 @@ export const LineChart = ({
|
|
|
98
117
|
type="category"
|
|
99
118
|
dataKey={dataKey}
|
|
100
119
|
stroke={theme.palette.border.primary}
|
|
101
|
-
tick={{
|
|
120
|
+
tick={{
|
|
121
|
+
fill: theme.palette.text.tertiary,
|
|
122
|
+
...baseAxisProps?.xAxis?.tick,
|
|
123
|
+
}}
|
|
124
|
+
angle={baseAxisProps?.xAxis?.angle}
|
|
125
|
+
tickMargin={baseAxisProps?.xAxis?.tickMargin}
|
|
102
126
|
>
|
|
103
127
|
<Label
|
|
104
128
|
{...xLabel}
|
|
@@ -109,7 +133,11 @@ export const LineChart = ({
|
|
|
109
133
|
<YAxis
|
|
110
134
|
type="number"
|
|
111
135
|
stroke={theme.palette.border.primary}
|
|
112
|
-
tick={{
|
|
136
|
+
tick={{
|
|
137
|
+
fill: theme.palette.text.tertiary,
|
|
138
|
+
...baseAxisProps?.yAxis?.tick,
|
|
139
|
+
}}
|
|
140
|
+
tickMargin={baseAxisProps?.yAxis?.tickMargin}
|
|
113
141
|
>
|
|
114
142
|
{yLabel && (
|
|
115
143
|
<Label
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { Stack, SxProps, useTheme } from '@mui/material';
|
|
2
2
|
import { Cell, Legend, Pie, PieChart as RePieChart, Tooltip } from 'recharts';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
LegendProps,
|
|
5
|
+
MarginProps,
|
|
6
|
+
SubTitleProps,
|
|
7
|
+
TitleProps,
|
|
8
|
+
} from '../types/types';
|
|
4
9
|
import { Typography } from '../../export';
|
|
5
10
|
|
|
6
11
|
export type PieChartProps = {
|
|
7
12
|
title?: string;
|
|
13
|
+
showSubtitle?: boolean;
|
|
14
|
+
subTitle?: string;
|
|
8
15
|
titleProps?: TitleProps;
|
|
16
|
+
subTitleProps?: SubTitleProps;
|
|
9
17
|
margin?: MarginProps;
|
|
10
18
|
width?: number;
|
|
11
19
|
height?: number;
|
|
@@ -31,6 +39,9 @@ type PieProps = {
|
|
|
31
39
|
|
|
32
40
|
export const PieChart = ({
|
|
33
41
|
title = 'Pie Chart',
|
|
42
|
+
showSubtitle = false,
|
|
43
|
+
subTitle = '',
|
|
44
|
+
subTitleProps = { variant: 'caption' },
|
|
34
45
|
titleProps = { variant: 'subtitle2' },
|
|
35
46
|
margin,
|
|
36
47
|
width = 500,
|
|
@@ -53,6 +64,15 @@ export const PieChart = ({
|
|
|
53
64
|
>
|
|
54
65
|
{title}
|
|
55
66
|
</Typography>
|
|
67
|
+
{showSubtitle && (
|
|
68
|
+
<Typography
|
|
69
|
+
variant={subTitleProps.variant}
|
|
70
|
+
align={'center'}
|
|
71
|
+
sx={subTitleProps.sx}
|
|
72
|
+
>
|
|
73
|
+
{title}
|
|
74
|
+
</Typography>
|
|
75
|
+
)}
|
|
56
76
|
<RePieChart width={width} height={height} margin={margin}>
|
|
57
77
|
{showToolTip && (
|
|
58
78
|
<Tooltip
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { Box, Stack, styled, SxProps, useTheme } from '@mui/material';
|
|
2
2
|
import { Treemap as ReTreeMap, Tooltip } from 'recharts';
|
|
3
3
|
import { AnimationTiming } from 'recharts/types/util/types';
|
|
4
|
-
import { MarginProps, TitleProps } from '../types/types';
|
|
4
|
+
import { MarginProps, SubTitleProps, TitleProps } from '../types/types';
|
|
5
5
|
import { Typography } from '../../export';
|
|
6
6
|
|
|
7
7
|
interface TreeMapProps {
|
|
8
8
|
title?: string;
|
|
9
|
+
showSubtitle?: boolean;
|
|
10
|
+
subTitle?: string;
|
|
9
11
|
titleProps?: TitleProps;
|
|
12
|
+
subTitleProps?: SubTitleProps;
|
|
10
13
|
data: any;
|
|
11
14
|
dataKey: string | number;
|
|
12
15
|
width?: number;
|
|
@@ -26,6 +29,9 @@ interface TreeMapProps {
|
|
|
26
29
|
const TreeMap = ({
|
|
27
30
|
title = 'Tree Map',
|
|
28
31
|
titleProps = { variant: 'subtitle2' },
|
|
32
|
+
showSubtitle = false,
|
|
33
|
+
subTitle = '',
|
|
34
|
+
subTitleProps = { variant: 'caption' },
|
|
29
35
|
data,
|
|
30
36
|
dataKey,
|
|
31
37
|
width = 400,
|
|
@@ -49,6 +55,15 @@ const TreeMap = ({
|
|
|
49
55
|
>
|
|
50
56
|
{title}
|
|
51
57
|
</Typography>
|
|
58
|
+
{showSubtitle && (
|
|
59
|
+
<Typography
|
|
60
|
+
variant={subTitleProps.variant}
|
|
61
|
+
align={'center'}
|
|
62
|
+
sx={subTitleProps.sx}
|
|
63
|
+
>
|
|
64
|
+
{title}
|
|
65
|
+
</Typography>
|
|
66
|
+
)}
|
|
52
67
|
<ReTreeMap
|
|
53
68
|
data={data}
|
|
54
69
|
dataKey={dataKey}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from '@mui/material';
|
|
10
10
|
import { Variant } from '@mui/material/styles/createTypography';
|
|
11
11
|
import { ReactNode } from 'react';
|
|
12
|
-
import { DropDownIcon, DropdownMenu } from '../../export';
|
|
12
|
+
import { DropDownIcon, DropdownMenu, Switch, SwitchProps } from '../../export';
|
|
13
13
|
import {
|
|
14
14
|
StyledButton,
|
|
15
15
|
StyledCardActions,
|
|
@@ -46,6 +46,8 @@ export interface CardProps {
|
|
|
46
46
|
imageSrc?: string;
|
|
47
47
|
titleImgIcon?: ReactNode;
|
|
48
48
|
checkBox?: boolean;
|
|
49
|
+
hasSwitch?: boolean;
|
|
50
|
+
switchProps?: SwitchProps;
|
|
49
51
|
moreOptions?: boolean;
|
|
50
52
|
menu?: Array<ReactNode>;
|
|
51
53
|
icon?: ReactNode;
|
|
@@ -76,6 +78,8 @@ export const Card = ({
|
|
|
76
78
|
icon,
|
|
77
79
|
children,
|
|
78
80
|
menu = [],
|
|
81
|
+
switchProps,
|
|
82
|
+
hasSwitch,
|
|
79
83
|
}: CardProps) => {
|
|
80
84
|
const handleClick = (e: any) => {
|
|
81
85
|
footer?.onClick();
|
|
@@ -106,6 +110,7 @@ export const Card = ({
|
|
|
106
110
|
</Stack>
|
|
107
111
|
</Stack>
|
|
108
112
|
<Stack flexDirection={'row'} gap={'12px'} alignItems={'center'}>
|
|
113
|
+
{hasSwitch && <Switch {...switchProps} />}
|
|
109
114
|
{status && (
|
|
110
115
|
<StyledStatusText variant="label2" sx={statusSx}>
|
|
111
116
|
{status}{' '}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { Button } from '@mui/material';
|
|
2
|
+
import {
|
|
3
|
+
GridActionsCellItem,
|
|
4
|
+
GridColDef,
|
|
5
|
+
GridEventListener,
|
|
6
|
+
GridRowEditStopReasons,
|
|
7
|
+
GridRowModel,
|
|
8
|
+
GridRowModes,
|
|
9
|
+
GridRowModesModel,
|
|
10
|
+
GridRowParams,
|
|
11
|
+
GridToolbarContainer,
|
|
12
|
+
GridValidRowModel,
|
|
13
|
+
} from '@mui/x-data-grid';
|
|
14
|
+
import { useEffect, useRef, useState } from 'react';
|
|
15
|
+
import { v4 } from 'uuid';
|
|
16
|
+
import { DataTable, DataTableProps, Icons } from '../../export';
|
|
17
|
+
|
|
18
|
+
export type EditableDataTableProps = {
|
|
19
|
+
limit?: number;
|
|
20
|
+
offset?: number;
|
|
21
|
+
totalCount?: number;
|
|
22
|
+
hideDelete?: boolean;
|
|
23
|
+
onPageChange?: (page: number) => void;
|
|
24
|
+
onLimitChange?: (limit: number) => void;
|
|
25
|
+
onChange: (rows: GridValidRowModel) => void;
|
|
26
|
+
onSave?: (params: any) => void;
|
|
27
|
+
onDelete?: (params: any) => void;
|
|
28
|
+
} & Omit<
|
|
29
|
+
DataTableProps,
|
|
30
|
+
| 'rowModesModel'
|
|
31
|
+
| 'onRowModesModelChange'
|
|
32
|
+
| 'onRowEditStop'
|
|
33
|
+
| 'processRowUpdate'
|
|
34
|
+
>;
|
|
35
|
+
|
|
36
|
+
export const EditableDataTable = (props: EditableDataTableProps) => {
|
|
37
|
+
const { rows } = props;
|
|
38
|
+
|
|
39
|
+
useEffect(() => {}, [props.columns]);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<EditableTableCore
|
|
43
|
+
{...props}
|
|
44
|
+
rows={rows?.map((row) => (row.id ? row : { id: v4(), ...row }))}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const EditableTableCore = (props: EditableDataTableProps) => {
|
|
50
|
+
const { rows, columns } = props;
|
|
51
|
+
const [rowModesModel, setRowModesModel] = useState<GridRowModesModel>({});
|
|
52
|
+
const processRowUpdate = (newRow: GridRowModel) => {
|
|
53
|
+
const updatedRow = { ...newRow, isNew: false };
|
|
54
|
+
props.onSave && props.onSave(newRow);
|
|
55
|
+
props.onChange(
|
|
56
|
+
rows?.map((row) => (row.id === newRow.id ? updatedRow : row)) ?? [],
|
|
57
|
+
);
|
|
58
|
+
return updatedRow;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleRowEditStop: GridEventListener<'rowEditStop'> = (
|
|
62
|
+
params,
|
|
63
|
+
event,
|
|
64
|
+
) => {
|
|
65
|
+
if (params.reason === GridRowEditStopReasons.rowFocusOut) {
|
|
66
|
+
event.defaultMuiPrevented = true;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => {
|
|
71
|
+
setRowModesModel(newRowModesModel);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const handleEditClick = (params: GridRowParams) => {
|
|
75
|
+
setRowModesModel({
|
|
76
|
+
...rowModesModel,
|
|
77
|
+
[params.id]: { mode: GridRowModes.Edit },
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const handleSaveClick = (params: GridRowParams) => {
|
|
82
|
+
setRowModesModel({
|
|
83
|
+
...rowModesModel,
|
|
84
|
+
[params.id]: { mode: GridRowModes.View },
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const handleDeleteClick = (params: GridRowParams) => {
|
|
89
|
+
props.onDelete && props.onDelete(params);
|
|
90
|
+
props.onChange(rows?.filter((row) => row.id !== params.id) ?? []);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<>
|
|
95
|
+
<DataTable
|
|
96
|
+
editMode="row"
|
|
97
|
+
onRowModesModelChange={handleRowModesModelChange}
|
|
98
|
+
onRowEditStop={handleRowEditStop}
|
|
99
|
+
processRowUpdate={processRowUpdate}
|
|
100
|
+
rowModesModel={rowModesModel}
|
|
101
|
+
{...props}
|
|
102
|
+
rows={rows}
|
|
103
|
+
columns={[
|
|
104
|
+
...columns,
|
|
105
|
+
{
|
|
106
|
+
field: 'actions',
|
|
107
|
+
type: 'actions',
|
|
108
|
+
headerName: 'Actions',
|
|
109
|
+
width: 150,
|
|
110
|
+
cellClassName: 'actions',
|
|
111
|
+
getActions: (params) => {
|
|
112
|
+
if (rowModesModel[params.id]?.mode === GridRowModes.Edit) {
|
|
113
|
+
return props.hideDelete
|
|
114
|
+
? [
|
|
115
|
+
<GridActionsCellItem
|
|
116
|
+
icon={<Icons.SaveIcon />}
|
|
117
|
+
label="Save"
|
|
118
|
+
onClick={() => handleSaveClick(params)}
|
|
119
|
+
/>,
|
|
120
|
+
]
|
|
121
|
+
: [
|
|
122
|
+
<GridActionsCellItem
|
|
123
|
+
icon={<Icons.SaveIcon />}
|
|
124
|
+
label="Save"
|
|
125
|
+
onClick={() => handleSaveClick(params)}
|
|
126
|
+
/>,
|
|
127
|
+
<GridActionsCellItem
|
|
128
|
+
icon={<Icons.DeleteIcon />}
|
|
129
|
+
label="Cancel"
|
|
130
|
+
onClick={() => handleDeleteClick(params)}
|
|
131
|
+
color="inherit"
|
|
132
|
+
/>,
|
|
133
|
+
];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return props.hideDelete
|
|
137
|
+
? [
|
|
138
|
+
<GridActionsCellItem
|
|
139
|
+
icon={<Icons.EditIcon />}
|
|
140
|
+
label="Edit"
|
|
141
|
+
onClick={() => handleEditClick(params)}
|
|
142
|
+
color="inherit"
|
|
143
|
+
/>,
|
|
144
|
+
]
|
|
145
|
+
: [
|
|
146
|
+
<GridActionsCellItem
|
|
147
|
+
icon={<Icons.EditIcon />}
|
|
148
|
+
label="Edit"
|
|
149
|
+
onClick={() => handleEditClick(params)}
|
|
150
|
+
color="inherit"
|
|
151
|
+
/>,
|
|
152
|
+
<GridActionsCellItem
|
|
153
|
+
icon={<Icons.DeleteIcon />}
|
|
154
|
+
label="Delete"
|
|
155
|
+
onClick={() => handleDeleteClick(params)}
|
|
156
|
+
color="inherit"
|
|
157
|
+
/>,
|
|
158
|
+
];
|
|
159
|
+
},
|
|
160
|
+
} as GridColDef,
|
|
161
|
+
]}
|
|
162
|
+
slots={{
|
|
163
|
+
footer: (footerProps) => (
|
|
164
|
+
<EditFooter
|
|
165
|
+
fields={props.columns.map((column) => column.field)}
|
|
166
|
+
setRows={props.onChange}
|
|
167
|
+
setRowModesModel={setRowModesModel}
|
|
168
|
+
/>
|
|
169
|
+
),
|
|
170
|
+
}}
|
|
171
|
+
/>
|
|
172
|
+
</>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
interface EditFooterProps {
|
|
177
|
+
setRows: (
|
|
178
|
+
newRows: (oldRows: GridValidRowModel[]) => GridValidRowModel[],
|
|
179
|
+
) => void;
|
|
180
|
+
setRowModesModel: (
|
|
181
|
+
newModel: (oldModel: GridRowModesModel) => GridRowModesModel,
|
|
182
|
+
) => void;
|
|
183
|
+
fields: string[];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const EditFooter = (props: EditFooterProps) => {
|
|
187
|
+
const { setRows, setRowModesModel, fields } = props;
|
|
188
|
+
const id = useRef(v4()).current;
|
|
189
|
+
const handleClick = () => {
|
|
190
|
+
setRows((oldRows) => [
|
|
191
|
+
...oldRows,
|
|
192
|
+
{
|
|
193
|
+
id,
|
|
194
|
+
isNew: true,
|
|
195
|
+
...Object.fromEntries(fields.map((field) => [field, ''])),
|
|
196
|
+
},
|
|
197
|
+
]);
|
|
198
|
+
setRowModesModel((oldModel) => ({
|
|
199
|
+
...oldModel,
|
|
200
|
+
[id]: { mode: GridRowModes.Edit, fieldToFocus: 'name' },
|
|
201
|
+
}));
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<GridToolbarContainer sx={{ margin: '10px 0px' }}>
|
|
206
|
+
<Button onClick={handleClick}>+ Add Row</Button>
|
|
207
|
+
</GridToolbarContainer>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
@@ -3,5 +3,6 @@ export * from './Avatar/Avatar';
|
|
|
3
3
|
export * from './Card/Card';
|
|
4
4
|
export * from './Chips/Chips';
|
|
5
5
|
export * from './DataTable/DataTable';
|
|
6
|
+
export * from './EditableDataTable/EditableDataTable';
|
|
6
7
|
export * from './SidePanel/SidePanel';
|
|
7
8
|
export * from './Typography/Typography';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { axios as campxAxios } from '@campxdev/campx-web-utils';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
AutocompleteCloseReason,
|
|
4
|
+
AutocompleteProps,
|
|
4
5
|
Box,
|
|
5
6
|
Autocomplete as MuiAutocomplete,
|
|
6
7
|
Paper,
|
|
@@ -8,7 +9,7 @@ import {
|
|
|
8
9
|
} from '@mui/material';
|
|
9
10
|
import axios from 'axios';
|
|
10
11
|
import _ from 'lodash';
|
|
11
|
-
import { useEffect, useReducer } from 'react';
|
|
12
|
+
import { SyntheticEvent, useEffect, useReducer } from 'react';
|
|
12
13
|
import { Typography } from '../../DataDisplay/Typography/Typography';
|
|
13
14
|
import { Spinner } from '../../Feedback/Spinner/Spinner';
|
|
14
15
|
import { TextField } from '../TextField/TextField';
|
|
@@ -26,16 +27,31 @@ function sleep(duration: number): Promise<void> {
|
|
|
26
27
|
export type SingleSelectProps = {
|
|
27
28
|
options?: { label: string; subLabel?: string; value: any }[] | any[];
|
|
28
29
|
optionsApiEndPoint?: string;
|
|
30
|
+
optionsApiEndpointParams?: any;
|
|
29
31
|
useCampxAxios?: boolean;
|
|
30
32
|
required?: boolean;
|
|
31
33
|
label?: string;
|
|
32
34
|
name?: string;
|
|
33
|
-
value?: any;
|
|
34
35
|
getValue?: (option: any) => any;
|
|
35
36
|
onChange: (value: any) => void;
|
|
36
37
|
error?: any;
|
|
37
38
|
helperText?: string;
|
|
38
|
-
} &
|
|
39
|
+
} & Omit<
|
|
40
|
+
AutocompleteProps<
|
|
41
|
+
{ label: string; subLabel?: string; value: any } | any,
|
|
42
|
+
false,
|
|
43
|
+
false,
|
|
44
|
+
false
|
|
45
|
+
>,
|
|
46
|
+
| 'options'
|
|
47
|
+
| 'open'
|
|
48
|
+
| 'onChange'
|
|
49
|
+
| 'autoFocus'
|
|
50
|
+
| 'PaperComponent'
|
|
51
|
+
| 'renderOption'
|
|
52
|
+
| 'options'
|
|
53
|
+
| 'renderInput'
|
|
54
|
+
>;
|
|
39
55
|
|
|
40
56
|
const CustomPaper = (props: PaperProps) => (
|
|
41
57
|
<Paper
|
|
@@ -126,6 +142,7 @@ const singleSelectReducer = (
|
|
|
126
142
|
export const SingleSelect = ({
|
|
127
143
|
options,
|
|
128
144
|
optionsApiEndPoint,
|
|
145
|
+
optionsApiEndpointParams,
|
|
129
146
|
useCampxAxios = true,
|
|
130
147
|
required = false,
|
|
131
148
|
label,
|
|
@@ -135,6 +152,8 @@ export const SingleSelect = ({
|
|
|
135
152
|
onChange,
|
|
136
153
|
error,
|
|
137
154
|
helperText,
|
|
155
|
+
onOpen,
|
|
156
|
+
onClose,
|
|
138
157
|
...restProps
|
|
139
158
|
}: SingleSelectProps) => {
|
|
140
159
|
const generateOptionsMap = (options: any[]) => {
|
|
@@ -163,7 +182,7 @@ export const SingleSelect = ({
|
|
|
163
182
|
|
|
164
183
|
const internalAxios = useCampxAxios ? campxAxios : axios;
|
|
165
184
|
|
|
166
|
-
const handleOpen = async () => {
|
|
185
|
+
const handleOpen = async (event: SyntheticEvent) => {
|
|
167
186
|
dispatch({
|
|
168
187
|
actionType: SingleSelectActionsTypes.OPEN,
|
|
169
188
|
});
|
|
@@ -177,6 +196,7 @@ export const SingleSelect = ({
|
|
|
177
196
|
params: {
|
|
178
197
|
limit,
|
|
179
198
|
offset,
|
|
199
|
+
...optionsApiEndpointParams,
|
|
180
200
|
},
|
|
181
201
|
})
|
|
182
202
|
.then((res) => res.data);
|
|
@@ -200,6 +220,21 @@ export const SingleSelect = ({
|
|
|
200
220
|
});
|
|
201
221
|
}
|
|
202
222
|
}
|
|
223
|
+
if (onOpen) {
|
|
224
|
+
onOpen(event);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const handleClose = (
|
|
229
|
+
event: SyntheticEvent,
|
|
230
|
+
reason: AutocompleteCloseReason,
|
|
231
|
+
) => {
|
|
232
|
+
dispatch({
|
|
233
|
+
actionType: SingleSelectActionsTypes.CLOSE,
|
|
234
|
+
});
|
|
235
|
+
if (onClose) {
|
|
236
|
+
onClose(event, reason);
|
|
237
|
+
}
|
|
203
238
|
};
|
|
204
239
|
|
|
205
240
|
const handleScroll = async (event: any) => {
|
|
@@ -288,22 +323,13 @@ export const SingleSelect = ({
|
|
|
288
323
|
}
|
|
289
324
|
return (
|
|
290
325
|
<MuiAutocomplete
|
|
326
|
+
{...restProps}
|
|
291
327
|
onChange={(e, value) => {
|
|
292
328
|
onChange(getValue ? getValue(value) : value?.value);
|
|
293
329
|
}}
|
|
294
330
|
open={open}
|
|
295
331
|
autoFocus={true}
|
|
296
332
|
value={state.internalOptionsMap[value]}
|
|
297
|
-
renderInput={(params) => (
|
|
298
|
-
<TextField
|
|
299
|
-
{...params}
|
|
300
|
-
label={label}
|
|
301
|
-
required={required}
|
|
302
|
-
name={name}
|
|
303
|
-
error={error}
|
|
304
|
-
helperText={helperText}
|
|
305
|
-
/>
|
|
306
|
-
)}
|
|
307
333
|
PaperComponent={CustomPaper}
|
|
308
334
|
renderOption={(props, option: any) => {
|
|
309
335
|
return (
|
|
@@ -316,20 +342,29 @@ export const SingleSelect = ({
|
|
|
316
342
|
);
|
|
317
343
|
}}
|
|
318
344
|
ListboxProps={{
|
|
345
|
+
...restProps.ListboxProps,
|
|
319
346
|
onScroll: handleScroll,
|
|
320
347
|
}}
|
|
321
348
|
slotProps={{
|
|
349
|
+
...restProps.slotProps,
|
|
322
350
|
paper: {
|
|
351
|
+
...restProps.slotProps?.paper,
|
|
323
352
|
square: loadingInternalOptions,
|
|
324
353
|
},
|
|
325
354
|
}}
|
|
326
355
|
onOpen={handleOpen}
|
|
327
|
-
onClose={
|
|
328
|
-
dispatch({
|
|
329
|
-
actionType: SingleSelectActionsTypes.CLOSE,
|
|
330
|
-
});
|
|
331
|
-
}}
|
|
356
|
+
onClose={handleClose}
|
|
332
357
|
options={internalOptions}
|
|
358
|
+
renderInput={(params) => (
|
|
359
|
+
<TextField
|
|
360
|
+
{...params}
|
|
361
|
+
label={label}
|
|
362
|
+
required={required}
|
|
363
|
+
name={name}
|
|
364
|
+
error={error}
|
|
365
|
+
helperText={helperText}
|
|
366
|
+
/>
|
|
367
|
+
)}
|
|
333
368
|
/>
|
|
334
369
|
);
|
|
335
370
|
};
|
|
@@ -4,6 +4,8 @@ import { Typography } from '../../DataDisplay/Typography/Typography';
|
|
|
4
4
|
import { Button } from '../../export';
|
|
5
5
|
import UserBox from './AppHeaderActions/UserBox';
|
|
6
6
|
import { StyledHeader } from './styles/styles';
|
|
7
|
+
import { StyledIconButton } from '../../Navigation/DropDownMenu/styles';
|
|
8
|
+
import { HelpIcon } from '../../Assets/Icons/IconComponents/HelpIcon';
|
|
7
9
|
|
|
8
10
|
export interface AppHeaderProps {
|
|
9
11
|
actions?: ReactNode[];
|
|
@@ -35,10 +37,10 @@ export const AppHeader = ({
|
|
|
35
37
|
<Stack alignItems={'center'} gap={'12px'} flexDirection={'row'}>
|
|
36
38
|
{/* <StyledIconButton>
|
|
37
39
|
<a
|
|
38
|
-
href={
|
|
40
|
+
href={'https://helpdesk.campx.in/helpdesk/my-tickets'}
|
|
39
41
|
target="_blank"
|
|
40
42
|
rel="noreferrer"
|
|
41
|
-
style={{ textDecoration:
|
|
43
|
+
style={{ textDecoration: 'none' }}
|
|
42
44
|
>
|
|
43
45
|
<HelpIcon size={20} />
|
|
44
46
|
</a>
|
|
@@ -47,6 +49,12 @@ export const AppHeader = ({
|
|
|
47
49
|
variant="outlined"
|
|
48
50
|
id="jiraIssueCollector"
|
|
49
51
|
className="reportAnIssue"
|
|
52
|
+
onClick={() => {
|
|
53
|
+
window.open(
|
|
54
|
+
'https://helpdesk.campx.in/helpdesk/my-tickets',
|
|
55
|
+
'_blank',
|
|
56
|
+
);
|
|
57
|
+
}}
|
|
50
58
|
>
|
|
51
59
|
<Typography
|
|
52
60
|
variant="button"
|