admin/fs: ask for virtual folder's name
Massimo Melina committed
Mar 13, 2022 at 12:19 UTC
d2f1604f1ca58187524d2bacb970000729030bf9
4 files changed
+61
-12
admin/src/Form.ts
+5
-5
@@ -2,7 +2,7 @@
2
3
import { createElement as h, FC, Fragment, isValidElement, ReactElement, ReactNode, useEffect, useState } from 'react'
4
import {
5
- Box,
5
+ Box, Button,
6
FormControl,
7
FormControlLabel, FormHelperText,
8
FormLabel,
@@ -27,7 +27,7 @@ interface FormProps {
27
defaults?: (f:FieldDescriptor) => Dict | void
28
values: Dict
29
set: (v: any, field: FieldDescriptor) => void
30
- save?: Dict
30
+ save?: Partial<Parameters<typeof Button>[0]>
31
stickyBar?: boolean
32
addToBar?: ReactNode[]
33
barSx?: Dict
@@ -37,16 +37,16 @@ export function Form({ fields, values, set, defaults, save, stickyBar, addToBar=
37
const [loading, setLoading] = useStateMounted(false)
38
const onClick = save?.onClick
39
if (onClick)
40
- save.onClick = async function () {
40
+ save.onClick = async function (ev) {
41
setLoading(true)
42
- try { return await onClick(this, arguments) }
42
+ try { return await onClick(ev) }
43
finally { setLoading(false) }
44
}
45
46
const [pendingSubmit, setPendingSubmit] = useStateMounted(false)
47
useEffect(() => {
48
if (!pendingSubmit) return
49
- setTimeout(save?.onClick)
49
+ setTimeout(save?.onClick!)
50
setPendingSubmit(false)
51
}, [pendingSubmit]) //eslint-disable-line
52
admin/src/addFiles.ts
+3
-2
@@ -1,6 +1,6 @@
1
// This file is part of HFS - Copyright 2021-2022, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
-import { alertDialog, newDialog } from './dialog'
3
+import { alertDialog, newDialog, promptDialog } from './dialog'
4
import { createElement as h } from 'react'
5
import { Box } from '@mui/material'
6
import { VfsNode, reloadVfs } from './VfsPage'
@@ -38,7 +38,8 @@ export default function addFiles() {
38
39
export async function addVirtual() {
40
try {
41
- const name = "Folder"+String(Date.now()).slice(8)
41
+ const name = await promptDialog("Enter folder name")
42
+ if (!name) return
43
const under = getUnder()
44
await apiCall('add_vfs', { under, name })
45
reloadVfs([ (under||'') + '/' + name ])
admin/src/dialog.ts
+52
-5
@@ -6,14 +6,15 @@ import {
6
isValidElement,
7
ReactElement,
8
useEffect,
9
- useRef
9
+ useRef,
10
+ useState
11
} from 'react'
11
-import { Check, Error as ErrorIcon, Info, Warning } from '@mui/icons-material'
12
-import { newDialog, closeDialog, dialogsDefaults, DialogOptions, Dialogs } from '@hfs/shared/lib/dialogs'
12
+import { Check, Error as ErrorIcon, Forward, Info, Warning } from '@mui/icons-material'
13
+import { newDialog, closeDialog, dialogsDefaults, DialogOptions } from '@hfs/shared/lib/dialogs'
14
+import { Form } from './Form'
15
export * from '@hfs/shared/lib/dialogs'
16
15
-dialogsDefaults.Container = Container
16
-function Container(d:DialogOptions) {
17
+dialogsDefaults.Container = function Container(d:DialogOptions) {
18
useEffect(()=>{
19
ref.current?.focus()
20
}, [])
@@ -83,3 +84,49 @@ export async function confirmDialog(msg: string, { href }: ConfirmOptions={}) :
84
}
85
}
86
87
+type FormProps = Parameters<typeof Form>[0]
88
+export async function formDialog(props: FormProps) : Promise<FormProps['values']> {
89
+ return new Promise(resolve => newDialog({
90
+ className: 'dialog-confirm',
91
+ icon: '?',
92
+ onClose: resolve,
93
+ Content
94
+ }) )
95
+
96
+ function Content() {
97
+ const [values, setValues] = useState<any>(props.values||{})
98
+ return h(Form, {
99
+ ...props,
100
+ values,
101
+ set(v, { k }) {
102
+ setValues({ ...values, [k]: v })
103
+ },
104
+ save: {
105
+ ...props.save,
106
+ onClick() {
107
+ closeDialog(values)
108
+ }
109
+ }
110
+ })
111
+ }
112
+}
113
+
114
+export async function promptDialog(msg: string, props:any={}) : Promise<string | undefined> {
115
+ return formDialog({
116
+ ...props,
117
+ fields: [
118
+ h(Box, {}, msg),
119
+ { k: 'text', label: null, autoFocus: true, },
120
+ ],
121
+ save: {
122
+ children: "Continue",
123
+ startIcon: h(Forward),
124
+ ...props.save,
125
+ },
126
+ barSx: { gap: 2 },
127
+ addToBar: [
128
+ h(Button, { onClick: closeDialog }, "Cancel"),
129
+ ...props.addToBar||[],
130
+ ]
131
+ }).then(values => values?.text)
132
+}
todo.md
+1
@@ -1,5 +1,6 @@
1
# To do
2
- mac/linux binary
3
+- admin/fs: support insert/delete key
4
- if specified config is a folder, check for file config.yaml inside
5
- merge accounts in config
6
- frontend: ok button to inputDialogs