better code: get defaults from backend

Massimo Melina committed Jan 13, 2023 at 18:24 UTC 3cc664de0892672d8f343d7663c6236389765372
4 files changed +27 -24
admin/src/FileForm.ts
+4 -4
@@ -6,7 +6,7 @@ import { Alert, Button } from '@mui/material'
6 import { BoolField, DisplayField, Field, FieldProps, Form, MultiSelectField, SelectField } from '@hfs/mui-grid-form'
7 import { apiCall, useApiEx } from './api'
8 import { formatBytes, isEqualLax, modifiedSx, onlyTruthy } from './misc'
9 -import { reloadVfs, VfsNode, Who } from './VfsPage'
9 +import { reloadVfs, VfsNode, VfsPerms, Who } from './VfsPage'
10 import md from './md'
11 import _ from 'lodash'
12 import FileField from './FileField'
@@ -14,7 +14,7 @@ import { alertDialog } from './dialog'
14
15 interface Account { username: string }
16
17 -export default function FileForm({ file }: { file: VfsNode }) {
17 +export default function FileForm({ file, defaultPerms }: { file: VfsNode, defaultPerms: VfsPerms }) {
18 const { parent, children, isRoot, ...rest } = file
19 const [values, setValues] = useState(rest)
20 useEffect(() => {
@@ -32,7 +32,7 @@ export default function FileForm({ file }: { file: VfsNode }) {
32 _.defaults(ret, run)
33 run = run.parent
34 }
35 - return _.defaults(ret, { can_read: true, can_see: true, can_upload: false })
35 + return _.defaults(ret, defaultPerms)
36 }, [parent])
37 const showCanSee = (values.can_read ?? inheritedPerms.can_read) === true
38 const showTimestamps = hasSource && Boolean(values.ctime)
@@ -104,7 +104,7 @@ interface WhoFieldProps extends FieldProps<Who> { accounts: Account[] }
104 function WhoField({ value, onChange, parent, inherit, accounts, helperText, ...rest }: WhoFieldProps) {
105 const options = useMemo(() =>
106 onlyTruthy([
107 - { value: null, label: (parent ? "Same as parent: " : "Default: " ) + who2desc(inherit === 0 ? true : inherit) },
107 + { value: null, label: (parent ? "Same as parent: " : "Default: " ) + who2desc(inherit) },
108 { value: true },
109 { value: false },
110 { value: '*' },
admin/src/VfsPage.ts
+18 -18
@@ -16,9 +16,9 @@ let selectOnReload: string[] | undefined
16
17 export default function VfsPage() {
18 const [id2node] = useState(() => new Map<string, VfsNode>())
19 - const snap = useSnapState()
19 + const { vfs, selectedFiles } = useSnapState()
20 const { data, reload, element } = useApiEx('get_vfs')
21 - useMemo(() => snap.vfs || reload(), [snap.vfs, reload])
21 + useMemo(() => vfs || reload(), [vfs, reload])
22 useEffect(() => {
23 state.vfs = undefined
24 if (!data) return
@@ -74,28 +74,31 @@ export default function VfsPage() {
74 h(Grid, { item:true, sm: 6, lg: 5 },
75 h(Typography, { variant: 'h6', mb:1, }, "Virtual File System"),
76 h(VfsMenuBar),
77 - snap.vfs && h(VfsTree, { id2node })),
77 + vfs && h(VfsTree, { id2node })),
78 h(Grid, { item:true, sm: 6, lg: 7, maxWidth:'100%' },
79 - h(SidePanel))
79 + selectedFiles.length === 0 ? null
80 + : selectedFiles.length === 1 ? h(FileForm, {
81 + defaultPerms: data?.defaultPerms as VfsPerms,
82 + file: selectedFiles[0] as VfsNode // it's actually Snapshot<VfsNode> but it's easier this way
83 + })
84 + : h(List, {},
85 + selectedFiles.length + ' selected',
86 + selectedFiles.map(f => h(ListItem, { key: f.name },
87 + h(ListItemText, { primary: f.name, secondary: f.source }) ))))
88 )
89 }
90
83 -function SidePanel() {
84 - const { selectedFiles: files } = useSnapState()
85 - return files.length === 0 ? null
86 - : files.length === 1 ? h(FileForm, { file: files[0] as VfsNode }) // it's actually Snapshot<VfsNode> but it's easier this way
87 - : h(List, {},
88 - files.length + ' selected',
89 - files.map(f => h(ListItem, { key: f.name },
90 - h(ListItemText, { primary: f.name, secondary: f.source }) )))
91 -}
92 -
91 export function reloadVfs(pleaseSelect?: string[]) {
92 selectOnReload = pleaseSelect
93 state.vfs = undefined
94 }
95
98 -export type VfsNode = {
96 +export interface VfsPerms {
97 + can_see?: Who
98 + can_read?: Who
99 + can_upload?: Who
100 +}
101 +export interface VfsNode extends VfsPerms {
102 id: string
103 name: string
104 type?: 'folder'
@@ -106,11 +109,8 @@ export type VfsNode = {
109 default?: string
110 children?: VfsNode[]
111 parent?: VfsNode
109 - can_see: Who
110 - can_read: Who
112 website?: true
113 masks?: any
113 -
114 isRoot?: true
115 }
116
admin/src/VfsTree.ts
+1 -1
@@ -41,7 +41,7 @@ export default function VfsTree({ id2node }:{ id2node: Map<string, VfsNode> }) {
41 }
42 }, recur(vfs as Readonly<VfsNode>))
43
44 - function isRestricted(who: Who) {
44 + function isRestricted(who: Who | undefined) {
45 return who !== undefined && who !== true
46 }
47
src/api.vfs.ts
+4 -1
@@ -29,7 +29,10 @@ async function urlToNodeOriginal(uri: string) {
29 const apis: ApiHandlers = {
30
31 async get_vfs() {
32 - return { root: vfs && await recur(vfs) }
32 + return {
33 + root: vfs && await recur(vfs),
34 + defaultPerms,
35 + }
36
37 async function recur(node: VfsNode): Promise<VfsAdmin> {
38 const dir = await nodeIsDirectory(node)