mui 6
Massimo Melina committed
Mar 14, 2026 at 18:13 UTC
d61966867cb011ef7495f1cce026794934ac37df
22 files changed
+817
-537
admin/package.json
+6
-6
@@ -12,12 +12,12 @@
12
"@hfs/mui-grid-form": "*",
13
"@hfs/shared": "*",
14
"@emotion/styled": "^11.11.5",
15
- "@mui/icons-material": "^5.18.0",
16
- "@mui/lab": "^5.0.0-alpha.177",
17
- "@mui/material": "^5.18.0",
18
- "@mui/x-data-grid": "^6.20.4",
19
- "@mui/x-date-pickers": "^6.20.2",
20
- "@mui/x-tree-view": "^6.17.0",
15
+ "@mui/icons-material": "^6.4.11",
16
+ "@mui/lab": "^6.0.1-beta.34",
17
+ "@mui/material": "^6.4.11",
18
+ "@mui/x-data-grid": "^7.29.0",
19
+ "@mui/x-date-pickers": "^7.29.0",
20
+ "@mui/x-tree-view": "^7.29.0",
21
"@gregoranders/csv": "^0.0.13",
22
"dayjs": "^1.11.10",
23
"prismjs": "^1.29.0",
admin/src/AccountForm.ts
+1
-1
@@ -69,7 +69,7 @@ export default function AccountForm({ account, done, groups, addToBar, reload }:
69
70
{ k: 'disabled', comp: BoolField, fromField: x=>!x, toField: x=>!x, label: "Enabled", xs: 12, sm: 6, lg: 4,
71
helperText: values.disabled || values.canLogin !== false ? "Login is prevented if account is disabled, or all its groups are disabled"
72
- : h(Box, { color: 'warning.main', component: 'span' },
72
+ : h(Box, { color: 'warning.main', component: 'span' } as any, // Box.component has ts problems with h()
73
new Date(account.expire!) < new Date() ? "Login is prevented because account is expired" // use account instead of values, so to use the value currently applied
74
: "Login is prevented because all of its groups are disabled")
75
},
admin/src/AccountsPage.ts
+20
-14
@@ -8,7 +8,7 @@ import {
8
} from '@mui/icons-material'
9
import { newDialog, with_, md, Jsonify } from './misc'
10
import { Btn, Flex, IconBtn, iconTooltip, reloadBtn, useBreakpoint, useToggleButton } from './mui'
11
-import { TreeItem, TreeView } from '@mui/x-tree-view'
11
+import { TreeItem, SimpleTreeView } from '@mui/x-tree-view'
12
import MenuButton from './MenuButton'
13
import AccountForm from './AccountForm'
14
import _ from 'lodash'
@@ -19,6 +19,9 @@ import apiAccounts from '../../src/api.accounts'
19
20
export type Account = Jsonify<ReturnType<typeof apiAccounts.get_accounts>['list'][0]>
21
22
+const SEP = '\t'
23
+const userFromItemId = (itemId?: string) => itemId?.split(SEP).at(-1)
24
+
25
export default function AccountsPage() {
26
const { username, accountsAsTree } = useSnapState()
27
const { data, reload, element } = useApiEx<typeof apiAccounts.get_accounts>('get_accounts')
@@ -26,10 +29,10 @@ export default function AccountsPage() {
29
const selectionMode = Array.isArray(sel)
30
useEffect(() => { // if accounts are reloaded, review the selection to remove elements that don't exist anymore
31
if (Array.isArray(data?.list) && selectionMode)
29
- setSel( sel.filter(u => data!.list.find((e:any) => e?.username === u)) ) // remove elements that don't exist anymore
32
+ setSel( sel.filter(x => data!.list.find((e:any) => e?.username === userFromItemId(x))) ) // remove elements that don't exist anymore
33
}, [data]) //eslint-disable-line -- Don't fall for its suggestion to add `sel` here: we modify it and declaring it as a dependency would cause a logical loop
34
const list = useMemo(() => data && _.sortBy(data.list, [x => !x.isGroup, x => !x.adminActualAccess, 'username']), [data])
32
- const selectedAccount = selectionMode && _.find(list, { username: sel[0] })
35
+ const selectedAccount = selectionMode && _.find(list, { username: userFromItemId(sel[0]) })
36
const sideBreakpoint = 'md'
37
const isSideBreakpoint = useBreakpoint(sideBreakpoint)
38
@@ -40,7 +43,7 @@ export default function AccountsPage() {
43
h(Btn, { onClick: deleteAccounts, icon: Delete }, "Remove"),
44
),
45
h(List, {},
43
- sel.map(username =>
46
+ _.uniq(sel.map(userFromItemId)).map(username =>
47
h(ListItem, { key: username },
48
h(ListItemText, {}, username))))
49
)
@@ -107,22 +110,24 @@ export default function AccountsPage() {
110
list?.length! > 0 && h(Typography, { p: 1 }, `${list!.length} account(s)`),
111
),
112
!list?.length && h(Alert, { severity: 'info' }, md`To access administration <u>remotely</u> you will need to create a user account with admin permission`),
110
- h(TreeView<true>, { // true because it's not detecting multiSelect correctly (ts495)
113
+ h(SimpleTreeView<true>, { // true because it's not detecting multiSelect correctly (ts495)
114
multiSelect: true,
115
sx: { pr: 4, pb: 2, minWidth: '15em' },
113
- selected: selectionMode ? sel : [],
114
- defaultCollapseIcon: h(ExpandMore),
115
- defaultExpandIcon: h(ChevronRight),
116
- onNodeSelect(ev, ids) {
117
- if (!(ev.target as any)?.closest?.('.MuiTreeItem-iconContainer')) // don't select if clicked the expansion button, mostly for mobile users
116
+ selectedItems: selectionMode ? sel : [],
117
+ slots: {
118
+ collapseIcon: ExpandMore,
119
+ expandIcon: ChevronRight,
120
+ },
121
+ onSelectedItemsChange(ev, ids) {
122
+ if (!(ev?.target as any)?.closest?.('.MuiTreeItem-iconContainer')) // don't select if clicked the expansion button, mostly for mobile users
123
setSel(ids)
124
}
125
},
121
- list && (function recur(thisLevel): ReactNode {
126
+ list && (function recur(thisLevel, prefixPath=''): ReactNode {
127
return thisLevel.map(ac =>
128
h(TreeItem, {
129
key: ac.username,
125
- nodeId: ac.username,
130
+ itemId: prefixPath + ac.username,
131
label: h(Box, {
132
sx: {
133
display: 'flex',
@@ -141,7 +146,7 @@ export default function AccountsPage() {
146
Boolean(ac.belongs?.length) && h(Box, { sx: { color: 'text.secondary', fontSize: 'small' } },
147
'(', ac.belongs?.join(', '), ')')
148
),
144
- }, showTree && recur(list.filter(x => ac.directMembers?.includes(x.username)))))
149
+ }, showTree && recur(list.filter(x => ac.directMembers?.includes(x.username)), prefixPath+ac.username+SEP)))
150
})(showTree ? list.filter(ac => !list.some(x => x.members?.includes(ac.username))) : list)
151
)
152
),
@@ -169,7 +174,8 @@ export default function AccountsPage() {
174
}
175
176
async function deleteAccounts() {
172
- const toDelete = _.without(sel, username)
177
+ if (typeof sel === 'string') return
178
+ const toDelete = _.without(_.uniq(sel.map(userFromItemId)), username)
179
if (sel.length > toDelete.length)
180
if (!await confirmDialog(`You cannot ask to delete the account you are using. Continue with the rest?`)) return
181
if (!toDelete.length)
admin/src/App.ts
+3
-3
@@ -101,7 +101,7 @@ function Routed() {
101
})),
102
h(Box, { display: 'flex', flex: 1, }, // horizontal layout for menu-content
103
sideMenu && h(MainMenu, { itemTitle, onSelect(){} }),
104
- h(Box, {
104
+ h(Box as any, {
105
component: 'main',
106
sx: {
107
background: 'url(cup.svg) no-repeat right fixed',
@@ -156,11 +156,11 @@ function StickyBar({ title, titleSide, openMenu, props }: { props?: BoxProps, ti
156
'& .MuiAlert-message': { py: '1px' }
157
}
158
},
159
- h(Box, { component: 'h2', m: 0, whiteSpace: 'nowrap' }, title),
159
+ h(Box as any, { component: 'h2', m: 0, whiteSpace: 'nowrap' }, title),
160
titleSide
161
),
162
)
163
)
164
}
165
166
-export default App
\ No newline at end of file
166
+export default App
admin/src/ArrayField.ts
+2
-4
@@ -82,9 +82,7 @@ export function ArrayField<T extends object>({
82
field: f.k,
83
headerName: f.headerName ?? (typeof f.label === 'string' ? f.label : labelFromKey(f.k)),
84
disableColumnMenu: true,
85
- valueGetter({ value }: any) {
86
- return (f.toField || _.identity)(value)
87
- },
85
+ valueGetter: (v: any) => (f.toField || _.identity)(v),
86
...f.$width ? { [f.$width >= 8 ? 'width' : 'flex']: f.$width } : (!def?.width && !def?.flex && { flex: 1 }),
87
renderCell: f.$render,
88
mergeRender: f.$mergeRender,
@@ -211,4 +209,4 @@ const byType: Dict<{ field?: Partial<FieldDescriptor>, column?: Partial<GridColD
209
renderCell: ({ value }) => value && new Date(value).toLocaleString(),
210
}
211
}
214
-}
\ No newline at end of file
212
+}
admin/src/DataTable.ts
+11
-13
@@ -1,5 +1,6 @@
1
-import { DataGrid, DataGridProps, enUS, getGridStringOperators, GridColDef, GridFooter, GridFooterContainer,
1
+import { DataGrid, DataGridProps, getGridStringOperators, GridColDef, GridFooter, GridFooterContainer,
2
GridValidRowModel, useGridApiRef, GridRenderCellParams } from '@mui/x-data-grid'
3
+import { enUS } from '@mui/x-data-grid/locales'
4
import { Alert, Box, BoxProps, Breakpoint, LinearProgress, useTheme } from '@mui/material'
5
import { createElement as h, Fragment, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
6
import { callable, Callback, Falsy, newDialog, onlyTruthy, useGetSize } from '@hfs/shared'
@@ -52,10 +53,6 @@ export function DataTable({ columns, initialState={}, actions, actionsProps, ini
53
const res = op.getApplyFilterFn(item, col)
54
return res && _.negate(res)
55
},
55
- ...op.getApplyFilterFnV7 && { getApplyFilterFnV7(item, col) {
56
- const res = op.getApplyFilterFnV7?.(item, col)
57
- return res ? _.negate(res) : null
58
- } },
56
label: "(not) " + (localeText['filterOperator' + _.upperFirst(op.value)] || op.value)
57
} satisfies typeof op
58
])
@@ -66,13 +63,14 @@ export function DataTable({ columns, initialState={}, actions, actionsProps, ini
63
originalRenderCell: col.renderCell || true,
64
renderCell(params: GridRenderCellParams) {
65
const { columns } = params.api.store.getSnapshot()
69
- return h(Box, { maxHeight: '100%', ...col.cellInnerProps, sx: { textWrap: 'wrap', ...callable(sx as any, params) } }, // wrap if necessary, but stay within the row
66
+ return h(Box, { maxHeight: '100%', ...col.cellInnerProps, sx: { textWrap: 'wrap', lineHeight: '1.2em', ...callable(sx as any, params) } }, // wrap if necessary, but stay within the row
67
col.renderCell ? col.renderCell(params) : params.formattedValue,
68
col.mergeRender && h(Flex, { fontSize: 'smaller', flexWrap: 'wrap', mt: '1px', rowGap: 0, ...col.mergeRenderSx }, // wrap, normally causing overflow/hiding, if it doesn't fit
69
...onlyTruthy(_.map(col.mergeRender, (props, other) => {
70
if (!props || columns.columnVisibilityModel[other] !== false) return null
71
const rendered = renderCell({ ...columns.lookup[other], ...props.override }, params.row)
75
- return rendered && h(Box, { ...props, ...{ override: undefined }, ...compact && { lineHeight: '1em' } }, rendered)
72
+ // keep mergeRender permissive for editor autocomplete, then narrow only at the render boundary
73
+ return rendered && h(Box as any, { ...props, ...{ override: undefined }, ...compact && { lineHeight: '1em' } }, rendered)
74
}))
75
)
76
)
@@ -152,10 +150,9 @@ export function DataTable({ columns, initialState={}, actions, actionsProps, ini
150
},
151
slots: {
152
noRowsOverlay: () => initializing ? null : h(Center, {}, noRows || "No entries"),
155
- footer: CustomFooter,
153
+ footer: () => h(CustomFooter, { add: wrappedFooterSide }),
154
},
155
slotProps: {
158
- footer: { add: wrappedFooterSide } as any, // 'add' is introduced by CustomFooter
156
pagination: {
157
labelRowsPerPage: "Rows",
158
...!causingScrolling && {
@@ -217,11 +214,12 @@ export function DataTable({ columns, initialState={}, actions, actionsProps, ini
214
function renderCell(col: GridColDef, row: any) {
215
const api = apiRef.current
216
let value = row[col.field]
220
- if (col.valueGetter)
221
- value = col.valueGetter({ value, api, row, field: col.field, id: row.id } as any)
217
+ if (col.valueGetter) // @ts-ignore
218
+ value = col.valueGetter(value, row, col, api)
219
const render = (col as any).originalRenderCell || col.renderCell
220
return render && render !== true ? render({ value, row, api, ...row })
224
- : col.valueFormatter ? col.valueFormatter({ value, ...row })
221
+ // @ts-ignore
222
+ : col.valueFormatter ? col.valueFormatter(value, row, col, api)
223
: value
224
}
225
}
@@ -231,4 +229,4 @@ function CustomFooter({ add, ...props }: { add: ReactNode }) {
229
}
230
231
// required in case of fillFlex:true
234
-export const fillFlexParentSx = { display: 'flex', flexDirection: 'column' } as const
\ No newline at end of file
232
+export const fillFlexParentSx = { display: 'flex', flexDirection: 'column' } as const
admin/src/DateTimeField.ts
+6
-4
@@ -2,7 +2,7 @@ import { DateTimePicker } from '@mui/x-date-pickers'
2
import dayjs from 'dayjs'
3
import { FieldProps } from '@hfs/mui-grid-form'
4
import { createElement as h } from 'react'
5
-import { Box, FormHelperText } from '@mui/material'
5
+import { Box } from '@mui/material'
6
import { isTimestampString, objSameKeys } from './misc'
7
8
export function DateTimeField({ onChange, error, helperText, ...rest }: FieldProps<Date>) {
@@ -13,10 +13,12 @@ export function DateTimeField({ onChange, error, helperText, ...rest }: FieldPro
13
onChange(v: any) {
14
onChange(v && new Date(v), { was: rest.value, event: undefined })
15
},
16
- slotProps: { // under 400, not all buttons fit, so we sacrifice 'cancel' as you can still tap outside the dialog
17
- actionBar: { actions: ['clear', ...window.innerWidth < 400 ? [] : ['cancel'] as const, 'today', 'accept'] }
16
+ slotProps: {
17
+ // keep the same field look as StringField (filled variant) for visual consistency
18
+ textField: { variant: 'filled', error, helperText },
19
+ // under 400, not all buttons fit, so we sacrifice 'cancel' as you can still tap outside the dialog
20
+ actionBar: { actions: ['clear', ...(window.innerWidth < 400 ? [] : ['cancel'] as const), 'today', 'accept'] }
21
}
22
}),
20
- helperText && h(FormHelperText, { error }, helperText),
23
)
24
}
admin/src/FileField.ts
+1
@@ -14,6 +14,7 @@ export default function FileField({ value, onChange, files=true, folders=false,
14
...props,
15
value,
16
onChange,
17
+ size: 'small',
18
wrap: true,
19
end: h(IconBtn, {
20
icon: Eject,
admin/src/FileForm.ts
+4
-4
@@ -23,7 +23,7 @@ import {
23
Check, ContentCopy, ContentCut, ContentPaste, Delete, Edit, QrCode2, Save, RestartAlt
24
} from '@mui/icons-material'
25
import { moveVfs } from './VfsTree'
26
-import QrCreator from 'qr-creator';
26
+import QrCreator from 'qr-creator'
27
import { AddVfsBtn } from './VfsMenuBar'
28
import { SYS_ICONS } from '@hfs/frontend/src/sysIcons'
29
import { hIcon } from '@hfs/frontend/src/misc'
@@ -69,7 +69,7 @@ export default function FileForm({ file, addToBar, statusApi, accounts, saved, i
69
const barColors = useDialogBarColors()
70
const { movingFile } = useSnapState()
71
72
- const needSourceWarning = !hasSource && h(Box, { color: 'warning.main', component: 'span' }, "Works only on folders with disk source! ")
72
+ const needSourceWarning = !hasSource && h(Box as any, { color: 'warning.main', component: 'span' }, "Works only on folders with disk source! ")
73
const show: Record<keyof VfsPerms, boolean> = {
74
can_read: !isLink,
75
can_see: true,
@@ -409,9 +409,9 @@ function LinkField({ value, statusApi }: LinkFieldProps) {
409
fill: color, // foreground color
410
background: null, // color or null for transparent
411
size: 300 // in pixels
412
- }, canvas);
412
+ }, canvas)
413
} catch (error) {
414
- console.error('Error generating QR code:', error);
414
+ console.error('Error generating QR code:', error)
415
}
416
}
417
}
admin/src/FilePicker.ts
+2
-2
@@ -108,7 +108,7 @@ export default function FilePicker({ onSelect, multiple=true, files=true, folder
108
},
109
sx: { flex: 1, display: 'flex', flexDirection: 'column' }
110
},
111
- !list.length ? h(Center, { flex: 1, mt: '4em' }, connecting ? spinner() : "No elements in this folder")
111
+ !list.length ? h(Center as any, { sx: { flex: 1 }, mt: '4em' }, connecting ? spinner() : "No elements in this folder")
112
: h(FixedSizeList, {
113
width: '100%', height: listHeight,
114
itemSize: 46, itemCount: filteredList.length, overscanCount: 5,
@@ -194,4 +194,4 @@ export function ListLsItem({ it }: { it: LsEntry }) {
194
ml: 4, mr: 1,
195
}, formatBytes(it.s))
196
)
197
-}
\ No newline at end of file
197
+}
admin/src/InstalledPlugins.ts
+3
-3
@@ -18,14 +18,14 @@ import { showPluginOptions, evalWrapper } from './pluginOptions'
18
19
// updates=true will show the "check updates" version of the page
20
export default function InstalledPlugins({ updates }: { updates?: true }) {
21
- const { list, error, setList, initializing } = useApiList(updates ? 'get_plugin_updates' : 'get_plugins', {}, {
21
+ const { list, error, setList, initializing } = useApiList<any>(updates ? 'get_plugin_updates' : 'get_plugins', {}, {
22
map(x: any) { x.config &&= tryJson(x.config, s => evalWrapper('()=>('+s+')')()) }
23
})
24
const [sortAgain, setSortAgain] = useState(0)
25
useEffect(() => {
26
setList(list =>
27
_.sortBy(list, x => (x.error ? 0 : x.started ? 1 : x.badApi ? 2 : 3) + treatPluginName(x.repo?.split('/').reverse().join('/') || x.id).toLowerCase()))
28
- }, [list.length, sortAgain]);
28
+ }, [list.length, sortAgain])
29
const size = 'small'
30
const { pause, pauseButton } = usePauseButton("plugins", () => getSingleConfig(CFG.suspend_plugins).then(x => !x), {
31
async onClick() {
@@ -52,7 +52,7 @@ export default function InstalledPlugins({ updates }: { updates?: true }) {
52
flex: .3,
53
minWidth: 150,
54
renderCell: renderName,
55
- valueGetter({ row }) { return row.repo || row.id },
55
+ valueGetter(_value: any, row: any) { return row.repo || row.id },
56
mergeRender: { [updates ? 'changelog' : 'description']: { fontSize: 'x-small' } }
57
},
58
{
admin/src/LangPage.ts
+1
-1
@@ -35,7 +35,7 @@ export default function LangPage({ setTitleSide }: PageProps) {
35
{
36
field: 'code',
37
width: 110,
38
- valueFormatter: ({ value }) => value?.toUpperCase(),
38
+ valueFormatter: (value: string | undefined) => value?.toUpperCase(),
39
},
40
{
41
field: 'version',
admin/src/LogsPage.ts
+11
-11
@@ -13,7 +13,7 @@ import {
13
import {
14
NetmaskField, Flex, IconBtn, useBreakpoint, usePauseButton, useToggleButton, Country,
15
hTooltip, Btn, wikiLink
16
-} from './mui';
16
+} from './mui'
17
import _ from 'lodash'
18
import {
19
AutoDelete, LinkOff, ClearAll, Delete, Download, Settings, SmartToy, Terminal, ContentCopy
@@ -21,7 +21,7 @@ import {
21
import { ConfigForm } from './ConfigForm'
22
import { BoolField, SelectField } from '@hfs/mui-grid-form'
23
import { toast, useDialogBarColors } from './dialog'
24
-import { BlockIpBtn } from './blockIp';
24
+import { BlockIpBtn } from './blockIp'
25
import { ALL as COUNTRIES } from './countries'
26
27
const logLabels = {
@@ -160,7 +160,7 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
160
headerName: "Timestamp",
161
type: 'dateTime',
162
width: 96,
163
- valueGetter: ({ value }) => new Date(value as string),
163
+ valueGetter: (value) => new Date(value as string),
164
renderCell: ({ value }) => h(Fragment, {}, value.toLocaleDateString(), h('br'), value.toLocaleTimeString())
165
}
166
const ipColumn: DataTableColumn = {
@@ -236,7 +236,7 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
236
field: 'msg',
237
headerName: "Message",
238
flex: 1,
239
- mergeRender: { k: { override: { valueFormatter: ({ value }) => value !== 'log' && value } } }
239
+ mergeRender: { k: { override: { valueFormatter: (value) => value !== 'log' && value } } }
240
}
241
] : isIps || file === 'disconnections' ? [
242
tsColumn,
@@ -246,7 +246,7 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
246
field: 'country',
247
flex: 1,
248
hideUnder: !showCountry || 'md',
249
- valueGetter: ({ value }) => _.find(COUNTRIES, { code: value })?.name || value,
249
+ valueGetter: (value) => _.find(COUNTRIES, { code: value })?.name || value,
250
renderCell: ({ row }) => h(Country, { code: row.country, long: true, def: '-' }),
251
},
252
!isIps && {
@@ -259,7 +259,7 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
259
{
260
headerName: "Country",
261
field: 'country',
262
- valueGetter: ({ row }) => row.extra?.country,
262
+ valueGetter: (_value: any, row: any) => row.extra?.country,
263
hideUnder: !showCountry || 'xl',
264
renderCell: ({ value }) => h(Country, { code: value, def: '-' }),
265
},
@@ -284,21 +284,21 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
284
width: 70,
285
hideUnder: 'xl',
286
renderCell: ({ value }) => hTooltip(prefix(value + ' - ', httpCodes[value]) || "Unknown", undefined,
287
- h(Box, { bgcolor: '#888a', color: '#fff', borderRadius: '.3em', p: '.05em .2em' }, value))
287
+ h(Box, { bgcolor: '#888a', color: '#fff', borderRadius: '.3em', p: '.05em .3em', lineHeight: '1.2em' }, value))
288
},
289
{
290
field: 'length',
291
headerName: "Size",
292
type: 'number',
293
hideUnder: 'md',
294
- valueFormatter: ({ value }) => formatBytes(value as number)
294
+ valueFormatter: (value) => formatBytes(value as number)
295
},
296
{
297
headerName: "Agent",
298
field: 'ua',
299
width: 60,
300
hideUnder: !showAgent || 'md',
301
- valueGetter: ({ row }) => row.extra?.ua,
301
+ valueGetter: (_value: any, row: any) => row.extra?.ua,
302
renderCell: ({ value }) => agentIcons(value),
303
},
304
{
@@ -322,7 +322,7 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
322
if (_.isArray(ul))
323
return path + ul.join(' + ')
324
if (!path.startsWith(API_URL))
325
- return [path, query && h(Box, { key: 0, component: 'span', color: 'text.secondary', fontSize: 'smaller' }, '?', query)]
325
+ return [path, query && h(Box as any, { key: 0, component: 'span', color: 'text.secondary', fontSize: 'smaller' }, '?', query)]
326
const name = path.slice(API_URL.length)
327
const params = query && ': ' + Array.from(new URLSearchParams(query)).map(x => `${x[0]}=${tryJson(x[1]) ?? x[1]}`).join(' ; ')
328
return "API " + name + params
@@ -330,7 +330,7 @@ export function LogFile({ file, footerSide, hidden, limit, filter, ...rest }: Lo
330
},
331
{
332
field: 'agentText',
333
- valueGetter: ({ row }) => row.extra?.ua,
333
+ valueGetter: (_value: any, row: any) => row.extra?.ua,
334
headerName: "Agent text",
335
flex: 2,
336
hideUnder: true,
admin/src/MonitorPage.ts
+9
-7
@@ -189,7 +189,7 @@ function Connections() {
189
type: 'dateTime',
190
width: 96,
191
hideUnder: 'lg',
192
- valueFormatter: ({ value }) => new Date(value as string).toLocaleTimeString()
192
+ valueFormatter: (value) => new Date(value as string).toLocaleTimeString()
193
},
194
{
195
field: 'path',
@@ -197,17 +197,19 @@ function Connections() {
197
flex: 1.5,
198
renderCell({ value, row }) {
199
if (!value || !row.op) return
200
+ const rowContentSx = { display: 'flex', alignItems: 'center', height: '100%', minWidth: 0, gap: 1 } as const
201
if (row.op === 'browsing')
201
- return h(Box, {}, value, h(Box, { fontSize: 'x-small' }, "browsing"))
202
- return h(Fragment, {},
202
+ return h(Box, { sx: rowContentSx }, h(Box, {}, value, h(Box, { fontSize: 'x-small' }, "browsing")))
203
+ // keep icon and filename on the same row: datagrid v7 wraps cell content differently than before
204
+ return h(Box, { sx: rowContentSx },
205
h(IconProgress, {
206
icon: row.archive ? FolderZip : row.op === 'upload' ? Upload : Download,
207
progress: row.opProgress ?? row.opOffset,
208
offset: row.opOffset,
209
title: md(formatPerc(row.opProgress) + (row.opTotal ? "\nTotal: " + formatBytes(row.opTotal) : '')),
208
- sx: { mr: 1 }
210
}),
210
- row.archive ? h(Box, {}, value, h(Box, {
211
+ // clamp line-height locally so this cell doesn't inherit tall line metrics from datagrid wrappers
212
+ h(Box, { lineHeight: '1.2em', minWidth: 0 }, row.archive ? h(Box, {}, value, h(Box, {
213
fontSize: 'x-small',
214
color: 'text.secondary'
215
}, row.archive))
@@ -216,7 +218,7 @@ function Connections() {
218
fontSize: 'x-small',
219
color: 'text.secondary'
220
}, value.slice(0, i))
219
- )),
221
+ ))),
222
)
223
}
224
},
@@ -281,4 +283,4 @@ function Connections() {
283
284
function formatSpeedK(value: number | undefined) {
285
return value === undefined ? '' : formatSpeed(value * 1000, { digits: 1 })
284
-}
\ No newline at end of file
286
+}
admin/src/OnlinePlugins.ts
+2
-2
@@ -53,7 +53,7 @@ export default function OnlinePlugins() {
53
{
54
field: 'pushed_at',
55
headerName: "last update",
56
- valueGetter: ({ value }) => new Date(value).toLocaleDateString(),
56
+ valueGetter: (value) => new Date(value).toLocaleDateString(),
57
},
58
{
59
field: 'license',
@@ -146,4 +146,4 @@ async function installPlugin(id: string, branch?: string): Promise<any> {
146
return installPlugin(id, branch)
147
throw e
148
}
149
-}
\ No newline at end of file
149
+}
admin/src/VfsPage.ts
+1
-1
@@ -128,7 +128,7 @@ export default function VfsPage({ setTitleSide }: PageProps) {
128
vfsNodeIcon(selectedFiles[0] as VfsNodeAdmin),
129
h(Flex, { flexWrap: 'wrap', gap: '0 0.5em' },
130
selectedFiles[0].name || "Home",
131
- h(Box, { component: 'span', color: 'text.secondary' }, ancestors.join(' /'))
131
+ h(Box, { component: 'span', color: 'text.secondary' } as any, ancestors.join(' /'))
132
)
133
),
134
dialogProps: { sx: { justifyContent: 'flex-end' } },
admin/src/VfsTree.ts
+37
-33
@@ -2,7 +2,7 @@
2
3
import { markVfsModified, prepareVfsUndo, state, useSnapState } from './state'
4
import { createElement as h, ReactElement, useCallback, useEffect, useRef, MouseEvent } from 'react'
5
-import { TreeItem, TreeView } from '@mui/x-tree-view'
5
+import { TreeItem, SimpleTreeView } from '@mui/x-tree-view'
6
import {
7
ChevronRight, ExpandMore, TheaterComedy, Folder, Home, Link, InsertDriveFileOutlined, Lock,
8
RemoveRedEye, Web, Upload, Cloud, Delete, HighlightOff, UnfoldMore, UnfoldLess
@@ -46,31 +46,30 @@ export default function VfsTree({ statusApi }:{ statusApi: ApiObject }) {
46
}
47
},
48
onDoubleClick: toggle,
49
- label:
50
- h(Box, {
51
- draggable: !isRoot,
52
- onDragStart() {
53
- dragging.current = id
54
- },
55
- onDragOver(ev) {
56
- if (!isFolder) return
57
- const src = dragging.current
58
- if (src?.startsWith(id) && !src.slice(id.length + 1, -1).includes('/')) return // dragging node (src) must not be direct child of destination (id)
59
- ev.preventDefault()
60
- },
61
- async onDrop() {
62
- const from = dragging.current
63
- if (!from) return
64
- const fromName = id2vfsNode.get(from)?.name // won't work after moving
49
+ label: h(Box, {
50
+ draggable: !isRoot,
51
+ onDragStart() {
52
+ dragging.current = id
53
+ },
54
+ onDragOver(ev) {
55
+ if (!isFolder) return
56
+ const src = dragging.current
57
+ if (src?.startsWith(id) && !src.slice(id.length + 1, -1).includes('/')) return // dragging node (src) must not be direct child of destination (id)
58
+ ev.preventDefault()
59
+ },
60
+ async onDrop() {
61
+ const from = dragging.current
62
+ if (!from) return
63
+ const fromName = id2vfsNode.get(from)?.name // won't work after moving
64
if (moveVfs(from, id))
65
toast(`Moved "${fromName}" under "${id2vfsNode.get(id)?.name}"`, 'success')
67
- },
68
- sx: {
69
- display: 'flex',
70
- gap: '.5em',
71
- minHeight: '1.8em', pt: '.2em', // comfy, make single-line ones taller
72
- }
66
},
67
+ sx: {
68
+ display: 'flex',
69
+ gap: '.5em',
70
+ minHeight: '1.8em', pt: '.2em', // comfy, make single-line ones taller
71
+ }
72
+ },
73
h(Box, { display: 'flex', flex: 0, },
74
vfsNodeIcon(node),
75
// attributes, as icons
@@ -94,11 +93,9 @@ export default function VfsTree({ statusApi }:{ statusApi: ApiObject }) {
93
),
94
isRoot ? "Home folder" : name
95
),
97
- collapseIcon: h(ExpandMore, { onClick: toggle }),
98
- expandIcon: h(ChevronRight, { onClick: toggle }),
99
- nodeId: id
96
+ itemId: id
97
}, with_(node.source && isFolder ? "files from " + node.source : !node.children?.length && isRoot && "nothing here", x =>
101
- x && h(TreeItem, { nodeId: SPECIAL_TREE_ITEM + id, label: h('i', {}, x) })),
98
+ x && h(TreeItem, { itemId: SPECIAL_TREE_ITEM + id, label: h('i', {}, x) })),
99
...node.children?.map(x => h(Branch, { key: x.id, node: x })) || []
100
)
101
@@ -141,10 +138,10 @@ export default function VfsTree({ statusApi }:{ statusApi: ApiObject }) {
138
h(Typography, { variant: 'h6' }, "Virtual File System"),
139
h(VfsMenuBar, { statusApi, add: toggleBtn }),
140
),
144
- vfs && h(TreeView, {
141
+ vfs && h(SimpleTreeView, {
142
ref,
146
- expanded: toMutable(expanded),
147
- selected: selectedFiles.map(x => x.id),
143
+ expandedItems: toMutable(expanded),
144
+ selectedItems: selectedFiles.map(x => x.id),
145
multiSelect: true,
146
id: treeId,
147
sx: {
@@ -153,10 +150,17 @@ export default function VfsTree({ statusApi }:{ statusApi: ApiObject }) {
150
maxWidth: ref.current && `calc(100vw - ${16 + ref.current.offsetLeft}px)`, // limit possible horizontal scrolling to this element
151
'& ul': { borderLeft: '1px dashed #444', marginLeft: '15px', paddingLeft: '15px' },
152
},
156
- onNodeSelect(_ev, ids) {
157
- state.selectedFiles = onlyTruthy(wantArray(ids).map(id => id2vfsNode.get(id)))
153
+ slots: {
154
+ collapseIcon: ExpandMore,
155
+ expandIcon: ChevronRight,
156
+ },
157
+ onSelectedItemsChange(_ev, ids) {
158
+ const selectedIds = wantArray(ids) as string[]
159
+ state.selectedFiles = onlyTruthy(selectedIds.map(id => id2vfsNode.get(id)))
160
// this is the only point where we have special node ids that don't fit selectedFiles
159
- state.vfsShowDiskContentFor = ids.length === 1 && ids[0]?.[0] === SPECIAL_TREE_ITEM && id2vfsNode.get(ids[0].slice(1))?.source || ''
161
+ state.vfsShowDiskContentFor = selectedIds.length === 1
162
+ && selectedIds[0][0] === SPECIAL_TREE_ITEM
163
+ && id2vfsNode.get(selectedIds[0].slice(1))?.source || ''
164
}
165
}, h(Branch, { node: vfs as Readonly<VfsNodeAdmin> }))
166
)
admin/src/index.scss
+7
-1
@@ -36,12 +36,18 @@ form { max-width: 100%; } // make fields with unbreakable text (LinkField) to no
36
.MuiSvgIcon-root {
37
vertical-align: bottom;
38
}
39
-div.MuiTreeItem-content { padding: 0; } // remove wasting horizontal padding
39
+div.MuiTreeItem-content {
40
+ padding-top: 1px; // denser
41
+ padding-bottom: 0;
42
+}
43
.MuiDataGrid-columnHeaders {
44
background-color: #8882;
45
}
46
+.MuiDataGrid-virtualScrollerRenderZone .MuiDataGrid-row // make it heavier
47
.MuiDataGrid-cell {
48
line-height: 1.2em;
49
+ display: flex;
50
+ align-items: center;
51
}
52
.MuiDataGrid-filterForm { flex-wrap: wrap; justify-content: space-evenly; row-gap: 1em; } // fit on mobile
53
admin/src/mui.ts
+13
-13
@@ -8,14 +8,13 @@ import {
8
ForwardedRef, useState, useMemo, isValidElement, ElementType
9
} from 'react'
10
import { Box, BoxProps, Breakpoint, ButtonProps, CircularProgress, IconButton, IconButtonProps, Link, LinkProps,
11
- Tooltip, TooltipProps, useMediaQuery } from '@mui/material'
11
+ Tooltip, TooltipProps, useMediaQuery, Button } from '@mui/material'
12
import {
13
anyDialogOpen, closeDialog, formatPerc, isIpLan, isIpLocalHost, prefix, WIKI_URL, with_, Functionable, callable
14
} from './misc'
15
import { dontBotherWithKeys, restartAnimation, useBatch, useStateMounted } from '@hfs/shared'
16
import { Promisable, StringField } from '@hfs/mui-grid-form'
17
import { alertDialog, confirmDialog, toast } from './dialog'
18
-import { LoadingButton } from '@mui/lab'
18
import { Link as RouterLink, LinkProps as RouterLinkProps, useNavigate } from 'react-router-dom'
19
import { SvgIconProps } from '@mui/material/SvgIcon/SvgIcon'
20
import _ from 'lodash'
@@ -68,15 +67,15 @@ export function IconProgress({ icon, progress, offset, title, sx }: IconProgress
67
value: (offset || 1e-7) * 100,
68
variant: 'determinate',
69
size: 32,
71
- sx: { display: 'flex', ...sx }, // workaround: without this the element has 0 width when the space is crammy (monitor/file)
70
+ sx: _.defaults(sx as any, { display: 'flex' }) as any, // workaround: without this the element has 0 width when the space is crammy (monitor/file)
71
}),
72
)
73
)
74
}
75
77
-type FlexProps = SxProps & { vert?: boolean, center?: boolean, children?: ReactNode, props?: BoxProps, component?: ElementType }
76
+type FlexProps = { vert?: boolean, center?: boolean, children?: ReactNode, props?: BoxProps, component?: ElementType } & Record<string, any>
77
export function Flex({ vert=false, center=false, children=null, props={}, component, ...rest }: FlexProps) {
79
- return h(Box, {
78
+ return h(Box as any, {
79
sx: {
80
display: 'flex',
81
gap: '.8em',
@@ -84,7 +83,7 @@ export function Flex({ vert=false, center=false, children=null, props={}, compon
83
alignItems: vert ? undefined : 'center',
84
...center && { justifyContent: 'center' },
85
...rest,
87
- },
86
+ } as any,
87
component,
88
...props
89
}, children)
@@ -140,7 +139,7 @@ export interface BtnProps extends Omit<ButtonProps & IconButtonProps,'disabled'|
139
doneAnimation?: boolean
140
tooltipProps?: Partial<TooltipProps>
141
modified?: boolean
143
- loading?: boolean
142
+ loading?: boolean | null
143
onClick?: (...args: Parameters<NonNullable<ButtonProps['onClick']>>) => Promisable<any>
144
}
145
@@ -176,7 +175,8 @@ export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link,
175
},
176
} as const, rest)
177
const iconElement = isValidElement(icon) ? icon : (icon && h(icon))
179
- let ret: ReactElement = children && showLabel ? h(LoadingButton, _.merge({
178
+ let ret: ReactElement = children && showLabel ? h(Button as any, _.merge({
179
+ // mui v6 moved LoadingButton behavior into Button, but current typings here still miss loading props
180
variant: 'contained',
181
startIcon: iconElement,
182
loading: Boolean(loading || loadingState || progress),
@@ -184,7 +184,7 @@ export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link,
184
loadingIndicator: typeof progress !== 'number' ? undefined
185
: h(CircularProgress, { size: '1rem', value: progress*100, variant: 'determinate' }),
186
children: showLabel && children,
187
- } as const, common, (!showLabel || !children) && { sx: { minWidth: 'auto', px: 1, py: '7px', '& span': { mx:0 }, } }))
187
+ } as const, common, (!showLabel || !children) && { sx: { minWidth: 'auto', px: 1, py: '7px', '& span': { mx:0 }, } }) as any)
188
: h(IconButton, _.merge(common, {
189
sx: { height: 'fit-content' }, TouchRippleProps: { 'aria-hidden': true },
190
// we need a direct accessible name on the actual clickable element for testing
@@ -314,7 +314,7 @@ export function Country({ code, ip, def, long, short }: { code: string, ip?: str
314
const country = code && _.find(COUNTRIES, { code })
315
return !country ? h(Fragment, {}, def)
316
: hTooltip(long ? undefined : country.name, undefined, h('span', {},
317
- h(Box, {
317
+ h(Box as any, {
318
className: `fflag fflag-${code.toUpperCase()}`,
319
component: 'span',
320
mr: 1,
@@ -331,8 +331,8 @@ async function ip2countryBatch(ips: string[]) {
331
// force you to think of aria when adding a tooltip
332
export function hTooltip(title: ReactNode, ariaLabel: string | undefined, children: ReactElement, props?: Omit<TooltipProps, 'title' | 'children'> & { key?: any }) {
333
return h(Tooltip, { title, children,
334
- ...ariaLabel === '' ? { 'aria-hidden': true } : { 'aria-label': ariaLabel || _.isString(title) && title || undefined },
335
- componentsProps: { popper: { sx: { whiteSpace: 'pre-wrap', ...props?.sx } } },
334
+ ...(ariaLabel === '' ? { 'aria-hidden': true } : { 'aria-label': ariaLabel || _.isString(title) && title || undefined }),
335
+ componentsProps: { popper: { sx: { whiteSpace: 'pre-wrap', ...props?.sx } } } as any,
336
...props
337
})
338
-}
\ No newline at end of file
338
+}
e2e/serial.spec.ts
+31
-29
@@ -12,53 +12,55 @@ export const fileToUpload = {
12
13
test('upload1', async ({ page, context, browserName }) => {
14
if (browserName !== 'chromium') return // only chromium has cdpSession
15
- await page.goto(FRONTEND_URL);
16
- await page.getByRole('button', { name: 'Login' }).click();
17
- await page.getByRole('textbox', { name: 'Username' }).fill(username);
18
- await page.getByRole('textbox', { name: 'Password' }).fill(password);
19
- await page.getByRole('button', { name: 'Continue' }).click();
20
- await page.locator('div').filter({ hasText: 'Logged in' }).nth(3).click();
15
+ await page.goto(FRONTEND_URL)
16
+ await page.getByRole('button', { name: 'Login' }).click()
17
+ await page.getByRole('textbox', { name: 'Username' }).fill(username)
18
+ await page.getByRole('textbox', { name: 'Password' }).fill(password)
19
+ await page.getByRole('button', { name: 'Continue' }).click()
20
+ await page.locator('div').filter({ hasText: 'Logged in' }).nth(3).click()
21
22
- await page.getByRole('link', { name: 'for-admins, Folder' }).click();
23
- await page.getByRole('link', { name: 'upload, Folder' }).click();
22
+ await page.getByRole('link', { name: 'for-admins, Folder' }).click()
23
+ await page.getByRole('link', { name: 'upload, Folder' }).click()
24
25
- await page.getByRole('button', { name: 'Options' }).click();
26
- const pageAdminPromise = page.waitForEvent('popup');
27
- await page.getByRole('button', { name: 'Admin-panel' }).click();
28
- const pageAdmin = await pageAdminPromise;
25
+ await page.getByRole('button', { name: 'Options' }).click()
26
+ const pageAdminPromise = page.waitForEvent('popup')
27
+ await page.getByRole('button', { name: 'Admin-panel' }).click()
28
+ const pageAdmin = await pageAdminPromise
29
await pageAdmin.goto(ADMIN_URL + '#/monitoring'); // cross-device way of changing page
30
- await page.locator('div').filter({ hasText: 'xOptionsAdmin-panelSort by:' }).nth(2).click();
31
- await page.getByRole('button', { name: 'Close' }).click();
32
- await page.getByRole('button', { name: 'Upload' }).click();
33
- const fileChooserPromise = page.waitForEvent('filechooser');
34
- await page.getByRole('button', { name: 'Pick files' }).click();
35
- const fileChooser = await fileChooserPromise;
36
- await fileChooser.setFiles(fileToUpload);
30
+ await page.locator('div').filter({ hasText: 'xOptionsAdmin-panelSort by:' }).nth(2).click()
31
+ await page.getByRole('button', { name: 'Close' }).click()
32
+ await page.getByRole('button', { name: 'Upload' }).click()
33
+ const fileChooserPromise = page.waitForEvent('filechooser')
34
+ await page.getByRole('button', { name: 'Pick files' }).click()
35
+ const fileChooser = await fileChooserPromise
36
+ await fileChooser.setFiles(fileToUpload)
37
// can't do without cdp to slow down the upload. I tried using route.continue, but i can't send half-body keeping the full content-length, and i also cannot pass a stream (to throttle)
38
const cdpSession = await context.newCDPSession(page)
39
await cdpSession.send('Network.emulateNetworkConditions', NETWORK_PRESETS.Regular2G)
40
- await page.getByRole('button', { name: 'Edit' }).click();
40
+ await page.getByRole('button', { name: 'Edit' }).click()
41
const renameDialog = page.locator('.dialog-prompt')
42
const renameInput = renameDialog.getByRole('textbox')
43
await expect(renameInput).toHaveValue(fileToUpload.name) // promptDialog initializes the field value in useEffect, so we wait for that init to avoid our fill being overwritten
44
- await renameInput.fill(uploadName);
45
- await renameDialog.getByRole('button', { name: 'Continue' }).click();
44
+ await renameInput.fill(uploadName)
45
+ await renameDialog.getByRole('button', { name: 'Continue' }).click()
46
await expect(page.getByText(uploadName)).toBeVisible() // rename was effective
47
// we send the upload, slowly, so that we can interrupt it in the admin-panel to test the upload resume
48
- await page.getByRole('button', { name: 'Send 1 file' }).click();
49
- const uploadCells = pageAdmin.getByRole('cell', { name: `${uploadName} /for-admins/upload` })
48
+ await page.getByRole('button', { name: 'Send 1 file' }).click()
49
+ const uploadCells = pageAdmin.locator('.MuiDataGrid-cell')
50
+ .filter({ hasText: uploadName })
51
+ .filter({ hasText: '/for-admins/upload' })
52
await expect(uploadCells.first()).toBeVisible()
53
// during upload resume, monitoring can briefly show two rows for the same path
54
await uploadCells.last().click()
55
await clickIconBtn('Disconnect', pageAdmin)
56
await clickIconBtn('Close', pageAdmin)
57
await pageAdmin.close()
56
- await page.getByText('Copy links').click();
57
- await page.getByText('Operation successful').click();
58
- await page.getByRole('button', { name: 'Close' }).click();
58
+ await page.getByText('Copy links').click()
59
+ await page.getByText('Operation successful').click()
60
+ await page.getByRole('button', { name: 'Close' }).click()
61
await cdpSession?.send('Network.emulateNetworkConditions', NETWORK_PRESETS.NoThrottle)
62
clearUploads()
61
-});
63
+})
64
65
const NETWORK_PRESETS = {
66
Offline: {
@@ -81,7 +83,7 @@ const NETWORK_PRESETS = {
83
latency: 300,
84
connectionType: 'cellular2g',
85
},
84
-} as const;
86
+} as const
87
88
// some interactions, no screenshots
89
test('admin2', async ({ page }) => {
mui-grid-form/index.ts
+32
-11
@@ -6,11 +6,9 @@ import {
6
} from 'react'
7
import { Box, BoxProps, Button, Tooltip } from '@mui/material'
8
import { Save } from '@mui/icons-material'
9
-import { LoadingButton } from '@mui/lab'
9
import _ from 'lodash'
10
import { StringField } from './StringField'
12
-import Grid from '@mui/material/Unstable_Grid2'
13
-import { GridProps } from '@mui/material/Grid/Grid'
11
+import Grid, { Grid2Props as GridProps } from '@mui/material/Grid2'
12
import { useDebounce } from 'usehooks-ts'
13
export * from './SelectField'
14
export * from './misc-fields'
@@ -145,12 +143,13 @@ export function Form<Values extends Dict>({
143
if (!row)
144
return null
145
if (isValidElement(row))
148
- return h(Grid, { key: idx, xs: 12 }, row)
146
+ return h(Grid, { key: idx, size: 12 }, row)
147
if (defaults)
148
row = { ...defaults?.(row), ...row }
149
const { k, fromField=_.identity, toField=_.identity, getError, error,
150
xs=12, sm, md, lg, xl, comp=StringField, before, after, parentProps,
151
...field } = row
152
+ const size = legacySpanToGridSize({ xs, sm, md, lg, xl })
153
let errMsg = errors[k] || error || fieldExceptions[k]
154
if (errMsg === true)
155
errMsg = "Not valid"
@@ -183,8 +182,8 @@ export function Form<Values extends Dict>({
182
field.helperText = h(Fragment, {}, ...field.helperText)
183
if (errMsg) // special rendering when we have both error and helperText. "hr" would be nice but issues a warning because contained in a <p>
184
field.helperText = !field.helperText ? errMsg
186
- : h(Box, { color: 'text.primary', component: 'span' },
187
- h(Box, {
185
+ : h(Box as any, { color: 'text.primary', component: 'span' },
186
+ h(Box as any, {
187
color: 'error.main',
188
style: { borderBottom: '1px solid' },
189
component: 'span', display: 'block' // avoid console warning, but keep it on separate line
@@ -195,7 +194,7 @@ export function Form<Values extends Dict>({
194
field.label = labelFromKey(k)
195
}
196
const n = (keyMet[k] = (keyMet[k] || 0) + 1)
198
- return h(Grid, { key: k ? k + n : idx, xs, sm, md, lg, xl, className: anyError && ERROR_CLASS, ...parentProps },
197
+ return h(Grid, { key: k ? k + n : idx, size, className: anyError && ERROR_CLASS, ...parentProps },
198
before,
199
isValidElement(comp) ? comp : h(comp, field),
200
after
@@ -211,7 +210,8 @@ export function Form<Values extends Dict>({
210
position: 'sticky', bottom: 0, p: 1, m: -1, boxShadow: '0px 0px 15px #000',
211
},
212
barSx)
214
- }, h(Tooltip, { title: "ctrl + enter", children: h(LoadingButton, {
213
+ }, h(Tooltip, { title: "ctrl + enter", children: h(Button as any, {
214
+ // mui v6 moved LoadingButton behavior into Button, but current typings here still miss loading props
215
variant: 'contained',
216
startIcon: h(Save),
217
children: "Save",
@@ -220,7 +220,7 @@ export function Form<Values extends Dict>({
220
onClick() {
221
pleaseSubmitAndValidate()
222
},
223
- }) }),
223
+ } as any) }),
224
...addToBar,
225
)
226
)
@@ -254,8 +254,8 @@ export function Form<Values extends Dict>({
254
const v = getValueFor(k)
255
let err: ReactNode
256
try {
257
- err = await apis[k]?.getError?.(v, { values, fields })
258
- || await f.getError?.(v, { values, fields })
257
+ err = (await apis[k]?.getError?.(v, { values, fields }))
258
+ || (await f.getError?.(v, { values, fields }))
259
|| fieldExceptions[k]
260
|| false
261
}
@@ -301,3 +301,24 @@ export function labelFromKey(k: string) {
301
return _.upperFirst(k.indexOf('_') > 0 ? k.replace(/_/g, ' ')
302
: k.replace(/([a-z])([A-Z])/g, (_all, a, b) => a + ' ' + b.toLowerCase()))
303
}
304
+
305
+function legacySpanToGridSize({ xs, sm, md, lg, xl }: { xs?: unknown, sm?: unknown, md?: unknown, lg?: unknown, xl?: unknown }) {
306
+ // keep compatibility with existing form descriptors still using xs/sm/md while grid2 expects size
307
+ const sizeByBreakpoint = {
308
+ xs: normalizeLegacySpan(xs),
309
+ sm: normalizeLegacySpan(sm),
310
+ md: normalizeLegacySpan(md),
311
+ lg: normalizeLegacySpan(lg),
312
+ xl: normalizeLegacySpan(xl),
313
+ }
314
+ if (sm === undefined && md === undefined && lg === undefined && xl === undefined)
315
+ return sizeByBreakpoint.xs
316
+ return sizeByBreakpoint as any
317
+}
318
+
319
+function normalizeLegacySpan(span: unknown) {
320
+ // in legacy Grid, `true` means auto-grow width; in grid2 this is expressed with `size="grow"`
321
+ if (span === true)
322
+ return 'grow'
323
+ return span
324
+}
package-lock.json
+614
-374
@@ -80,12 +80,12 @@
80
"@gregoranders/csv": "^0.0.13",
81
"@hfs/mui-grid-form": "*",
82
"@hfs/shared": "*",
83
- "@mui/icons-material": "^5.18.0",
84
- "@mui/lab": "^5.0.0-alpha.177",
85
- "@mui/material": "^5.18.0",
86
- "@mui/x-data-grid": "^6.20.4",
87
- "@mui/x-date-pickers": "^6.20.2",
88
- "@mui/x-tree-view": "^6.17.0",
83
+ "@mui/icons-material": "^6.4.11",
84
+ "@mui/lab": "^6.0.1-beta.34",
85
+ "@mui/material": "^6.4.11",
86
+ "@mui/x-data-grid": "^7.29.0",
87
+ "@mui/x-date-pickers": "^7.29.0",
88
+ "@mui/x-tree-view": "^7.29.0",
89
"dayjs": "^1.11.10",
90
"immer": "*",
91
"prismjs": "^1.29.0",
@@ -106,35 +106,122 @@
106
"vite": "^6.4.1"
107
}
108
},
109
- "admin/node_modules/@mui/x-data-grid": {
110
- "version": "6.20.4",
111
- "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.20.4.tgz",
112
- "integrity": "sha512-I0JhinVV4e25hD2dB+R6biPBtpGeFrXf8RwlMPQbr9gUggPmPmNtWKo8Kk2PtBBMlGtdMAgHWe7PqhmucUxU1w==",
109
+ "admin/node_modules/@mui/icons-material": {
110
+ "version": "6.5.0",
111
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.5.0.tgz",
112
+ "integrity": "sha512-VPuPqXqbBPlcVSA0BmnoE4knW4/xG6Thazo8vCLWkOKusko6DtwFV6B665MMWJ9j0KFohTIf3yx2zYtYacvG1g==",
113
+ "license": "MIT",
114
"dependencies": {
114
- "@babel/runtime": "^7.23.2",
115
- "@mui/utils": "^5.14.16",
116
- "clsx": "^2.0.0",
117
- "prop-types": "^15.8.1",
118
- "reselect": "^4.1.8"
115
+ "@babel/runtime": "^7.26.0"
116
+ },
117
+ "engines": {
118
+ "node": ">=14.0.0"
119
+ },
120
+ "funding": {
121
+ "type": "opencollective",
122
+ "url": "https://opencollective.com/mui-org"
123
+ },
124
+ "peerDependencies": {
125
+ "@mui/material": "^6.5.0",
126
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
127
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
128
+ },
129
+ "peerDependenciesMeta": {
130
+ "@types/react": {
131
+ "optional": true
132
+ }
133
+ }
134
+ },
135
+ "admin/node_modules/@mui/lab": {
136
+ "version": "6.0.1-beta.36",
137
+ "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.1-beta.36.tgz",
138
+ "integrity": "sha512-af9lDmA9SZGEWF1XXk0EVBpfCITk9IKsvh9lLOZGdYaaHfQeCsqxGEDMvNO66j0P8EYoxpyry84LFCJYuLVtVw==",
139
+ "license": "MIT",
140
+ "dependencies": {
141
+ "@babel/runtime": "^7.26.0",
142
+ "@mui/base": "5.0.0-beta.70",
143
+ "@mui/system": "^6.5.0",
144
+ "@mui/types": "~7.2.24",
145
+ "@mui/utils": "^6.4.9",
146
+ "clsx": "^2.1.1",
147
+ "prop-types": "^15.8.1"
148
+ },
149
+ "engines": {
150
+ "node": ">=14.0.0"
151
+ },
152
+ "funding": {
153
+ "type": "opencollective",
154
+ "url": "https://opencollective.com/mui-org"
155
+ },
156
+ "peerDependencies": {
157
+ "@emotion/react": "^11.5.0",
158
+ "@emotion/styled": "^11.3.0",
159
+ "@mui/material": "^6.5.0",
160
+ "@mui/material-pigment-css": "^6.5.0",
161
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
162
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
163
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
164
+ },
165
+ "peerDependenciesMeta": {
166
+ "@emotion/react": {
167
+ "optional": true
168
+ },
169
+ "@emotion/styled": {
170
+ "optional": true
171
+ },
172
+ "@mui/material-pigment-css": {
173
+ "optional": true
174
+ },
175
+ "@types/react": {
176
+ "optional": true
177
+ }
178
+ }
179
+ },
180
+ "admin/node_modules/@mui/lab/node_modules/@mui/base": {
181
+ "version": "5.0.0-beta.70",
182
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.70.tgz",
183
+ "integrity": "sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ==",
184
+ "deprecated": "This package has been replaced by @base-ui/react",
185
+ "license": "MIT",
186
+ "dependencies": {
187
+ "@babel/runtime": "^7.26.0",
188
+ "@floating-ui/react-dom": "^2.1.1",
189
+ "@mui/types": "~7.2.24",
190
+ "@mui/utils": "^6.4.8",
191
+ "@popperjs/core": "^2.11.8",
192
+ "clsx": "^2.1.1",
193
+ "prop-types": "^15.8.1"
194
},
195
"engines": {
196
"node": ">=14.0.0"
197
},
198
"funding": {
199
"type": "opencollective",
125
- "url": "https://opencollective.com/mui"
200
+ "url": "https://opencollective.com/mui-org"
201
},
202
"peerDependencies": {
128
- "@mui/material": "^5.4.1",
129
- "@mui/system": "^5.4.1",
130
- "react": "^17.0.0 || ^18.0.0",
131
- "react-dom": "^17.0.0 || ^18.0.0"
203
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
204
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
205
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
206
+ },
207
+ "peerDependenciesMeta": {
208
+ "@types/react": {
209
+ "optional": true
210
+ }
211
}
212
},
134
- "admin/node_modules/reselect": {
135
- "version": "4.1.8",
136
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
137
- "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
213
+ "admin/node_modules/@mui/lab/node_modules/@mui/base/node_modules/@floating-ui/react-dom": {
214
+ "version": "2.1.8",
215
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
216
+ "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==",
217
+ "license": "MIT",
218
+ "dependencies": {
219
+ "@floating-ui/dom": "^1.7.6"
220
+ },
221
+ "peerDependencies": {
222
+ "react": ">=16.8.0",
223
+ "react-dom": ">=16.8.0"
224
+ }
225
},
226
"frontend": {
227
"name": "@hfs/frontend",
@@ -200,6 +287,123 @@
287
"react-dom": "*"
288
}
289
},
290
+ "mui-grid-form/node_modules/@mui/icons-material": {
291
+ "version": "6.5.0",
292
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.5.0.tgz",
293
+ "integrity": "sha512-VPuPqXqbBPlcVSA0BmnoE4knW4/xG6Thazo8vCLWkOKusko6DtwFV6B665MMWJ9j0KFohTIf3yx2zYtYacvG1g==",
294
+ "license": "MIT",
295
+ "dependencies": {
296
+ "@babel/runtime": "^7.26.0"
297
+ },
298
+ "engines": {
299
+ "node": ">=14.0.0"
300
+ },
301
+ "funding": {
302
+ "type": "opencollective",
303
+ "url": "https://opencollective.com/mui-org"
304
+ },
305
+ "peerDependencies": {
306
+ "@mui/material": "^6.5.0",
307
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
308
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
309
+ },
310
+ "peerDependenciesMeta": {
311
+ "@types/react": {
312
+ "optional": true
313
+ }
314
+ }
315
+ },
316
+ "mui-grid-form/node_modules/@mui/lab": {
317
+ "version": "6.0.1-beta.36",
318
+ "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.1-beta.36.tgz",
319
+ "integrity": "sha512-af9lDmA9SZGEWF1XXk0EVBpfCITk9IKsvh9lLOZGdYaaHfQeCsqxGEDMvNO66j0P8EYoxpyry84LFCJYuLVtVw==",
320
+ "license": "MIT",
321
+ "dependencies": {
322
+ "@babel/runtime": "^7.26.0",
323
+ "@mui/base": "5.0.0-beta.70",
324
+ "@mui/system": "^6.5.0",
325
+ "@mui/types": "~7.2.24",
326
+ "@mui/utils": "^6.4.9",
327
+ "clsx": "^2.1.1",
328
+ "prop-types": "^15.8.1"
329
+ },
330
+ "engines": {
331
+ "node": ">=14.0.0"
332
+ },
333
+ "funding": {
334
+ "type": "opencollective",
335
+ "url": "https://opencollective.com/mui-org"
336
+ },
337
+ "peerDependencies": {
338
+ "@emotion/react": "^11.5.0",
339
+ "@emotion/styled": "^11.3.0",
340
+ "@mui/material": "^6.5.0",
341
+ "@mui/material-pigment-css": "^6.5.0",
342
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
343
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
344
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
345
+ },
346
+ "peerDependenciesMeta": {
347
+ "@emotion/react": {
348
+ "optional": true
349
+ },
350
+ "@emotion/styled": {
351
+ "optional": true
352
+ },
353
+ "@mui/material-pigment-css": {
354
+ "optional": true
355
+ },
356
+ "@types/react": {
357
+ "optional": true
358
+ }
359
+ }
360
+ },
361
+ "mui-grid-form/node_modules/@mui/lab/node_modules/@mui/base": {
362
+ "version": "5.0.0-beta.70",
363
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.70.tgz",
364
+ "integrity": "sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ==",
365
+ "deprecated": "This package has been replaced by @base-ui/react",
366
+ "license": "MIT",
367
+ "dependencies": {
368
+ "@babel/runtime": "^7.26.0",
369
+ "@floating-ui/react-dom": "^2.1.1",
370
+ "@mui/types": "~7.2.24",
371
+ "@mui/utils": "^6.4.8",
372
+ "@popperjs/core": "^2.11.8",
373
+ "clsx": "^2.1.1",
374
+ "prop-types": "^15.8.1"
375
+ },
376
+ "engines": {
377
+ "node": ">=14.0.0"
378
+ },
379
+ "funding": {
380
+ "type": "opencollective",
381
+ "url": "https://opencollective.com/mui-org"
382
+ },
383
+ "peerDependencies": {
384
+ "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
385
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
386
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
387
+ },
388
+ "peerDependenciesMeta": {
389
+ "@types/react": {
390
+ "optional": true
391
+ }
392
+ }
393
+ },
394
+ "mui-grid-form/node_modules/@mui/lab/node_modules/@mui/base/node_modules/@floating-ui/react-dom": {
395
+ "version": "2.1.8",
396
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
397
+ "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==",
398
+ "license": "MIT",
399
+ "dependencies": {
400
+ "@floating-ui/dom": "^1.7.6"
401
+ },
402
+ "peerDependencies": {
403
+ "react": ">=16.8.0",
404
+ "react-dom": ">=16.8.0"
405
+ }
406
+ },
407
"node_modules/@ampproject/remapping": {
408
"version": "2.3.0",
409
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -2434,38 +2638,29 @@
2638
}
2639
},
2640
"node_modules/@floating-ui/core": {
2437
- "version": "1.6.0",
2438
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz",
2439
- "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==",
2641
+ "version": "1.7.5",
2642
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
2643
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
2644
+ "license": "MIT",
2645
"dependencies": {
2441
- "@floating-ui/utils": "^0.2.1"
2646
+ "@floating-ui/utils": "^0.2.11"
2647
}
2648
},
2649
"node_modules/@floating-ui/dom": {
2445
- "version": "1.6.1",
2446
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz",
2447
- "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==",
2650
+ "version": "1.7.6",
2651
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
2652
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
2653
+ "license": "MIT",
2654
"dependencies": {
2449
- "@floating-ui/core": "^1.6.0",
2450
- "@floating-ui/utils": "^0.2.1"
2451
- }
2452
- },
2453
- "node_modules/@floating-ui/react-dom": {
2454
- "version": "2.0.8",
2455
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz",
2456
- "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==",
2457
- "dependencies": {
2458
- "@floating-ui/dom": "^1.6.1"
2459
- },
2460
- "peerDependencies": {
2461
- "react": ">=16.8.0",
2462
- "react-dom": ">=16.8.0"
2655
+ "@floating-ui/core": "^1.7.5",
2656
+ "@floating-ui/utils": "^0.2.11"
2657
}
2658
},
2659
"node_modules/@floating-ui/utils": {
2466
- "version": "0.2.1",
2467
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz",
2468
- "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q=="
2660
+ "version": "0.2.11",
2661
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
2662
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==",
2663
+ "license": "MIT"
2664
},
2665
"node_modules/@gregoranders/csv": {
2666
"version": "0.0.13",
@@ -2559,137 +2754,37 @@
2754
"@jridgewell/sourcemap-codec": "^1.4.14"
2755
}
2756
},
2562
- "node_modules/@mui/base": {
2563
- "version": "5.0.0-beta.40-1",
2564
- "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40-1.tgz",
2565
- "integrity": "sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA==",
2566
- "deprecated": "This package has been replaced by @base-ui-components/react",
2567
- "license": "MIT",
2568
- "dependencies": {
2569
- "@babel/runtime": "^7.23.9",
2570
- "@floating-ui/react-dom": "^2.0.8",
2571
- "@mui/types": "~7.2.15",
2572
- "@mui/utils": "^5.17.1",
2573
- "@popperjs/core": "^2.11.8",
2574
- "clsx": "^2.1.0",
2575
- "prop-types": "^15.8.1"
2576
- },
2577
- "engines": {
2578
- "node": ">=12.0.0"
2579
- },
2580
- "funding": {
2581
- "type": "opencollective",
2582
- "url": "https://opencollective.com/mui-org"
2583
- },
2584
- "peerDependencies": {
2585
- "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2586
- "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2587
- "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
2588
- },
2589
- "peerDependenciesMeta": {
2590
- "@types/react": {
2591
- "optional": true
2592
- }
2593
- }
2594
- },
2757
"node_modules/@mui/core-downloads-tracker": {
2596
- "version": "5.18.0",
2597
- "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz",
2598
- "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==",
2599
- "license": "MIT",
2600
- "funding": {
2601
- "type": "opencollective",
2602
- "url": "https://opencollective.com/mui-org"
2603
- }
2604
- },
2605
- "node_modules/@mui/icons-material": {
2606
- "version": "5.18.0",
2607
- "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.18.0.tgz",
2608
- "integrity": "sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg==",
2609
- "license": "MIT",
2610
- "dependencies": {
2611
- "@babel/runtime": "^7.23.9"
2612
- },
2613
- "engines": {
2614
- "node": ">=12.0.0"
2615
- },
2616
- "funding": {
2617
- "type": "opencollective",
2618
- "url": "https://opencollective.com/mui-org"
2619
- },
2620
- "peerDependencies": {
2621
- "@mui/material": "^5.0.0",
2622
- "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2623
- "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
2624
- },
2625
- "peerDependenciesMeta": {
2626
- "@types/react": {
2627
- "optional": true
2628
- }
2629
- }
2630
- },
2631
- "node_modules/@mui/lab": {
2632
- "version": "5.0.0-alpha.177",
2633
- "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.177.tgz",
2634
- "integrity": "sha512-bdCxxtNjlWAgN9rtrwlmFydJ1qxA3IIbb6OlomGFsIXw0zGoHomLyjvh72q/R3yUAC0kvSef18cHY1UalLylyQ==",
2758
+ "version": "6.5.0",
2759
+ "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.5.0.tgz",
2760
+ "integrity": "sha512-LGb8t8i6M2ZtS3Drn3GbTI1DVhDY6FJ9crEey2lZ0aN2EMZo8IZBZj9wRf4vqbZHaWjsYgtbOnJw5V8UWbmK2Q==",
2761
"license": "MIT",
2636
- "dependencies": {
2637
- "@babel/runtime": "^7.23.9",
2638
- "@mui/base": "5.0.0-beta.40-1",
2639
- "@mui/system": "^5.18.0",
2640
- "@mui/types": "~7.2.15",
2641
- "@mui/utils": "^5.17.1",
2642
- "clsx": "^2.1.0",
2643
- "prop-types": "^15.8.1"
2644
- },
2645
- "engines": {
2646
- "node": ">=12.0.0"
2647
- },
2762
"funding": {
2763
"type": "opencollective",
2764
"url": "https://opencollective.com/mui-org"
2651
- },
2652
- "peerDependencies": {
2653
- "@emotion/react": "^11.5.0",
2654
- "@emotion/styled": "^11.3.0",
2655
- "@mui/material": ">=5.15.0",
2656
- "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2657
- "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2658
- "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
2659
- },
2660
- "peerDependenciesMeta": {
2661
- "@emotion/react": {
2662
- "optional": true
2663
- },
2664
- "@emotion/styled": {
2665
- "optional": true
2666
- },
2667
- "@types/react": {
2668
- "optional": true
2669
- }
2765
}
2766
},
2767
"node_modules/@mui/material": {
2673
- "version": "5.18.0",
2674
- "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz",
2675
- "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==",
2768
+ "version": "6.5.0",
2769
+ "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.5.0.tgz",
2770
+ "integrity": "sha512-yjvtXoFcrPLGtgKRxFaH6OQPtcLPhkloC0BML6rBG5UeldR0nPULR/2E2BfXdo5JNV7j7lOzrrLX2Qf/iSidow==",
2771
"license": "MIT",
2772
"dependencies": {
2678
- "@babel/runtime": "^7.23.9",
2679
- "@mui/core-downloads-tracker": "^5.18.0",
2680
- "@mui/system": "^5.18.0",
2681
- "@mui/types": "~7.2.15",
2682
- "@mui/utils": "^5.17.1",
2773
+ "@babel/runtime": "^7.26.0",
2774
+ "@mui/core-downloads-tracker": "^6.5.0",
2775
+ "@mui/system": "^6.5.0",
2776
+ "@mui/types": "~7.2.24",
2777
+ "@mui/utils": "^6.4.9",
2778
"@popperjs/core": "^2.11.8",
2684
- "@types/react-transition-group": "^4.4.10",
2685
- "clsx": "^2.1.0",
2779
+ "@types/react-transition-group": "^4.4.12",
2780
+ "clsx": "^2.1.1",
2781
"csstype": "^3.1.3",
2782
"prop-types": "^15.8.1",
2783
"react-is": "^19.0.0",
2784
"react-transition-group": "^4.4.5"
2785
},
2786
"engines": {
2692
- "node": ">=12.0.0"
2787
+ "node": ">=14.0.0"
2788
},
2789
"funding": {
2790
"type": "opencollective",
@@ -2698,6 +2793,7 @@
2793
"peerDependencies": {
2794
"@emotion/react": "^11.5.0",
2795
"@emotion/styled": "^11.3.0",
2796
+ "@mui/material-pigment-css": "^6.5.0",
2797
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2798
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2799
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -2709,23 +2805,26 @@
2805
"@emotion/styled": {
2806
"optional": true
2807
},
2808
+ "@mui/material-pigment-css": {
2809
+ "optional": true
2810
+ },
2811
"@types/react": {
2812
"optional": true
2813
}
2814
}
2815
},
2816
"node_modules/@mui/private-theming": {
2718
- "version": "5.17.1",
2719
- "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz",
2720
- "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==",
2817
+ "version": "6.4.9",
2818
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.9.tgz",
2819
+ "integrity": "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==",
2820
"license": "MIT",
2821
"dependencies": {
2723
- "@babel/runtime": "^7.23.9",
2724
- "@mui/utils": "^5.17.1",
2822
+ "@babel/runtime": "^7.26.0",
2823
+ "@mui/utils": "^6.4.9",
2824
"prop-types": "^15.8.1"
2825
},
2826
"engines": {
2728
- "node": ">=12.0.0"
2827
+ "node": ">=14.0.0"
2828
},
2829
"funding": {
2830
"type": "opencollective",
@@ -2742,19 +2841,20 @@
2841
}
2842
},
2843
"node_modules/@mui/styled-engine": {
2745
- "version": "5.18.0",
2746
- "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz",
2747
- "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==",
2844
+ "version": "6.5.0",
2845
+ "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.5.0.tgz",
2846
+ "integrity": "sha512-8woC2zAqF4qUDSPIBZ8v3sakj+WgweolpyM/FXf8jAx6FMls+IE4Y8VDZc+zS805J7PRz31vz73n2SovKGaYgw==",
2847
"license": "MIT",
2848
"dependencies": {
2750
- "@babel/runtime": "^7.23.9",
2849
+ "@babel/runtime": "^7.26.0",
2850
"@emotion/cache": "^11.13.5",
2851
"@emotion/serialize": "^1.3.3",
2852
+ "@emotion/sheet": "^1.4.0",
2853
"csstype": "^3.1.3",
2854
"prop-types": "^15.8.1"
2855
},
2856
"engines": {
2757
- "node": ">=12.0.0"
2857
+ "node": ">=14.0.0"
2858
},
2859
"funding": {
2860
"type": "opencollective",
@@ -2775,22 +2875,22 @@
2875
}
2876
},
2877
"node_modules/@mui/system": {
2778
- "version": "5.18.0",
2779
- "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz",
2780
- "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==",
2878
+ "version": "6.5.0",
2879
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.5.0.tgz",
2880
+ "integrity": "sha512-XcbBYxDS+h/lgsoGe78ExXFZXtuIlSBpn/KsZq8PtZcIkUNJInkuDqcLd2rVBQrDC1u+rvVovdaWPf2FHKJf3w==",
2881
"license": "MIT",
2882
"dependencies": {
2783
- "@babel/runtime": "^7.23.9",
2784
- "@mui/private-theming": "^5.17.1",
2785
- "@mui/styled-engine": "^5.18.0",
2786
- "@mui/types": "~7.2.15",
2787
- "@mui/utils": "^5.17.1",
2788
- "clsx": "^2.1.0",
2883
+ "@babel/runtime": "^7.26.0",
2884
+ "@mui/private-theming": "^6.4.9",
2885
+ "@mui/styled-engine": "^6.5.0",
2886
+ "@mui/types": "~7.2.24",
2887
+ "@mui/utils": "^6.4.9",
2888
+ "clsx": "^2.1.1",
2889
"csstype": "^3.1.3",
2890
"prop-types": "^15.8.1"
2891
},
2892
"engines": {
2793
- "node": ">=12.0.0"
2893
+ "node": ">=14.0.0"
2894
},
2895
"funding": {
2896
"type": "opencollective",
@@ -2815,9 +2915,10 @@
2915
}
2916
},
2917
"node_modules/@mui/types": {
2818
- "version": "7.2.16",
2819
- "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz",
2820
- "integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==",
2918
+ "version": "7.2.24",
2919
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz",
2920
+ "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==",
2921
+ "license": "MIT",
2922
"peerDependencies": {
2923
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0"
2924
},
@@ -2828,20 +2929,20 @@
2929
}
2930
},
2931
"node_modules/@mui/utils": {
2831
- "version": "5.17.1",
2832
- "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz",
2833
- "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==",
2932
+ "version": "6.4.9",
2933
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.9.tgz",
2934
+ "integrity": "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==",
2935
"license": "MIT",
2936
"dependencies": {
2836
- "@babel/runtime": "^7.23.9",
2837
- "@mui/types": "~7.2.15",
2838
- "@types/prop-types": "^15.7.12",
2937
+ "@babel/runtime": "^7.26.0",
2938
+ "@mui/types": "~7.2.24",
2939
+ "@types/prop-types": "^15.7.14",
2940
"clsx": "^2.1.1",
2941
"prop-types": "^15.8.1",
2942
"react-is": "^19.0.0"
2943
},
2944
"engines": {
2844
- "node": ">=12.0.0"
2945
+ "node": ">=14.0.0"
2946
},
2947
"funding": {
2948
"type": "opencollective",
@@ -2857,17 +2958,55 @@
2958
}
2959
}
2960
},
2961
+ "node_modules/@mui/x-data-grid": {
2962
+ "version": "7.29.12",
2963
+ "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.29.12.tgz",
2964
+ "integrity": "sha512-MaEC7ubr/je8jVWjdRU7LxBXAzlOZwFEdNdvlDUJIYkRa3TRCQ1HsY8Gd8Od0jnlnMYn9M4BrEfOrq9VRnt4bw==",
2965
+ "license": "MIT",
2966
+ "dependencies": {
2967
+ "@babel/runtime": "^7.25.7",
2968
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0",
2969
+ "@mui/x-internals": "7.29.0",
2970
+ "clsx": "^2.1.1",
2971
+ "prop-types": "^15.8.1",
2972
+ "reselect": "^5.1.1",
2973
+ "use-sync-external-store": "^1.0.0"
2974
+ },
2975
+ "engines": {
2976
+ "node": ">=14.0.0"
2977
+ },
2978
+ "funding": {
2979
+ "type": "opencollective",
2980
+ "url": "https://opencollective.com/mui-org"
2981
+ },
2982
+ "peerDependencies": {
2983
+ "@emotion/react": "^11.9.0",
2984
+ "@emotion/styled": "^11.8.1",
2985
+ "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0",
2986
+ "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0",
2987
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
2988
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
2989
+ },
2990
+ "peerDependenciesMeta": {
2991
+ "@emotion/react": {
2992
+ "optional": true
2993
+ },
2994
+ "@emotion/styled": {
2995
+ "optional": true
2996
+ }
2997
+ }
2998
+ },
2999
"node_modules/@mui/x-date-pickers": {
2861
- "version": "6.20.2",
2862
- "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.20.2.tgz",
2863
- "integrity": "sha512-x1jLg8R+WhvkmUETRfX2wC+xJreMii78EXKLl6r3G+ggcAZlPyt0myID1Amf6hvJb9CtR7CgUo8BwR+1Vx9Ggw==",
3000
+ "version": "7.29.4",
3001
+ "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.29.4.tgz",
3002
+ "integrity": "sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw==",
3003
"license": "MIT",
3004
"dependencies": {
2866
- "@babel/runtime": "^7.23.2",
2867
- "@mui/base": "^5.0.0-beta.22",
2868
- "@mui/utils": "^5.14.16",
2869
- "@types/react-transition-group": "^4.4.8",
2870
- "clsx": "^2.0.0",
3005
+ "@babel/runtime": "^7.25.7",
3006
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0",
3007
+ "@mui/x-internals": "7.29.0",
3008
+ "@types/react-transition-group": "^4.4.11",
3009
+ "clsx": "^2.1.1",
3010
"prop-types": "^15.8.1",
3011
"react-transition-group": "^4.4.5"
3012
},
@@ -2876,22 +3015,22 @@
3015
},
3016
"funding": {
3017
"type": "opencollective",
2879
- "url": "https://opencollective.com/mui"
3018
+ "url": "https://opencollective.com/mui-org"
3019
},
3020
"peerDependencies": {
3021
"@emotion/react": "^11.9.0",
3022
"@emotion/styled": "^11.8.1",
2884
- "@mui/material": "^5.8.6",
2885
- "@mui/system": "^5.8.0",
2886
- "date-fns": "^2.25.0 || ^3.2.0",
2887
- "date-fns-jalali": "^2.13.0-0",
3023
+ "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0",
3024
+ "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0",
3025
+ "date-fns": "^2.25.0 || ^3.2.0 || ^4.0.0",
3026
+ "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0",
3027
"dayjs": "^1.10.7",
3028
"luxon": "^3.0.2",
3029
"moment": "^2.29.4",
2891
- "moment-hijri": "^2.1.2",
3030
+ "moment-hijri": "^2.1.2 || ^3.0.0",
3031
"moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0",
2893
- "react": "^17.0.0 || ^18.0.0",
2894
- "react-dom": "^17.0.0 || ^18.0.0"
3032
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
3033
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
3034
},
3035
"peerDependenciesMeta": {
3036
"@emotion/react": {
@@ -2923,16 +3062,37 @@
3062
}
3063
}
3064
},
3065
+ "node_modules/@mui/x-internals": {
3066
+ "version": "7.29.0",
3067
+ "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.29.0.tgz",
3068
+ "integrity": "sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA==",
3069
+ "license": "MIT",
3070
+ "dependencies": {
3071
+ "@babel/runtime": "^7.25.7",
3072
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0"
3073
+ },
3074
+ "engines": {
3075
+ "node": ">=14.0.0"
3076
+ },
3077
+ "funding": {
3078
+ "type": "opencollective",
3079
+ "url": "https://opencollective.com/mui-org"
3080
+ },
3081
+ "peerDependencies": {
3082
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
3083
+ }
3084
+ },
3085
"node_modules/@mui/x-tree-view": {
2927
- "version": "6.17.0",
2928
- "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-6.17.0.tgz",
2929
- "integrity": "sha512-09dc2D+Rjg2z8KOaxbUXyPi0aw7fm2jurEtV8Xw48xJ00joLWd5QJm1/v4CarEvaiyhTQzHImNqdgeJW8ZQB6g==",
2930
- "dependencies": {
2931
- "@babel/runtime": "^7.23.2",
2932
- "@mui/base": "^5.0.0-beta.20",
2933
- "@mui/utils": "^5.14.14",
2934
- "@types/react-transition-group": "^4.4.8",
2935
- "clsx": "^2.0.0",
3086
+ "version": "7.29.10",
3087
+ "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.29.10.tgz",
3088
+ "integrity": "sha512-/ZcM582yIaQN2PmadIlQYRJzc3yXV7bh463J4GHtTmFw+PEjzUfzETBWe3VxmU3EPgIFzVQPjqAAJwylmQSJOg==",
3089
+ "license": "MIT",
3090
+ "dependencies": {
3091
+ "@babel/runtime": "^7.25.7",
3092
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0",
3093
+ "@mui/x-internals": "7.29.0",
3094
+ "@types/react-transition-group": "^4.4.11",
3095
+ "clsx": "^2.1.1",
3096
"prop-types": "^15.8.1",
3097
"react-transition-group": "^4.4.5"
3098
},
@@ -2941,15 +3101,23 @@
3101
},
3102
"funding": {
3103
"type": "opencollective",
2944
- "url": "https://opencollective.com/mui"
3104
+ "url": "https://opencollective.com/mui-org"
3105
},
3106
"peerDependencies": {
3107
"@emotion/react": "^11.9.0",
3108
"@emotion/styled": "^11.8.1",
2949
- "@mui/material": "^5.8.6",
2950
- "@mui/system": "^5.8.0",
2951
- "react": "^17.0.0 || ^18.0.0",
2952
- "react-dom": "^17.0.0 || ^18.0.0"
3109
+ "@mui/material": "^5.15.14 || ^6.0.0 || ^7.0.0",
3110
+ "@mui/system": "^5.15.14 || ^6.0.0 || ^7.0.0",
3111
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
3112
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
3113
+ },
3114
+ "peerDependenciesMeta": {
3115
+ "@emotion/react": {
3116
+ "optional": true
3117
+ },
3118
+ "@emotion/styled": {
3119
+ "optional": true
3120
+ }
3121
}
3122
},
3123
"node_modules/@nodable/entities": {
@@ -3857,9 +4025,10 @@
4025
"license": "MIT"
4026
},
4027
"node_modules/@types/prop-types": {
3860
- "version": "15.7.12",
3861
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
3862
- "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
4028
+ "version": "15.7.15",
4029
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
4030
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
4031
+ "license": "MIT"
4032
},
4033
"node_modules/@types/qs": {
4034
"version": "6.9.7",
@@ -3894,10 +4063,11 @@
4063
}
4064
},
4065
"node_modules/@types/react-transition-group": {
3897
- "version": "4.4.10",
3898
- "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
3899
- "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
3900
- "dependencies": {
4066
+ "version": "4.4.12",
4067
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
4068
+ "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==",
4069
+ "license": "MIT",
4070
+ "peerDependencies": {
4071
"@types/react": "*"
4072
}
4073
},
@@ -8459,6 +8629,12 @@
8629
"node": ">=0.10.0"
8630
}
8631
},
8632
+ "node_modules/reselect": {
8633
+ "version": "5.1.1",
8634
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
8635
+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
8636
+ "license": "MIT"
8637
+ },
8638
"node_modules/resolve": {
8639
"version": "1.22.10",
8640
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
@@ -11241,34 +11417,26 @@
11417
"optional": true
11418
},
11419
"@floating-ui/core": {
11244
- "version": "1.6.0",
11245
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz",
11246
- "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==",
11420
+ "version": "1.7.5",
11421
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.5.tgz",
11422
+ "integrity": "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==",
11423
"requires": {
11248
- "@floating-ui/utils": "^0.2.1"
11424
+ "@floating-ui/utils": "^0.2.11"
11425
}
11426
},
11427
"@floating-ui/dom": {
11252
- "version": "1.6.1",
11253
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.1.tgz",
11254
- "integrity": "sha512-iA8qE43/H5iGozC3W0YSnVSW42Vh522yyM1gj+BqRwVsTNOyr231PsXDaV04yT39PsO0QL2QpbI/M0ZaLUQgRQ==",
11428
+ "version": "1.7.6",
11429
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.6.tgz",
11430
+ "integrity": "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==",
11431
"requires": {
11256
- "@floating-ui/core": "^1.6.0",
11257
- "@floating-ui/utils": "^0.2.1"
11258
- }
11259
- },
11260
- "@floating-ui/react-dom": {
11261
- "version": "2.0.8",
11262
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz",
11263
- "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==",
11264
- "requires": {
11265
- "@floating-ui/dom": "^1.6.1"
11432
+ "@floating-ui/core": "^1.7.5",
11433
+ "@floating-ui/utils": "^0.2.11"
11434
}
11435
},
11436
"@floating-ui/utils": {
11269
- "version": "0.2.1",
11270
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz",
11271
- "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q=="
11437
+ "version": "0.2.11",
11438
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.11.tgz",
11439
+ "integrity": "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="
11440
},
11441
"@gregoranders/csv": {
11442
"version": "0.0.13",
@@ -11283,12 +11451,12 @@
11451
"@gregoranders/csv": "^0.0.13",
11452
"@hfs/mui-grid-form": "*",
11453
"@hfs/shared": "*",
11286
- "@mui/icons-material": "^5.18.0",
11287
- "@mui/lab": "^5.0.0-alpha.177",
11288
- "@mui/material": "^5.18.0",
11289
- "@mui/x-data-grid": "^6.20.4",
11290
- "@mui/x-date-pickers": "^6.20.2",
11291
- "@mui/x-tree-view": "^6.17.0",
11454
+ "@mui/icons-material": "^6.4.11",
11455
+ "@mui/lab": "^6.0.1-beta.34",
11456
+ "@mui/material": "^6.4.11",
11457
+ "@mui/x-data-grid": "^7.29.0",
11458
+ "@mui/x-date-pickers": "^7.29.0",
11459
+ "@mui/x-tree-view": "^7.29.0",
11460
"@types/prismjs": "^1.26.5",
11461
"@types/react": "^18.3.14",
11462
"@types/react-dom": "^18.3.2",
@@ -11307,22 +11475,53 @@
11475
"vite": "^6.4.1"
11476
},
11477
"dependencies": {
11310
- "@mui/x-data-grid": {
11311
- "version": "6.20.4",
11312
- "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.20.4.tgz",
11313
- "integrity": "sha512-I0JhinVV4e25hD2dB+R6biPBtpGeFrXf8RwlMPQbr9gUggPmPmNtWKo8Kk2PtBBMlGtdMAgHWe7PqhmucUxU1w==",
11478
+ "@mui/icons-material": {
11479
+ "version": "6.5.0",
11480
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.5.0.tgz",
11481
+ "integrity": "sha512-VPuPqXqbBPlcVSA0BmnoE4knW4/xG6Thazo8vCLWkOKusko6DtwFV6B665MMWJ9j0KFohTIf3yx2zYtYacvG1g==",
11482
"requires": {
11315
- "@babel/runtime": "^7.23.2",
11316
- "@mui/utils": "^5.14.16",
11317
- "clsx": "^2.0.0",
11318
- "prop-types": "^15.8.1",
11319
- "reselect": "^4.1.8"
11483
+ "@babel/runtime": "^7.26.0"
11484
}
11485
},
11322
- "reselect": {
11323
- "version": "4.1.8",
11324
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz",
11325
- "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
11486
+ "@mui/lab": {
11487
+ "version": "6.0.1-beta.36",
11488
+ "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.1-beta.36.tgz",
11489
+ "integrity": "sha512-af9lDmA9SZGEWF1XXk0EVBpfCITk9IKsvh9lLOZGdYaaHfQeCsqxGEDMvNO66j0P8EYoxpyry84LFCJYuLVtVw==",
11490
+ "requires": {
11491
+ "@babel/runtime": "^7.26.0",
11492
+ "@mui/base": "5.0.0-beta.70",
11493
+ "@mui/system": "^6.5.0",
11494
+ "@mui/types": "~7.2.24",
11495
+ "@mui/utils": "^6.4.9",
11496
+ "clsx": "^2.1.1",
11497
+ "prop-types": "^15.8.1"
11498
+ },
11499
+ "dependencies": {
11500
+ "@mui/base": {
11501
+ "version": "5.0.0-beta.70",
11502
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.70.tgz",
11503
+ "integrity": "sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ==",
11504
+ "requires": {
11505
+ "@babel/runtime": "^7.26.0",
11506
+ "@floating-ui/react-dom": "^2.1.1",
11507
+ "@mui/types": "~7.2.24",
11508
+ "@mui/utils": "^6.4.8",
11509
+ "@popperjs/core": "^2.11.8",
11510
+ "clsx": "^2.1.1",
11511
+ "prop-types": "^15.8.1"
11512
+ },
11513
+ "dependencies": {
11514
+ "@floating-ui/react-dom": {
11515
+ "version": "2.1.8",
11516
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
11517
+ "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==",
11518
+ "requires": {
11519
+ "@floating-ui/dom": "^1.7.6"
11520
+ }
11521
+ }
11522
+ }
11523
+ }
11524
+ }
11525
}
11526
}
11527
},
@@ -11375,6 +11574,56 @@
11574
"lodash": "*",
11575
"react": "*",
11576
"react-dom": "*"
11577
+ },
11578
+ "dependencies": {
11579
+ "@mui/icons-material": {
11580
+ "version": "6.5.0",
11581
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.5.0.tgz",
11582
+ "integrity": "sha512-VPuPqXqbBPlcVSA0BmnoE4knW4/xG6Thazo8vCLWkOKusko6DtwFV6B665MMWJ9j0KFohTIf3yx2zYtYacvG1g==",
11583
+ "requires": {
11584
+ "@babel/runtime": "^7.26.0"
11585
+ }
11586
+ },
11587
+ "@mui/lab": {
11588
+ "version": "6.0.1-beta.36",
11589
+ "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-6.0.1-beta.36.tgz",
11590
+ "integrity": "sha512-af9lDmA9SZGEWF1XXk0EVBpfCITk9IKsvh9lLOZGdYaaHfQeCsqxGEDMvNO66j0P8EYoxpyry84LFCJYuLVtVw==",
11591
+ "requires": {
11592
+ "@babel/runtime": "^7.26.0",
11593
+ "@mui/base": "5.0.0-beta.70",
11594
+ "@mui/system": "^6.5.0",
11595
+ "@mui/types": "~7.2.24",
11596
+ "@mui/utils": "^6.4.9",
11597
+ "clsx": "^2.1.1",
11598
+ "prop-types": "^15.8.1"
11599
+ },
11600
+ "dependencies": {
11601
+ "@mui/base": {
11602
+ "version": "5.0.0-beta.70",
11603
+ "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.70.tgz",
11604
+ "integrity": "sha512-Tb/BIhJzb0pa5zv/wu7OdokY9ZKEDqcu1BDFnohyvGCoHuSXbEr90rPq1qeNW3XvTBIbNWHEF7gqge+xpUo6tQ==",
11605
+ "requires": {
11606
+ "@babel/runtime": "^7.26.0",
11607
+ "@floating-ui/react-dom": "^2.1.1",
11608
+ "@mui/types": "~7.2.24",
11609
+ "@mui/utils": "^6.4.8",
11610
+ "@popperjs/core": "^2.11.8",
11611
+ "clsx": "^2.1.1",
11612
+ "prop-types": "^15.8.1"
11613
+ },
11614
+ "dependencies": {
11615
+ "@floating-ui/react-dom": {
11616
+ "version": "2.1.8",
11617
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.8.tgz",
11618
+ "integrity": "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==",
11619
+ "requires": {
11620
+ "@floating-ui/dom": "^1.7.6"
11621
+ }
11622
+ }
11623
+ }
11624
+ }
11625
+ }
11626
+ }
11627
}
11628
},
11629
"@hfs/shared": {
@@ -11444,60 +11693,24 @@
11693
"@jridgewell/sourcemap-codec": "^1.4.14"
11694
}
11695
},
11447
- "@mui/base": {
11448
- "version": "5.0.0-beta.40-1",
11449
- "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40-1.tgz",
11450
- "integrity": "sha512-agKXuNNy0bHUmeU7pNmoZwNFr7Hiyhojkb9+2PVyDG5+6RafYuyMgbrav8CndsB7KUc/U51JAw9vKNDLYBzaUA==",
11451
- "requires": {
11452
- "@babel/runtime": "^7.23.9",
11453
- "@floating-ui/react-dom": "^2.0.8",
11454
- "@mui/types": "~7.2.15",
11455
- "@mui/utils": "^5.17.1",
11456
- "@popperjs/core": "^2.11.8",
11457
- "clsx": "^2.1.0",
11458
- "prop-types": "^15.8.1"
11459
- }
11460
- },
11696
"@mui/core-downloads-tracker": {
11462
- "version": "5.18.0",
11463
- "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz",
11464
- "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA=="
11465
- },
11466
- "@mui/icons-material": {
11467
- "version": "5.18.0",
11468
- "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.18.0.tgz",
11469
- "integrity": "sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg==",
11470
- "requires": {
11471
- "@babel/runtime": "^7.23.9"
11472
- }
11473
- },
11474
- "@mui/lab": {
11475
- "version": "5.0.0-alpha.177",
11476
- "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.177.tgz",
11477
- "integrity": "sha512-bdCxxtNjlWAgN9rtrwlmFydJ1qxA3IIbb6OlomGFsIXw0zGoHomLyjvh72q/R3yUAC0kvSef18cHY1UalLylyQ==",
11478
- "requires": {
11479
- "@babel/runtime": "^7.23.9",
11480
- "@mui/base": "5.0.0-beta.40-1",
11481
- "@mui/system": "^5.18.0",
11482
- "@mui/types": "~7.2.15",
11483
- "@mui/utils": "^5.17.1",
11484
- "clsx": "^2.1.0",
11485
- "prop-types": "^15.8.1"
11486
- }
11697
+ "version": "6.5.0",
11698
+ "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.5.0.tgz",
11699
+ "integrity": "sha512-LGb8t8i6M2ZtS3Drn3GbTI1DVhDY6FJ9crEey2lZ0aN2EMZo8IZBZj9wRf4vqbZHaWjsYgtbOnJw5V8UWbmK2Q=="
11700
},
11701
"@mui/material": {
11489
- "version": "5.18.0",
11490
- "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz",
11491
- "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==",
11492
- "requires": {
11493
- "@babel/runtime": "^7.23.9",
11494
- "@mui/core-downloads-tracker": "^5.18.0",
11495
- "@mui/system": "^5.18.0",
11496
- "@mui/types": "~7.2.15",
11497
- "@mui/utils": "^5.17.1",
11702
+ "version": "6.5.0",
11703
+ "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.5.0.tgz",
11704
+ "integrity": "sha512-yjvtXoFcrPLGtgKRxFaH6OQPtcLPhkloC0BML6rBG5UeldR0nPULR/2E2BfXdo5JNV7j7lOzrrLX2Qf/iSidow==",
11705
+ "requires": {
11706
+ "@babel/runtime": "^7.26.0",
11707
+ "@mui/core-downloads-tracker": "^6.5.0",
11708
+ "@mui/system": "^6.5.0",
11709
+ "@mui/types": "~7.2.24",
11710
+ "@mui/utils": "^6.4.9",
11711
"@popperjs/core": "^2.11.8",
11499
- "@types/react-transition-group": "^4.4.10",
11500
- "clsx": "^2.1.0",
11712
+ "@types/react-transition-group": "^4.4.12",
11713
+ "clsx": "^2.1.1",
11714
"csstype": "^3.1.3",
11715
"prop-types": "^15.8.1",
11716
"react-is": "^19.0.0",
@@ -11505,85 +11718,109 @@
11718
}
11719
},
11720
"@mui/private-theming": {
11508
- "version": "5.17.1",
11509
- "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz",
11510
- "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==",
11721
+ "version": "6.4.9",
11722
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.9.tgz",
11723
+ "integrity": "sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==",
11724
"requires": {
11512
- "@babel/runtime": "^7.23.9",
11513
- "@mui/utils": "^5.17.1",
11725
+ "@babel/runtime": "^7.26.0",
11726
+ "@mui/utils": "^6.4.9",
11727
"prop-types": "^15.8.1"
11728
}
11729
},
11730
"@mui/styled-engine": {
11518
- "version": "5.18.0",
11519
- "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz",
11520
- "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==",
11731
+ "version": "6.5.0",
11732
+ "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.5.0.tgz",
11733
+ "integrity": "sha512-8woC2zAqF4qUDSPIBZ8v3sakj+WgweolpyM/FXf8jAx6FMls+IE4Y8VDZc+zS805J7PRz31vz73n2SovKGaYgw==",
11734
"requires": {
11522
- "@babel/runtime": "^7.23.9",
11735
+ "@babel/runtime": "^7.26.0",
11736
"@emotion/cache": "^11.13.5",
11737
"@emotion/serialize": "^1.3.3",
11738
+ "@emotion/sheet": "^1.4.0",
11739
"csstype": "^3.1.3",
11740
"prop-types": "^15.8.1"
11741
}
11742
},
11743
"@mui/system": {
11530
- "version": "5.18.0",
11531
- "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz",
11532
- "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==",
11533
- "requires": {
11534
- "@babel/runtime": "^7.23.9",
11535
- "@mui/private-theming": "^5.17.1",
11536
- "@mui/styled-engine": "^5.18.0",
11537
- "@mui/types": "~7.2.15",
11538
- "@mui/utils": "^5.17.1",
11539
- "clsx": "^2.1.0",
11744
+ "version": "6.5.0",
11745
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.5.0.tgz",
11746
+ "integrity": "sha512-XcbBYxDS+h/lgsoGe78ExXFZXtuIlSBpn/KsZq8PtZcIkUNJInkuDqcLd2rVBQrDC1u+rvVovdaWPf2FHKJf3w==",
11747
+ "requires": {
11748
+ "@babel/runtime": "^7.26.0",
11749
+ "@mui/private-theming": "^6.4.9",
11750
+ "@mui/styled-engine": "^6.5.0",
11751
+ "@mui/types": "~7.2.24",
11752
+ "@mui/utils": "^6.4.9",
11753
+ "clsx": "^2.1.1",
11754
"csstype": "^3.1.3",
11755
"prop-types": "^15.8.1"
11756
}
11757
},
11758
"@mui/types": {
11545
- "version": "7.2.16",
11546
- "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz",
11547
- "integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==",
11759
+ "version": "7.2.24",
11760
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz",
11761
+ "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==",
11762
"requires": {}
11763
},
11764
"@mui/utils": {
11551
- "version": "5.17.1",
11552
- "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz",
11553
- "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==",
11765
+ "version": "6.4.9",
11766
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.9.tgz",
11767
+ "integrity": "sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==",
11768
"requires": {
11555
- "@babel/runtime": "^7.23.9",
11556
- "@mui/types": "~7.2.15",
11557
- "@types/prop-types": "^15.7.12",
11769
+ "@babel/runtime": "^7.26.0",
11770
+ "@mui/types": "~7.2.24",
11771
+ "@types/prop-types": "^15.7.14",
11772
"clsx": "^2.1.1",
11773
"prop-types": "^15.8.1",
11774
"react-is": "^19.0.0"
11775
}
11776
},
11777
+ "@mui/x-data-grid": {
11778
+ "version": "7.29.12",
11779
+ "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.29.12.tgz",
11780
+ "integrity": "sha512-MaEC7ubr/je8jVWjdRU7LxBXAzlOZwFEdNdvlDUJIYkRa3TRCQ1HsY8Gd8Od0jnlnMYn9M4BrEfOrq9VRnt4bw==",
11781
+ "requires": {
11782
+ "@babel/runtime": "^7.25.7",
11783
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0",
11784
+ "@mui/x-internals": "7.29.0",
11785
+ "clsx": "^2.1.1",
11786
+ "prop-types": "^15.8.1",
11787
+ "reselect": "^5.1.1",
11788
+ "use-sync-external-store": "^1.0.0"
11789
+ }
11790
+ },
11791
"@mui/x-date-pickers": {
11564
- "version": "6.20.2",
11565
- "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.20.2.tgz",
11566
- "integrity": "sha512-x1jLg8R+WhvkmUETRfX2wC+xJreMii78EXKLl6r3G+ggcAZlPyt0myID1Amf6hvJb9CtR7CgUo8BwR+1Vx9Ggw==",
11567
- "requires": {
11568
- "@babel/runtime": "^7.23.2",
11569
- "@mui/base": "^5.0.0-beta.22",
11570
- "@mui/utils": "^5.14.16",
11571
- "@types/react-transition-group": "^4.4.8",
11572
- "clsx": "^2.0.0",
11792
+ "version": "7.29.4",
11793
+ "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.29.4.tgz",
11794
+ "integrity": "sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw==",
11795
+ "requires": {
11796
+ "@babel/runtime": "^7.25.7",
11797
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0",
11798
+ "@mui/x-internals": "7.29.0",
11799
+ "@types/react-transition-group": "^4.4.11",
11800
+ "clsx": "^2.1.1",
11801
"prop-types": "^15.8.1",
11802
"react-transition-group": "^4.4.5"
11803
}
11804
},
11805
+ "@mui/x-internals": {
11806
+ "version": "7.29.0",
11807
+ "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.29.0.tgz",
11808
+ "integrity": "sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA==",
11809
+ "requires": {
11810
+ "@babel/runtime": "^7.25.7",
11811
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0"
11812
+ }
11813
+ },
11814
"@mui/x-tree-view": {
11578
- "version": "6.17.0",
11579
- "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-6.17.0.tgz",
11580
- "integrity": "sha512-09dc2D+Rjg2z8KOaxbUXyPi0aw7fm2jurEtV8Xw48xJ00joLWd5QJm1/v4CarEvaiyhTQzHImNqdgeJW8ZQB6g==",
11581
- "requires": {
11582
- "@babel/runtime": "^7.23.2",
11583
- "@mui/base": "^5.0.0-beta.20",
11584
- "@mui/utils": "^5.14.14",
11585
- "@types/react-transition-group": "^4.4.8",
11586
- "clsx": "^2.0.0",
11815
+ "version": "7.29.10",
11816
+ "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.29.10.tgz",
11817
+ "integrity": "sha512-/ZcM582yIaQN2PmadIlQYRJzc3yXV7bh463J4GHtTmFw+PEjzUfzETBWe3VxmU3EPgIFzVQPjqAAJwylmQSJOg==",
11818
+ "requires": {
11819
+ "@babel/runtime": "^7.25.7",
11820
+ "@mui/utils": "^5.16.6 || ^6.0.0 || ^7.0.0",
11821
+ "@mui/x-internals": "7.29.0",
11822
+ "@types/react-transition-group": "^4.4.11",
11823
+ "clsx": "^2.1.1",
11824
"prop-types": "^15.8.1",
11825
"react-transition-group": "^4.4.5"
11826
}
@@ -12237,9 +12474,9 @@
12474
"dev": true
12475
},
12476
"@types/prop-types": {
12240
- "version": "15.7.12",
12241
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
12242
- "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="
12477
+ "version": "15.7.15",
12478
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
12479
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw=="
12480
},
12481
"@types/qs": {
12482
"version": "6.9.7",
@@ -12272,12 +12509,10 @@
12509
}
12510
},
12511
"@types/react-transition-group": {
12275
- "version": "4.4.10",
12276
- "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
12277
- "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
12278
- "requires": {
12279
- "@types/react": "*"
12280
- }
12512
+ "version": "4.4.12",
12513
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
12514
+ "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==",
12515
+ "requires": {}
12516
},
12517
"@types/react-window": {
12518
"version": "1.8.8",
@@ -15279,6 +15514,11 @@
15514
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
15515
"dev": true
15516
},
15517
+ "reselect": {
15518
+ "version": "5.1.1",
15519
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
15520
+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w=="
15521
+ },
15522
"resolve": {
15523
"version": "1.22.10",
15524
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",