goobs-frontend 0.9.33 → 0.9.35
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 +5 -5
- package/src/components/DataGrid/FilterSection/index.tsx +257 -0
- package/src/components/DataGrid/ManageRow/index.tsx +139 -138
- package/src/components/DataGrid/MetricCard/index.tsx +467 -0
- package/src/components/DataGrid/MetricSection/index.tsx +70 -0
- package/src/components/DataGrid/Table/Rows/index.tsx +10 -0
- package/src/components/DataGrid/Table/index.tsx +1 -1
- package/src/components/DataGrid/index.tsx +46 -39
- package/src/components/DataGrid/types/index.ts +38 -5
- package/src/components/Field/Dropdown/Searchable/index.tsx +23 -31
- package/src/components/Form/DataGrid/index.tsx +190 -2
- package/src/components/Nav/VerticalVariant/viewNav/expanding.tsx +0 -4
- package/src/components/Nav/index.tsx +1 -1
- package/src/index.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "goobs-frontend",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A comprehensive React-based libary that extends the functionality of Material-UI",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"next": "15",
|
|
38
38
|
"otplib": "^12",
|
|
39
39
|
"react-qr-code": "^2",
|
|
40
|
-
"slate": "^0.
|
|
41
|
-
"slate-dom": "^0.
|
|
40
|
+
"slate": "^0.117",
|
|
41
|
+
"slate-dom": "^0.116",
|
|
42
42
|
"slate-history": "^0.113",
|
|
43
|
-
"slate-react": "^0.
|
|
43
|
+
"slate-react": "^0.117",
|
|
44
44
|
"storybook": "^9",
|
|
45
45
|
"zod": "^3",
|
|
46
46
|
"zod-formik-adapter": "^1"
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@types/react-dom": "^19",
|
|
56
56
|
"@typescript-eslint/eslint-plugin": "^8",
|
|
57
57
|
"@typescript-eslint/parser": "^8",
|
|
58
|
-
"chromatic": "^
|
|
58
|
+
"chromatic": "^13",
|
|
59
59
|
"eslint": "^9",
|
|
60
60
|
"eslint-config-next": "^15",
|
|
61
61
|
"eslint-config-prettier": "^10",
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Box, Grid, useMediaQuery, keyframes, alpha } from '@mui/material'
|
|
5
|
+
import SearchableDropdown from '../../Field/Dropdown/Searchable'
|
|
6
|
+
import DateField from '../../Field/Date/DateField'
|
|
7
|
+
import DateRange from '../../Field/Date/DateRange'
|
|
8
|
+
import { DataGridFilter } from '../types'
|
|
9
|
+
|
|
10
|
+
// Sacred theming animations
|
|
11
|
+
const sacredGlow = keyframes`
|
|
12
|
+
0% { box-shadow: 0 0 10px rgba(255, 215, 0, 0.3); }
|
|
13
|
+
50% { box-shadow: 0 0 20px rgba(255, 215, 0, 0.5); }
|
|
14
|
+
100% { box-shadow: 0 0 10px rgba(255, 215, 0, 0.3); }
|
|
15
|
+
`
|
|
16
|
+
|
|
17
|
+
const sacredFloat = keyframes`
|
|
18
|
+
0% { transform: translateY(0px); }
|
|
19
|
+
50% { transform: translateY(-2px); }
|
|
20
|
+
100% { transform: translateY(0px); }
|
|
21
|
+
`
|
|
22
|
+
|
|
23
|
+
const rotateGlyph = keyframes`
|
|
24
|
+
from { transform: rotate(0deg); }
|
|
25
|
+
to { transform: rotate(360deg); }
|
|
26
|
+
`
|
|
27
|
+
|
|
28
|
+
// Sacred hieroglyphs for decoration
|
|
29
|
+
const SACRED_GLYPHS = [
|
|
30
|
+
'𓁟',
|
|
31
|
+
'𓂀',
|
|
32
|
+
'𓃀',
|
|
33
|
+
'𓄿',
|
|
34
|
+
'𓊖',
|
|
35
|
+
'𓊗',
|
|
36
|
+
'𓋴',
|
|
37
|
+
'𓏏',
|
|
38
|
+
'𓊨',
|
|
39
|
+
'𓁦',
|
|
40
|
+
'𓅓',
|
|
41
|
+
'𓆄',
|
|
42
|
+
'𓇳',
|
|
43
|
+
'𓈖',
|
|
44
|
+
'𓊹',
|
|
45
|
+
'𓊺',
|
|
46
|
+
'𓊻',
|
|
47
|
+
'𓋹',
|
|
48
|
+
'𓌻',
|
|
49
|
+
'𓍿',
|
|
50
|
+
'𓅨',
|
|
51
|
+
'𓂋',
|
|
52
|
+
'𓏭',
|
|
53
|
+
'𓊵',
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
export interface FilterSectionProps {
|
|
57
|
+
filters: DataGridFilter[]
|
|
58
|
+
sacredtheme?: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const FilterSection: React.FC<FilterSectionProps> = ({
|
|
62
|
+
filters,
|
|
63
|
+
sacredtheme = false,
|
|
64
|
+
}) => {
|
|
65
|
+
const isMobile = useMediaQuery('(max-width:600px)')
|
|
66
|
+
const isTablet = useMediaQuery('(max-width:900px)')
|
|
67
|
+
|
|
68
|
+
if (!filters || filters.length === 0) {
|
|
69
|
+
return null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Determine grid size based on screen size and number of filters
|
|
73
|
+
const getGridSize = () => {
|
|
74
|
+
if (isMobile) {
|
|
75
|
+
return 12 // Full width on mobile
|
|
76
|
+
}
|
|
77
|
+
if (isTablet) {
|
|
78
|
+
return filters.length === 1 ? 6 : 12 / Math.min(filters.length, 2) // Max 2 per row on tablet
|
|
79
|
+
}
|
|
80
|
+
// Desktop - up to 4 filters per row, but scale based on count
|
|
81
|
+
if (filters.length === 1) return 3
|
|
82
|
+
if (filters.length === 2) return 6
|
|
83
|
+
if (filters.length === 3) return 4
|
|
84
|
+
return 3 // 4 filters per row max
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const gridSize = getGridSize()
|
|
88
|
+
|
|
89
|
+
// Helper function to render the appropriate filter component
|
|
90
|
+
const renderFilterComponent = (filter: DataGridFilter) => {
|
|
91
|
+
// Check if this is a date range filter
|
|
92
|
+
if (filter.type === 'daterange') {
|
|
93
|
+
return (
|
|
94
|
+
<DateRange
|
|
95
|
+
startLabel="From Date"
|
|
96
|
+
endLabel="To Date"
|
|
97
|
+
value={filter.value as { start: Date | null; end: Date | null }}
|
|
98
|
+
onChange={
|
|
99
|
+
filter.onChange as (value: {
|
|
100
|
+
start: Date | null
|
|
101
|
+
end: Date | null
|
|
102
|
+
}) => void
|
|
103
|
+
}
|
|
104
|
+
sacredtheme={sacredtheme}
|
|
105
|
+
style={{
|
|
106
|
+
marginBottom: '8px',
|
|
107
|
+
width: filter.width || '100%',
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Check if this is a date filter
|
|
114
|
+
if (filter.type === 'date') {
|
|
115
|
+
return (
|
|
116
|
+
<DateField
|
|
117
|
+
label={filter.label}
|
|
118
|
+
value={
|
|
119
|
+
(filter.value as string) ? new Date(filter.value as string) : null
|
|
120
|
+
}
|
|
121
|
+
onChange={filter.onChange as (date: Date | null) => void}
|
|
122
|
+
placeholder={filter.placeholder}
|
|
123
|
+
sacredtheme={sacredtheme}
|
|
124
|
+
disableFutureDateValidation={true}
|
|
125
|
+
style={{
|
|
126
|
+
marginBottom: '8px',
|
|
127
|
+
width: filter.width || '100%',
|
|
128
|
+
}}
|
|
129
|
+
/>
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Default to SearchableDropdown for regular filters
|
|
134
|
+
return (
|
|
135
|
+
<SearchableDropdown
|
|
136
|
+
label={filter.label}
|
|
137
|
+
options={filter.options || []}
|
|
138
|
+
defaultValue={filter.value === 'all' ? '' : (filter.value as string)}
|
|
139
|
+
onChange={filter.onChange as (value: { value: string } | null) => void}
|
|
140
|
+
placeholder={filter.placeholder}
|
|
141
|
+
width={filter.width || '100%'}
|
|
142
|
+
variant="simple"
|
|
143
|
+
sacredtheme={sacredtheme}
|
|
144
|
+
sacredTitle={sacredtheme ? 'Divine Filtering' : ''}
|
|
145
|
+
sacredSubtitle={sacredtheme ? 'Channel cosmic data streams' : ''}
|
|
146
|
+
style={{
|
|
147
|
+
marginBottom: '8px',
|
|
148
|
+
}}
|
|
149
|
+
/>
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<Box
|
|
155
|
+
sx={{
|
|
156
|
+
width: '100%',
|
|
157
|
+
position: 'relative',
|
|
158
|
+
p: sacredtheme ? 1 : 0.5,
|
|
159
|
+
...(sacredtheme && {
|
|
160
|
+
backgroundColor: alpha('#000000', 0.6),
|
|
161
|
+
borderRadius: '8px',
|
|
162
|
+
border: `1px solid ${alpha('#FFD700', 0.3)}`,
|
|
163
|
+
backgroundImage: `
|
|
164
|
+
linear-gradient(rgba(255, 215, 0, 0.02), rgba(255, 215, 0, 0.02)),
|
|
165
|
+
radial-gradient(circle at top left, rgba(255, 215, 0, 0.08) 0%, transparent 50%)
|
|
166
|
+
`,
|
|
167
|
+
animation: `${sacredGlow} 3s ease-in-out infinite`,
|
|
168
|
+
'&::before': {
|
|
169
|
+
content: '"𓊹"',
|
|
170
|
+
position: 'absolute',
|
|
171
|
+
top: '8px',
|
|
172
|
+
right: '12px',
|
|
173
|
+
fontSize: '14px',
|
|
174
|
+
color: alpha('#FFD700', 0.4),
|
|
175
|
+
animation: `${rotateGlyph} 15s linear infinite`,
|
|
176
|
+
zIndex: 1,
|
|
177
|
+
},
|
|
178
|
+
}),
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
{/* Sacred decorative glyphs */}
|
|
182
|
+
{sacredtheme && (
|
|
183
|
+
<>
|
|
184
|
+
<Box
|
|
185
|
+
sx={{
|
|
186
|
+
position: 'absolute',
|
|
187
|
+
top: '8px',
|
|
188
|
+
left: '8px',
|
|
189
|
+
color: alpha('#FFD700', 0.3),
|
|
190
|
+
fontSize: '12px',
|
|
191
|
+
animation: `${sacredFloat} 4s ease-in-out infinite`,
|
|
192
|
+
zIndex: 1,
|
|
193
|
+
}}
|
|
194
|
+
>
|
|
195
|
+
{SACRED_GLYPHS[15]} {/* Filter/sieve symbol */}
|
|
196
|
+
</Box>
|
|
197
|
+
<Box
|
|
198
|
+
sx={{
|
|
199
|
+
position: 'absolute',
|
|
200
|
+
bottom: '8px',
|
|
201
|
+
right: '8px',
|
|
202
|
+
color: alpha('#FFD700', 0.3),
|
|
203
|
+
fontSize: '12px',
|
|
204
|
+
animation: `${sacredFloat} 3s ease-in-out infinite reverse`,
|
|
205
|
+
zIndex: 1,
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
{SACRED_GLYPHS[16]} {/* Filter/refine symbol */}
|
|
209
|
+
</Box>
|
|
210
|
+
</>
|
|
211
|
+
)}
|
|
212
|
+
|
|
213
|
+
<Grid container spacing={1}>
|
|
214
|
+
{filters.map((filter, index) => (
|
|
215
|
+
<Grid
|
|
216
|
+
key={`${filter.label}-${index}`}
|
|
217
|
+
size={{
|
|
218
|
+
xs: isMobile ? 12 : filter.type === 'daterange' ? 6 : gridSize,
|
|
219
|
+
}}
|
|
220
|
+
>
|
|
221
|
+
{renderFilterComponent(filter)}
|
|
222
|
+
</Grid>
|
|
223
|
+
))}
|
|
224
|
+
</Grid>
|
|
225
|
+
|
|
226
|
+
{/* Bottom sacred decoration */}
|
|
227
|
+
{sacredtheme && (
|
|
228
|
+
<Box
|
|
229
|
+
sx={{
|
|
230
|
+
position: 'absolute',
|
|
231
|
+
bottom: '4px',
|
|
232
|
+
left: '50%',
|
|
233
|
+
transform: 'translateX(-50%)',
|
|
234
|
+
display: 'flex',
|
|
235
|
+
gap: 0.5,
|
|
236
|
+
opacity: 0.5,
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
{['𓊖', '𓊗', '𓊖'].map((glyph, i) => (
|
|
240
|
+
<Box
|
|
241
|
+
key={i}
|
|
242
|
+
sx={{
|
|
243
|
+
color: alpha('#FFD700', 0.4),
|
|
244
|
+
fontSize: 8,
|
|
245
|
+
animation: `${sacredFloat} ${2 + i * 0.3}s ease-in-out infinite`,
|
|
246
|
+
}}
|
|
247
|
+
>
|
|
248
|
+
{glyph}
|
|
249
|
+
</Box>
|
|
250
|
+
))}
|
|
251
|
+
</Box>
|
|
252
|
+
)}
|
|
253
|
+
</Box>
|
|
254
|
+
)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export default FilterSection
|
|
@@ -178,161 +178,162 @@ function ManageRow({
|
|
|
178
178
|
sx={{ '& > div:not(:last-child)': { marginRight: '2px' } }}
|
|
179
179
|
>
|
|
180
180
|
{/* If exactly 1 item selected, show Manage / Show / Duplicate */}
|
|
181
|
-
{selectedRows.length === 1 &&
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
onClick={e => {
|
|
197
|
-
e.stopPropagation()
|
|
198
|
-
handleActionSelection('manage')
|
|
199
|
-
}}
|
|
200
|
-
display="flex"
|
|
201
|
-
flexDirection="column"
|
|
202
|
-
alignItems="center"
|
|
203
|
-
sx={{
|
|
204
|
-
padding: '8px',
|
|
205
|
-
cursor: 'pointer',
|
|
206
|
-
'&:hover': {
|
|
207
|
-
backgroundColor: sacredtheme
|
|
208
|
-
? alpha(egyptianStyles.goldColor, 0.1)
|
|
209
|
-
: 'rgba(0, 0, 0, 0.04)',
|
|
210
|
-
},
|
|
211
|
-
borderRadius: '4px',
|
|
212
|
-
transition: 'background-color 0.2s',
|
|
213
|
-
userSelect: 'none',
|
|
214
|
-
}}
|
|
215
|
-
>
|
|
181
|
+
{selectedRows.length === 1 &&
|
|
182
|
+
(onManage || onShow || (onDuplicate && !isMobile)) && (
|
|
183
|
+
<Box
|
|
184
|
+
display="flex"
|
|
185
|
+
flexDirection="row"
|
|
186
|
+
alignItems="center"
|
|
187
|
+
sx={{
|
|
188
|
+
borderRight: sacredtheme
|
|
189
|
+
? `1px solid ${alpha(egyptianStyles.goldColor, 0.3)}`
|
|
190
|
+
: '1px solid #e0e0e0',
|
|
191
|
+
paddingRight: '8px',
|
|
192
|
+
marginRight: '8px',
|
|
193
|
+
}}
|
|
194
|
+
>
|
|
195
|
+
{onManage && (
|
|
216
196
|
<Box
|
|
197
|
+
onClick={e => {
|
|
198
|
+
e.stopPropagation()
|
|
199
|
+
handleActionSelection('manage')
|
|
200
|
+
}}
|
|
201
|
+
display="flex"
|
|
202
|
+
flexDirection="column"
|
|
203
|
+
alignItems="center"
|
|
217
204
|
sx={{
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
205
|
+
padding: '8px',
|
|
206
|
+
cursor: 'pointer',
|
|
207
|
+
'&:hover': {
|
|
208
|
+
backgroundColor: sacredtheme
|
|
209
|
+
? alpha(egyptianStyles.goldColor, 0.1)
|
|
210
|
+
: 'rgba(0, 0, 0, 0.04)',
|
|
211
|
+
},
|
|
212
|
+
borderRadius: '4px',
|
|
213
|
+
transition: 'background-color 0.2s',
|
|
214
|
+
userSelect: 'none',
|
|
222
215
|
}}
|
|
223
216
|
>
|
|
224
|
-
<
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
sacredtheme ? egyptianStyles.goldColor :
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
217
|
+
<Box
|
|
218
|
+
sx={{
|
|
219
|
+
display: 'flex',
|
|
220
|
+
flexDirection: 'column',
|
|
221
|
+
alignItems: 'center',
|
|
222
|
+
color: sacredtheme ? egyptianStyles.goldColor : 'black',
|
|
223
|
+
}}
|
|
224
|
+
>
|
|
225
|
+
<EditIcon />
|
|
226
|
+
<Typography
|
|
227
|
+
fontvariant="merriparagraph"
|
|
228
|
+
text="Manage"
|
|
229
|
+
fontcolor={
|
|
230
|
+
sacredtheme ? egyptianStyles.goldColor : undefined
|
|
231
|
+
}
|
|
232
|
+
sx={
|
|
233
|
+
sacredtheme
|
|
234
|
+
? { fontFamily: '"Crimson Text", serif' }
|
|
235
|
+
: {}
|
|
236
|
+
}
|
|
237
|
+
/>
|
|
238
|
+
</Box>
|
|
237
239
|
</Box>
|
|
238
|
-
|
|
239
|
-
)}
|
|
240
|
+
)}
|
|
240
241
|
|
|
241
|
-
|
|
242
|
-
<Box
|
|
243
|
-
onClick={e => {
|
|
244
|
-
e.stopPropagation()
|
|
245
|
-
handleActionSelection('show')
|
|
246
|
-
}}
|
|
247
|
-
display="flex"
|
|
248
|
-
flexDirection="column"
|
|
249
|
-
alignItems="center"
|
|
250
|
-
sx={{
|
|
251
|
-
padding: '8px',
|
|
252
|
-
cursor: 'pointer',
|
|
253
|
-
'&:hover': {
|
|
254
|
-
backgroundColor: sacredtheme
|
|
255
|
-
? alpha(egyptianStyles.goldColor, 0.1)
|
|
256
|
-
: 'rgba(0, 0, 0, 0.04)',
|
|
257
|
-
},
|
|
258
|
-
borderRadius: '4px',
|
|
259
|
-
transition: 'background-color 0.2s',
|
|
260
|
-
userSelect: 'none',
|
|
261
|
-
}}
|
|
262
|
-
>
|
|
242
|
+
{onShow && (
|
|
263
243
|
<Box
|
|
244
|
+
onClick={e => {
|
|
245
|
+
e.stopPropagation()
|
|
246
|
+
handleActionSelection('show')
|
|
247
|
+
}}
|
|
248
|
+
display="flex"
|
|
249
|
+
flexDirection="column"
|
|
250
|
+
alignItems="center"
|
|
264
251
|
sx={{
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
252
|
+
padding: '8px',
|
|
253
|
+
cursor: 'pointer',
|
|
254
|
+
'&:hover': {
|
|
255
|
+
backgroundColor: sacredtheme
|
|
256
|
+
? alpha(egyptianStyles.goldColor, 0.1)
|
|
257
|
+
: 'rgba(0, 0, 0, 0.04)',
|
|
258
|
+
},
|
|
259
|
+
borderRadius: '4px',
|
|
260
|
+
transition: 'background-color 0.2s',
|
|
261
|
+
userSelect: 'none',
|
|
269
262
|
}}
|
|
270
263
|
>
|
|
271
|
-
<
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
sacredtheme ? egyptianStyles.goldColor :
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
264
|
+
<Box
|
|
265
|
+
sx={{
|
|
266
|
+
display: 'flex',
|
|
267
|
+
flexDirection: 'column',
|
|
268
|
+
alignItems: 'center',
|
|
269
|
+
color: sacredtheme ? egyptianStyles.goldColor : 'black',
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
<VisibilityIcon />
|
|
273
|
+
<Typography
|
|
274
|
+
fontvariant="merriparagraph"
|
|
275
|
+
text="Show"
|
|
276
|
+
fontcolor={
|
|
277
|
+
sacredtheme ? egyptianStyles.goldColor : undefined
|
|
278
|
+
}
|
|
279
|
+
sx={
|
|
280
|
+
sacredtheme
|
|
281
|
+
? { fontFamily: '"Crimson Text", serif' }
|
|
282
|
+
: {}
|
|
283
|
+
}
|
|
284
|
+
/>
|
|
285
|
+
</Box>
|
|
284
286
|
</Box>
|
|
285
|
-
|
|
286
|
-
)}
|
|
287
|
+
)}
|
|
287
288
|
|
|
288
|
-
|
|
289
|
-
<Box
|
|
290
|
-
onClick={e => {
|
|
291
|
-
e.stopPropagation()
|
|
292
|
-
handleActionSelection('duplicate')
|
|
293
|
-
}}
|
|
294
|
-
display="flex"
|
|
295
|
-
flexDirection="column"
|
|
296
|
-
alignItems="center"
|
|
297
|
-
sx={{
|
|
298
|
-
padding: '8px',
|
|
299
|
-
cursor: 'pointer',
|
|
300
|
-
'&:hover': {
|
|
301
|
-
backgroundColor: sacredtheme
|
|
302
|
-
? alpha(egyptianStyles.goldColor, 0.1)
|
|
303
|
-
: 'rgba(0, 0, 0, 0.04)',
|
|
304
|
-
},
|
|
305
|
-
borderRadius: '4px',
|
|
306
|
-
transition: 'background-color 0.2s',
|
|
307
|
-
userSelect: 'none',
|
|
308
|
-
}}
|
|
309
|
-
>
|
|
289
|
+
{onDuplicate && !isMobile && (
|
|
310
290
|
<Box
|
|
291
|
+
onClick={e => {
|
|
292
|
+
e.stopPropagation()
|
|
293
|
+
handleActionSelection('duplicate')
|
|
294
|
+
}}
|
|
295
|
+
display="flex"
|
|
296
|
+
flexDirection="column"
|
|
297
|
+
alignItems="center"
|
|
311
298
|
sx={{
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
299
|
+
padding: '8px',
|
|
300
|
+
cursor: 'pointer',
|
|
301
|
+
'&:hover': {
|
|
302
|
+
backgroundColor: sacredtheme
|
|
303
|
+
? alpha(egyptianStyles.goldColor, 0.1)
|
|
304
|
+
: 'rgba(0, 0, 0, 0.04)',
|
|
305
|
+
},
|
|
306
|
+
borderRadius: '4px',
|
|
307
|
+
transition: 'background-color 0.2s',
|
|
308
|
+
userSelect: 'none',
|
|
316
309
|
}}
|
|
317
310
|
>
|
|
318
|
-
<
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
sacredtheme ? egyptianStyles.goldColor :
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
311
|
+
<Box
|
|
312
|
+
sx={{
|
|
313
|
+
display: 'flex',
|
|
314
|
+
flexDirection: 'column',
|
|
315
|
+
alignItems: 'center',
|
|
316
|
+
color: sacredtheme ? egyptianStyles.goldColor : 'black',
|
|
317
|
+
}}
|
|
318
|
+
>
|
|
319
|
+
<DuplicateIcon />
|
|
320
|
+
<Typography
|
|
321
|
+
fontvariant="merriparagraph"
|
|
322
|
+
text="Duplicate"
|
|
323
|
+
fontcolor={
|
|
324
|
+
sacredtheme ? egyptianStyles.goldColor : undefined
|
|
325
|
+
}
|
|
326
|
+
sx={
|
|
327
|
+
sacredtheme
|
|
328
|
+
? { fontFamily: '"Crimson Text", serif' }
|
|
329
|
+
: {}
|
|
330
|
+
}
|
|
331
|
+
/>
|
|
332
|
+
</Box>
|
|
331
333
|
</Box>
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
)}
|
|
334
|
+
)}
|
|
335
|
+
</Box>
|
|
336
|
+
)}
|
|
336
337
|
|
|
337
338
|
{/* Delete and Export - shown for any number of selected rows */}
|
|
338
339
|
<Box display="flex" flexDirection="row" alignItems="center">
|