@stoker-platform/web-app 0.5.28 → 0.5.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/src/Form.tsx +115 -50
- package/src/utils/getFormattedFieldValue.tsx +1 -1
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
package/src/Form.tsx
CHANGED
|
@@ -2322,6 +2322,36 @@ function RecordForm({
|
|
|
2322
2322
|
[collectionPath, record, path],
|
|
2323
2323
|
)
|
|
2324
2324
|
|
|
2325
|
+
const getUserRoleAssignment = useCallback(() => {
|
|
2326
|
+
const userRole = permissions?.Role
|
|
2327
|
+
if (!userRole) return null
|
|
2328
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
2329
|
+
const assignment = collection.access?.files?.assignment?.[userRole]
|
|
2330
|
+
return assignment || null
|
|
2331
|
+
}, [collection, permissions])
|
|
2332
|
+
|
|
2333
|
+
const shouldSkipPermissionsDialog = useCallback(() => {
|
|
2334
|
+
const assignment = getUserRoleAssignment()
|
|
2335
|
+
if (!assignment) return false
|
|
2336
|
+
const optional = assignment.optional || {}
|
|
2337
|
+
const hasOptional = Boolean(
|
|
2338
|
+
(optional.read && optional.read.length) ||
|
|
2339
|
+
(optional.update && optional.update.length) ||
|
|
2340
|
+
(optional.delete && optional.delete.length),
|
|
2341
|
+
)
|
|
2342
|
+
return !hasOptional
|
|
2343
|
+
}, [getUserRoleAssignment])
|
|
2344
|
+
|
|
2345
|
+
const getDefaultPermissions = useCallback((): FilePermissions => {
|
|
2346
|
+
const assignment = getUserRoleAssignment()
|
|
2347
|
+
const required = assignment?.required || {}
|
|
2348
|
+
return {
|
|
2349
|
+
read: (required.read || []).join(","),
|
|
2350
|
+
update: (required.update || []).join(","),
|
|
2351
|
+
delete: (required.delete || []).join(","),
|
|
2352
|
+
}
|
|
2353
|
+
}, [getUserRoleAssignment])
|
|
2354
|
+
|
|
2325
2355
|
const uploadFilesToRecord = useCallback(
|
|
2326
2356
|
async (targetId: string, files: File[] | FileList, permissions: FilePermissions, customFilename?: string) => {
|
|
2327
2357
|
if (!files || !currentUser) return
|
|
@@ -2407,56 +2437,6 @@ function RecordForm({
|
|
|
2407
2437
|
[computeBasePath, currentUser, path, record],
|
|
2408
2438
|
)
|
|
2409
2439
|
|
|
2410
|
-
const enqueueImageForCreate = useCallback((fieldName: string, file: File) => {
|
|
2411
|
-
setPermissionsContext("image-create")
|
|
2412
|
-
setPendingImageFieldName(fieldName)
|
|
2413
|
-
setPendingUploadFile(file)
|
|
2414
|
-
setPendingUploadField(fieldName)
|
|
2415
|
-
setEditingFilename(file.name)
|
|
2416
|
-
setIsMultipleFileUpload(false)
|
|
2417
|
-
setShowPermissionsDialog(true)
|
|
2418
|
-
}, [])
|
|
2419
|
-
|
|
2420
|
-
const uploadImageForUpdate = useCallback(async (fieldName: string, file: File) => {
|
|
2421
|
-
return await new Promise<void>((resolve) => {
|
|
2422
|
-
setPermissionsContext("image-update")
|
|
2423
|
-
setPendingImageForUpdate({ fieldName, file })
|
|
2424
|
-
setEditingFilename(file.name)
|
|
2425
|
-
setIsMultipleFileUpload(false)
|
|
2426
|
-
setShowPermissionsDialog(true)
|
|
2427
|
-
setImageUpdateResolver(() => resolve)
|
|
2428
|
-
})
|
|
2429
|
-
}, [])
|
|
2430
|
-
|
|
2431
|
-
const handleFormFileUpload = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
2432
|
-
const files = event.target.files
|
|
2433
|
-
if (!files) return
|
|
2434
|
-
if (files.length === 1) {
|
|
2435
|
-
const file = files[0]
|
|
2436
|
-
setPendingUploadFile(file)
|
|
2437
|
-
setPendingUploadField(null)
|
|
2438
|
-
setEditingFilename(file.name)
|
|
2439
|
-
setIsMultipleFileUpload(false)
|
|
2440
|
-
setShowFilenameDialog(true)
|
|
2441
|
-
} else {
|
|
2442
|
-
setPendingUploadFiles(Array.from(files))
|
|
2443
|
-
setIsMultipleFileUpload(true)
|
|
2444
|
-
setShowPermissionsDialog(true)
|
|
2445
|
-
}
|
|
2446
|
-
event.target.value = ""
|
|
2447
|
-
}, [])
|
|
2448
|
-
|
|
2449
|
-
const handleConfirmFilename = useCallback(() => {
|
|
2450
|
-
if (!pendingUploadFile) return
|
|
2451
|
-
const trimmed = editingFilename.trim()
|
|
2452
|
-
const validationError = validateStorageName(trimmed)
|
|
2453
|
-
if (validationError) {
|
|
2454
|
-
toast({ title: "Invalid file name", description: validationError, variant: "destructive" })
|
|
2455
|
-
return
|
|
2456
|
-
}
|
|
2457
|
-
setShowPermissionsDialog(true)
|
|
2458
|
-
}, [pendingUploadFile, editingFilename])
|
|
2459
|
-
|
|
2460
2440
|
const handlePermissionsConfirm = useCallback(
|
|
2461
2441
|
async (selectedPermissions: FilePermissions) => {
|
|
2462
2442
|
if (permissionsContext === "files") {
|
|
@@ -2620,6 +2600,91 @@ function RecordForm({
|
|
|
2620
2600
|
],
|
|
2621
2601
|
)
|
|
2622
2602
|
|
|
2603
|
+
const enqueueImageForCreate = useCallback(
|
|
2604
|
+
(fieldName: string, file: File) => {
|
|
2605
|
+
if (shouldSkipPermissionsDialog()) {
|
|
2606
|
+
setQueuedImageUploads((prev) => ({
|
|
2607
|
+
...prev,
|
|
2608
|
+
[fieldName]: { file, permissions: getDefaultPermissions() },
|
|
2609
|
+
}))
|
|
2610
|
+
} else {
|
|
2611
|
+
setPermissionsContext("image-create")
|
|
2612
|
+
setPendingImageFieldName(fieldName)
|
|
2613
|
+
setPendingUploadFile(file)
|
|
2614
|
+
setEditingFilename(file.name)
|
|
2615
|
+
setIsMultipleFileUpload(false)
|
|
2616
|
+
setShowPermissionsDialog(true)
|
|
2617
|
+
}
|
|
2618
|
+
},
|
|
2619
|
+
[shouldSkipPermissionsDialog, getDefaultPermissions],
|
|
2620
|
+
)
|
|
2621
|
+
|
|
2622
|
+
const uploadImageForUpdate = useCallback(
|
|
2623
|
+
async (fieldName: string, file: File) => {
|
|
2624
|
+
return await new Promise<void>((resolve) => {
|
|
2625
|
+
setPermissionsContext("image-update")
|
|
2626
|
+
setPendingImageForUpdate({ fieldName, file })
|
|
2627
|
+
setEditingFilename(file.name)
|
|
2628
|
+
setIsMultipleFileUpload(false)
|
|
2629
|
+
setImageUpdateResolver(() => resolve)
|
|
2630
|
+
if (shouldSkipPermissionsDialog()) {
|
|
2631
|
+
setTimeout(() => handlePermissionsConfirm(getDefaultPermissions()), 0)
|
|
2632
|
+
} else {
|
|
2633
|
+
setShowPermissionsDialog(true)
|
|
2634
|
+
}
|
|
2635
|
+
})
|
|
2636
|
+
},
|
|
2637
|
+
[shouldSkipPermissionsDialog, getDefaultPermissions, handlePermissionsConfirm],
|
|
2638
|
+
)
|
|
2639
|
+
|
|
2640
|
+
const handleFormFileUpload = useCallback(
|
|
2641
|
+
async (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
2642
|
+
const files = event.target.files
|
|
2643
|
+
if (!files) return
|
|
2644
|
+
if (files.length === 1) {
|
|
2645
|
+
const file = files[0]
|
|
2646
|
+
setPendingUploadFile(file)
|
|
2647
|
+
setPendingUploadField(null)
|
|
2648
|
+
setEditingFilename(file.name)
|
|
2649
|
+
setIsMultipleFileUpload(false)
|
|
2650
|
+
setShowFilenameDialog(true)
|
|
2651
|
+
} else {
|
|
2652
|
+
const fileList = Array.from(files)
|
|
2653
|
+
if (shouldSkipPermissionsDialog()) {
|
|
2654
|
+
setQueuedUploads((prev) => [...prev, { files: fileList, permissions: getDefaultPermissions() }])
|
|
2655
|
+
} else {
|
|
2656
|
+
setPendingUploadFiles(fileList)
|
|
2657
|
+
setIsMultipleFileUpload(true)
|
|
2658
|
+
setShowPermissionsDialog(true)
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
event.target.value = ""
|
|
2662
|
+
},
|
|
2663
|
+
[shouldSkipPermissionsDialog, getDefaultPermissions],
|
|
2664
|
+
)
|
|
2665
|
+
|
|
2666
|
+
const handleConfirmFilename = useCallback(() => {
|
|
2667
|
+
if (!pendingUploadFile) return
|
|
2668
|
+
const trimmed = editingFilename.trim()
|
|
2669
|
+
const validationError = validateStorageName(trimmed)
|
|
2670
|
+
if (validationError) {
|
|
2671
|
+
toast({ title: "Invalid file name", description: validationError, variant: "destructive" })
|
|
2672
|
+
return
|
|
2673
|
+
}
|
|
2674
|
+
if (shouldSkipPermissionsDialog()) {
|
|
2675
|
+
setQueuedUploads((prev) => [
|
|
2676
|
+
...prev,
|
|
2677
|
+
{ files: [pendingUploadFile], permissions: getDefaultPermissions(), customFilename: trimmed },
|
|
2678
|
+
])
|
|
2679
|
+
setShowFilenameDialog(false)
|
|
2680
|
+
setPendingUploadFile(null)
|
|
2681
|
+
setPendingUploadField(null)
|
|
2682
|
+
setEditingFilename("")
|
|
2683
|
+
} else {
|
|
2684
|
+
setShowPermissionsDialog(true)
|
|
2685
|
+
}
|
|
2686
|
+
}, [pendingUploadFile, editingFilename, shouldSkipPermissionsDialog, getDefaultPermissions])
|
|
2687
|
+
|
|
2623
2688
|
const handlePermissionsCancel = useCallback(() => {
|
|
2624
2689
|
if (permissionsContext === "image-create" && pendingImageFieldName) {
|
|
2625
2690
|
setTimeout(() => {
|