goobs-frontend 0.8.19 → 0.8.20
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 +3 -3
- package/src/components/DataGrid/ManageRow/index.tsx +198 -227
- package/src/components/DataGrid/Table/ColumnHeaderRow/index.tsx +115 -75
- package/src/components/DataGrid/Table/Rows/index.tsx +41 -33
- package/src/components/DataGrid/Table/index.tsx +85 -198
- package/src/components/DataGrid/index.tsx +7 -47
- package/src/components/DataGrid/types/index.ts +10 -118
- package/src/components/Dropdown/index.tsx +84 -222
- package/src/components/Form/DataGrid/index.tsx +0 -4
- package/src/components/Nav/index.tsx +10 -19
- package/src/components/SearchableDropdown/index.tsx +18 -21
- package/src/components/TextField/index.tsx +18 -3
- package/src/components/Toolbar/index.tsx +21 -229
- package/src/components/Toolbar/left/index.tsx +193 -0
- package/src/components/Toolbar/right/index.tsx +82 -0
- package/src/index.ts +24 -23
- package/src/components/DataGrid/utils/useSelectColumn.tsx +0 -37
- package/src/components/Icons/DownArrowFilled.tsx +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goobs-frontend",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A comprehensive React-based UI library built on Material-UI, offering a wide range of customizable components including grids, typography, buttons, cards, forms, navigation, pricing tables, steppers, tooltips, accordions, and more. Designed for building responsive and consistent user interfaces with advanced features like form validation, theming, and code syntax highlighting.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"highlight.js": "^11.11.1",
|
|
30
30
|
"jotai": "^2.11.0",
|
|
31
31
|
"lodash": "^4.17.21",
|
|
32
|
-
"next": "15.1.
|
|
32
|
+
"next": "15.1.4",
|
|
33
33
|
"otplib": "^12.0.1",
|
|
34
34
|
"react-datepicker": "^7.6.0",
|
|
35
35
|
"react-qr-code": "^2.0.15",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
49
49
|
"@typescript-eslint/parser": "^8.19.1",
|
|
50
50
|
"eslint": "^9.17.0",
|
|
51
|
-
"eslint-config-next": "^15.1.
|
|
51
|
+
"eslint-config-next": "^15.1.4",
|
|
52
52
|
"eslint-config-prettier": "^9.1.0",
|
|
53
53
|
"eslint-plugin-prettier": "^5.2.1",
|
|
54
54
|
"prettier": "^3.4.2",
|
|
@@ -32,22 +32,9 @@ function ManageRow({
|
|
|
32
32
|
onShow,
|
|
33
33
|
onExport,
|
|
34
34
|
}: ManageRowProps) {
|
|
35
|
-
// Determine if we're on a small screen (mobile)
|
|
36
35
|
const isMobile = useMediaQuery('(max-width:600px)')
|
|
37
36
|
|
|
38
|
-
console.log('ManageRow rendered with props:', {
|
|
39
|
-
selectedRowsCount: selectedRows.length,
|
|
40
|
-
selectedRows,
|
|
41
|
-
hasManageHandler: !!onManage,
|
|
42
|
-
})
|
|
43
|
-
|
|
44
37
|
const handleActionSelection = (type: ModalType) => {
|
|
45
|
-
console.log('Action selected:', type, {
|
|
46
|
-
selectedRows,
|
|
47
|
-
hasManageHandler: !!onManage,
|
|
48
|
-
timestamp: new Date().toISOString(),
|
|
49
|
-
})
|
|
50
|
-
|
|
51
38
|
switch (type) {
|
|
52
39
|
case 'duplicate':
|
|
53
40
|
onDuplicate?.()
|
|
@@ -67,15 +54,8 @@ function ManageRow({
|
|
|
67
54
|
break
|
|
68
55
|
case 'manage':
|
|
69
56
|
if (selectedRows.length === 1 && onManage) {
|
|
70
|
-
console.log('Triggering manage with selection:', selectedRows[0])
|
|
71
57
|
onManage()
|
|
72
|
-
// Don't call handleClose for manage
|
|
73
58
|
return
|
|
74
|
-
} else {
|
|
75
|
-
console.warn('Invalid manage state:', {
|
|
76
|
-
selectedRows,
|
|
77
|
-
hasManageHandler: !!onManage,
|
|
78
|
-
})
|
|
79
59
|
}
|
|
80
60
|
break
|
|
81
61
|
case 'show':
|
|
@@ -86,9 +66,8 @@ function ManageRow({
|
|
|
86
66
|
}
|
|
87
67
|
|
|
88
68
|
const handleExport = () => {
|
|
89
|
-
console.log('Exporting data for rows:', selectedRows)
|
|
90
69
|
const selectedData = rows.filter(row =>
|
|
91
|
-
selectedRows.includes(row.id as string)
|
|
70
|
+
selectedRows.includes((row.id ?? row._id) as string)
|
|
92
71
|
)
|
|
93
72
|
const csvContent = selectedData
|
|
94
73
|
.map(row => Object.values(row).join(','))
|
|
@@ -107,209 +86,6 @@ function ManageRow({
|
|
|
107
86
|
}
|
|
108
87
|
}
|
|
109
88
|
|
|
110
|
-
// Build the action buttons
|
|
111
|
-
const actionButtons = (
|
|
112
|
-
<Stack
|
|
113
|
-
component="div"
|
|
114
|
-
spacing={0}
|
|
115
|
-
direction="row"
|
|
116
|
-
justifyContent="center"
|
|
117
|
-
sx={{ '& > div:not(:last-child)': { marginRight: '2px' } }}
|
|
118
|
-
>
|
|
119
|
-
{/* First group: Manage, Show (only if exactly 1 item selected) */}
|
|
120
|
-
{(onManage || onShow) && selectedRows.length === 1 && (
|
|
121
|
-
<Box
|
|
122
|
-
display="flex"
|
|
123
|
-
flexDirection="row"
|
|
124
|
-
alignItems="center"
|
|
125
|
-
sx={{
|
|
126
|
-
borderRight: '1px solid #e0e0e0',
|
|
127
|
-
paddingRight: '8px',
|
|
128
|
-
marginRight: '8px',
|
|
129
|
-
}}
|
|
130
|
-
>
|
|
131
|
-
{onManage && (
|
|
132
|
-
<Box
|
|
133
|
-
onClick={e => {
|
|
134
|
-
e.stopPropagation()
|
|
135
|
-
handleActionSelection('manage')
|
|
136
|
-
}}
|
|
137
|
-
display="flex"
|
|
138
|
-
flexDirection="column"
|
|
139
|
-
alignItems="center"
|
|
140
|
-
sx={{
|
|
141
|
-
padding: '8px',
|
|
142
|
-
cursor: 'pointer',
|
|
143
|
-
'&:hover': {
|
|
144
|
-
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
145
|
-
},
|
|
146
|
-
borderRadius: '4px',
|
|
147
|
-
transition: 'background-color 0.2s',
|
|
148
|
-
userSelect: 'none',
|
|
149
|
-
}}
|
|
150
|
-
>
|
|
151
|
-
<Box
|
|
152
|
-
sx={{
|
|
153
|
-
display: 'flex',
|
|
154
|
-
flexDirection: 'column',
|
|
155
|
-
alignItems: 'center',
|
|
156
|
-
color: 'black',
|
|
157
|
-
}}
|
|
158
|
-
>
|
|
159
|
-
<EditIcon />
|
|
160
|
-
<Typography fontvariant="merriparagraph" text="Manage" />
|
|
161
|
-
</Box>
|
|
162
|
-
</Box>
|
|
163
|
-
)}
|
|
164
|
-
{onShow && (
|
|
165
|
-
<Box
|
|
166
|
-
onClick={e => {
|
|
167
|
-
e.stopPropagation()
|
|
168
|
-
handleActionSelection('show')
|
|
169
|
-
}}
|
|
170
|
-
display="flex"
|
|
171
|
-
flexDirection="column"
|
|
172
|
-
alignItems="center"
|
|
173
|
-
sx={{
|
|
174
|
-
padding: '8px',
|
|
175
|
-
cursor: 'pointer',
|
|
176
|
-
'&:hover': {
|
|
177
|
-
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
178
|
-
},
|
|
179
|
-
borderRadius: '4px',
|
|
180
|
-
transition: 'background-color 0.2s',
|
|
181
|
-
userSelect: 'none',
|
|
182
|
-
}}
|
|
183
|
-
>
|
|
184
|
-
<Box
|
|
185
|
-
sx={{
|
|
186
|
-
display: 'flex',
|
|
187
|
-
flexDirection: 'column',
|
|
188
|
-
alignItems: 'center',
|
|
189
|
-
color: 'black',
|
|
190
|
-
}}
|
|
191
|
-
>
|
|
192
|
-
<VisibilityIcon />
|
|
193
|
-
<Typography fontvariant="merriparagraph" text="Show" />
|
|
194
|
-
</Box>
|
|
195
|
-
</Box>
|
|
196
|
-
)}
|
|
197
|
-
</Box>
|
|
198
|
-
)}
|
|
199
|
-
|
|
200
|
-
{/* Second group: Duplicate, Delete, Export */}
|
|
201
|
-
{selectedRows.length > 0 && (
|
|
202
|
-
<Box display="flex" flexDirection="row" alignItems="center">
|
|
203
|
-
{/* If not on mobile, show "Duplicate" */}
|
|
204
|
-
{!isMobile && onDuplicate && (
|
|
205
|
-
<Box
|
|
206
|
-
onClick={e => {
|
|
207
|
-
e.stopPropagation()
|
|
208
|
-
handleActionSelection('duplicate')
|
|
209
|
-
}}
|
|
210
|
-
display="flex"
|
|
211
|
-
flexDirection="column"
|
|
212
|
-
alignItems="center"
|
|
213
|
-
sx={{
|
|
214
|
-
padding: '8px',
|
|
215
|
-
cursor: 'pointer',
|
|
216
|
-
'&:hover': {
|
|
217
|
-
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
218
|
-
},
|
|
219
|
-
borderRadius: '4px',
|
|
220
|
-
transition: 'background-color 0.2s',
|
|
221
|
-
userSelect: 'none',
|
|
222
|
-
}}
|
|
223
|
-
>
|
|
224
|
-
<Box
|
|
225
|
-
sx={{
|
|
226
|
-
display: 'flex',
|
|
227
|
-
flexDirection: 'column',
|
|
228
|
-
alignItems: 'center',
|
|
229
|
-
color: 'black',
|
|
230
|
-
}}
|
|
231
|
-
>
|
|
232
|
-
<DuplicateIcon />
|
|
233
|
-
<Typography fontvariant="merriparagraph" text="Duplicate" />
|
|
234
|
-
</Box>
|
|
235
|
-
</Box>
|
|
236
|
-
)}
|
|
237
|
-
|
|
238
|
-
{/* Always show "Delete" if provided */}
|
|
239
|
-
{onDelete && (
|
|
240
|
-
<Box
|
|
241
|
-
onClick={e => {
|
|
242
|
-
e.stopPropagation()
|
|
243
|
-
handleActionSelection('delete')
|
|
244
|
-
}}
|
|
245
|
-
display="flex"
|
|
246
|
-
flexDirection="column"
|
|
247
|
-
alignItems="center"
|
|
248
|
-
sx={{
|
|
249
|
-
padding: '8px',
|
|
250
|
-
cursor: 'pointer',
|
|
251
|
-
'&:hover': {
|
|
252
|
-
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
253
|
-
},
|
|
254
|
-
borderRadius: '4px',
|
|
255
|
-
transition: 'background-color 0.2s',
|
|
256
|
-
userSelect: 'none',
|
|
257
|
-
}}
|
|
258
|
-
>
|
|
259
|
-
<Box
|
|
260
|
-
sx={{
|
|
261
|
-
display: 'flex',
|
|
262
|
-
flexDirection: 'column',
|
|
263
|
-
alignItems: 'center',
|
|
264
|
-
color: 'black',
|
|
265
|
-
}}
|
|
266
|
-
>
|
|
267
|
-
<DeleteIcon />
|
|
268
|
-
<Typography fontvariant="merriparagraph" text="Delete" />
|
|
269
|
-
</Box>
|
|
270
|
-
</Box>
|
|
271
|
-
)}
|
|
272
|
-
|
|
273
|
-
{/* If not on mobile, show "Export" */}
|
|
274
|
-
{!isMobile && (onExport || rows.length > 0) && (
|
|
275
|
-
<Box
|
|
276
|
-
onClick={e => {
|
|
277
|
-
e.stopPropagation()
|
|
278
|
-
handleActionSelection('export')
|
|
279
|
-
}}
|
|
280
|
-
display="flex"
|
|
281
|
-
flexDirection="column"
|
|
282
|
-
alignItems="center"
|
|
283
|
-
sx={{
|
|
284
|
-
padding: '8px',
|
|
285
|
-
cursor: 'pointer',
|
|
286
|
-
'&:hover': {
|
|
287
|
-
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
288
|
-
},
|
|
289
|
-
borderRadius: '4px',
|
|
290
|
-
transition: 'background-color 0.2s',
|
|
291
|
-
userSelect: 'none',
|
|
292
|
-
}}
|
|
293
|
-
>
|
|
294
|
-
<Box
|
|
295
|
-
sx={{
|
|
296
|
-
display: 'flex',
|
|
297
|
-
flexDirection: 'column',
|
|
298
|
-
alignItems: 'center',
|
|
299
|
-
color: 'black',
|
|
300
|
-
}}
|
|
301
|
-
>
|
|
302
|
-
<ExportIcon />
|
|
303
|
-
<Typography fontvariant="merriparagraph" text="Export" />
|
|
304
|
-
</Box>
|
|
305
|
-
</Box>
|
|
306
|
-
)}
|
|
307
|
-
</Box>
|
|
308
|
-
)}
|
|
309
|
-
</Stack>
|
|
310
|
-
)
|
|
311
|
-
|
|
312
|
-
// If no items are selected, nothing to manage
|
|
313
89
|
if (selectedRows.length === 0) return null
|
|
314
90
|
|
|
315
91
|
return (
|
|
@@ -322,7 +98,6 @@ function ManageRow({
|
|
|
322
98
|
alignItems: 'center',
|
|
323
99
|
justifyContent: 'space-between',
|
|
324
100
|
height: '60px',
|
|
325
|
-
// On mobile: reduce minWidth + 5px side padding
|
|
326
101
|
minWidth: isMobile ? 'auto' : '560px',
|
|
327
102
|
padding: isMobile ? '0 5px' : '0 10px',
|
|
328
103
|
userSelect: 'none',
|
|
@@ -344,7 +119,203 @@ function ManageRow({
|
|
|
344
119
|
} selected`}
|
|
345
120
|
/>
|
|
346
121
|
</Box>
|
|
347
|
-
|
|
122
|
+
|
|
123
|
+
<Stack
|
|
124
|
+
component="div"
|
|
125
|
+
spacing={0}
|
|
126
|
+
direction="row"
|
|
127
|
+
justifyContent="center"
|
|
128
|
+
sx={{ '& > div:not(:last-child)': { marginRight: '2px' } }}
|
|
129
|
+
>
|
|
130
|
+
{/* If exactly 1 item selected, show Manage / Show */}
|
|
131
|
+
{selectedRows.length === 1 && (
|
|
132
|
+
<Box
|
|
133
|
+
display="flex"
|
|
134
|
+
flexDirection="row"
|
|
135
|
+
alignItems="center"
|
|
136
|
+
sx={{
|
|
137
|
+
borderRight: '1px solid #e0e0e0',
|
|
138
|
+
paddingRight: '8px',
|
|
139
|
+
marginRight: '8px',
|
|
140
|
+
}}
|
|
141
|
+
>
|
|
142
|
+
{onManage && (
|
|
143
|
+
<Box
|
|
144
|
+
onClick={e => {
|
|
145
|
+
e.stopPropagation()
|
|
146
|
+
handleActionSelection('manage')
|
|
147
|
+
}}
|
|
148
|
+
display="flex"
|
|
149
|
+
flexDirection="column"
|
|
150
|
+
alignItems="center"
|
|
151
|
+
sx={{
|
|
152
|
+
padding: '8px',
|
|
153
|
+
cursor: 'pointer',
|
|
154
|
+
'&:hover': {
|
|
155
|
+
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
156
|
+
},
|
|
157
|
+
borderRadius: '4px',
|
|
158
|
+
transition: 'background-color 0.2s',
|
|
159
|
+
userSelect: 'none',
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
<Box
|
|
163
|
+
sx={{
|
|
164
|
+
display: 'flex',
|
|
165
|
+
flexDirection: 'column',
|
|
166
|
+
alignItems: 'center',
|
|
167
|
+
color: 'black',
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
<EditIcon />
|
|
171
|
+
<Typography fontvariant="merriparagraph" text="Manage" />
|
|
172
|
+
</Box>
|
|
173
|
+
</Box>
|
|
174
|
+
)}
|
|
175
|
+
|
|
176
|
+
{onShow && (
|
|
177
|
+
<Box
|
|
178
|
+
onClick={e => {
|
|
179
|
+
e.stopPropagation()
|
|
180
|
+
handleActionSelection('show')
|
|
181
|
+
}}
|
|
182
|
+
display="flex"
|
|
183
|
+
flexDirection="column"
|
|
184
|
+
alignItems="center"
|
|
185
|
+
sx={{
|
|
186
|
+
padding: '8px',
|
|
187
|
+
cursor: 'pointer',
|
|
188
|
+
'&:hover': {
|
|
189
|
+
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
190
|
+
},
|
|
191
|
+
borderRadius: '4px',
|
|
192
|
+
transition: 'background-color 0.2s',
|
|
193
|
+
userSelect: 'none',
|
|
194
|
+
}}
|
|
195
|
+
>
|
|
196
|
+
<Box
|
|
197
|
+
sx={{
|
|
198
|
+
display: 'flex',
|
|
199
|
+
flexDirection: 'column',
|
|
200
|
+
alignItems: 'center',
|
|
201
|
+
color: 'black',
|
|
202
|
+
}}
|
|
203
|
+
>
|
|
204
|
+
<VisibilityIcon />
|
|
205
|
+
<Typography fontvariant="merriparagraph" text="Show" />
|
|
206
|
+
</Box>
|
|
207
|
+
</Box>
|
|
208
|
+
)}
|
|
209
|
+
</Box>
|
|
210
|
+
)}
|
|
211
|
+
|
|
212
|
+
{/* Duplicate, Delete, Export */}
|
|
213
|
+
{selectedRows.length > 0 && (
|
|
214
|
+
<Box display="flex" flexDirection="row" alignItems="center">
|
|
215
|
+
{onDuplicate && !isMobile && (
|
|
216
|
+
<Box
|
|
217
|
+
onClick={e => {
|
|
218
|
+
e.stopPropagation()
|
|
219
|
+
handleActionSelection('duplicate')
|
|
220
|
+
}}
|
|
221
|
+
display="flex"
|
|
222
|
+
flexDirection="column"
|
|
223
|
+
alignItems="center"
|
|
224
|
+
sx={{
|
|
225
|
+
padding: '8px',
|
|
226
|
+
cursor: 'pointer',
|
|
227
|
+
'&:hover': {
|
|
228
|
+
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
229
|
+
},
|
|
230
|
+
borderRadius: '4px',
|
|
231
|
+
transition: 'background-color 0.2s',
|
|
232
|
+
userSelect: 'none',
|
|
233
|
+
}}
|
|
234
|
+
>
|
|
235
|
+
<Box
|
|
236
|
+
sx={{
|
|
237
|
+
display: 'flex',
|
|
238
|
+
flexDirection: 'column',
|
|
239
|
+
alignItems: 'center',
|
|
240
|
+
color: 'black',
|
|
241
|
+
}}
|
|
242
|
+
>
|
|
243
|
+
<DuplicateIcon />
|
|
244
|
+
<Typography fontvariant="merriparagraph" text="Duplicate" />
|
|
245
|
+
</Box>
|
|
246
|
+
</Box>
|
|
247
|
+
)}
|
|
248
|
+
|
|
249
|
+
{onDelete && (
|
|
250
|
+
<Box
|
|
251
|
+
onClick={e => {
|
|
252
|
+
e.stopPropagation()
|
|
253
|
+
handleActionSelection('delete')
|
|
254
|
+
}}
|
|
255
|
+
display="flex"
|
|
256
|
+
flexDirection="column"
|
|
257
|
+
alignItems="center"
|
|
258
|
+
sx={{
|
|
259
|
+
padding: '8px',
|
|
260
|
+
cursor: 'pointer',
|
|
261
|
+
'&:hover': {
|
|
262
|
+
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
263
|
+
},
|
|
264
|
+
borderRadius: '4px',
|
|
265
|
+
transition: 'background-color 0.2s',
|
|
266
|
+
userSelect: 'none',
|
|
267
|
+
}}
|
|
268
|
+
>
|
|
269
|
+
<Box
|
|
270
|
+
sx={{
|
|
271
|
+
display: 'flex',
|
|
272
|
+
flexDirection: 'column',
|
|
273
|
+
alignItems: 'center',
|
|
274
|
+
color: 'black',
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
<DeleteIcon />
|
|
278
|
+
<Typography fontvariant="merriparagraph" text="Delete" />
|
|
279
|
+
</Box>
|
|
280
|
+
</Box>
|
|
281
|
+
)}
|
|
282
|
+
|
|
283
|
+
{(!isMobile || onExport) && (
|
|
284
|
+
<Box
|
|
285
|
+
onClick={e => {
|
|
286
|
+
e.stopPropagation()
|
|
287
|
+
handleActionSelection('export')
|
|
288
|
+
}}
|
|
289
|
+
display="flex"
|
|
290
|
+
flexDirection="column"
|
|
291
|
+
alignItems="center"
|
|
292
|
+
sx={{
|
|
293
|
+
padding: '8px',
|
|
294
|
+
cursor: 'pointer',
|
|
295
|
+
'&:hover': {
|
|
296
|
+
backgroundColor: 'rgba(0, 0, 0, 0.04)',
|
|
297
|
+
},
|
|
298
|
+
borderRadius: '4px',
|
|
299
|
+
transition: 'background-color 0.2s',
|
|
300
|
+
userSelect: 'none',
|
|
301
|
+
}}
|
|
302
|
+
>
|
|
303
|
+
<Box
|
|
304
|
+
sx={{
|
|
305
|
+
display: 'flex',
|
|
306
|
+
flexDirection: 'column',
|
|
307
|
+
alignItems: 'center',
|
|
308
|
+
color: 'black',
|
|
309
|
+
}}
|
|
310
|
+
>
|
|
311
|
+
<ExportIcon />
|
|
312
|
+
<Typography fontvariant="merriparagraph" text="Export" />
|
|
313
|
+
</Box>
|
|
314
|
+
</Box>
|
|
315
|
+
)}
|
|
316
|
+
</Box>
|
|
317
|
+
)}
|
|
318
|
+
</Stack>
|
|
348
319
|
</Box>
|
|
349
320
|
</Paper>
|
|
350
321
|
)
|