admin/fs: ux: select items with single click, multiselect only through checkboxes
Massimo Melina committed
Mar 15, 2022 at 14:58 UTC
e54fe2c033b2cbb92361a547341554ffb330fbe8
1 file changed
+50
-43
admin/src/FilePicker.ts
+50
-43
@@ -49,16 +49,8 @@ export default function FilePicker({ onSelect }: { onSelect:(v:string[])=>void }
49
return spinner()
50
const pathDelimiter = /[:\\]/.test(cwd) ? '\\' : '/'
51
const cwdPostfixed = enforceFinal(pathDelimiter, cwd)
52
- return h(Box, { display: 'flex', flexDirection: 'column', gap: 2 },
52
+ return h(Box, { display: 'flex', flexDirection: 'column' },
53
h(Box, { display:'flex', gap: 1 },
54
- h(Button, {
55
- variant: 'contained',
56
- disabled: !sel.length,
57
- sx: { minWidth: 'max-content' },
58
- onClick() {
59
- onSelect(sel.map(x => cwdPostfixed + x))
60
- }
61
- }, `Select (${sel.length})`),
54
h(Button, {
55
onClick() {
56
setCwd( isWindowsDrive(cwd) ? '' : cwd.slice(0, cwd.lastIndexOf(pathDelimiter)) )
@@ -69,46 +61,61 @@ export default function FilePicker({ onSelect }: { onSelect:(v:string[])=>void }
61
setCwd('')
62
}
63
}, h(Home)),
72
- h(TextField, {
73
- value: filter,
74
- label: 'Filter results',
75
- onChange(ev) {
76
- setFilterBounced(ev.target.value)
77
- },
78
- sx: { minWidth: '20em' },
79
- fullWidth: true,
64
+ h(StringField, {
65
+ label: 'Current path',
66
+ value: cwd,
67
+ onChange: setCwd
68
}),
69
),
82
- h(StringField, {
83
- label: 'Current path',
84
- value: cwd,
85
- onChange: setCwd
86
- }),
70
error ? h(Alert, { severity:'error' }, String(error))
71
: !list.length ? h(Typography, { p:1 }, 'No elements in this folder')
89
- : h(MenuList, { sx:{ maxHeight: 'calc(100vh - 24em)', overflow:'auto' } },
90
- list.map((it:DirEntry) =>
91
- h(MenuItem, {
92
- key: it.n,
93
- sx: { display: filterMatch(it.n) ? undefined : 'none' },
94
- onClick(){
95
- const id = it.n
96
- const removed = sel.filter(x => x !== id)
97
- setSel(removed.length < sel.length ? removed : [...sel, id])
72
+ : h(Box, {},
73
+ h(MenuList, { sx:{ maxHeight: 'calc(100vh - 24em)', overflow:'auto' } },
74
+ list.map((it:DirEntry) =>
75
+ h(MenuItem, {
76
+ key: it.n,
77
+ sx: { display: filterMatch(it.n) ? undefined : 'none' },
78
+ onClick(){
79
+ if (it.k === 'd')
80
+ setCwd( cwdPostfixed + it.n )
81
+ else
82
+ onSelect([ cwdPostfixed + it.n ])
83
+ }
84
},
99
- onDoubleClick(){
100
- if (it.k === 'd')
101
- setCwd( cwdPostfixed + it.n )
102
- else
103
- onSelect([ cwdPostfixed + it.n ])
104
- }
105
- },
106
- h(Checkbox, { checked: sel.includes(it.n) }),
107
- h(ListItemIcon, {}, h(it.k ? FolderIcon : FileIcon)),
108
- h(ListItemText, {}, it.n),
109
- it.k !== 'd' && it.s !== undefined && h(Typography, { variant:'body2', color:'text.secondary', ml:4 }, formatBytes(it.s) )
85
+ h(Checkbox, {
86
+ checked: sel.includes(it.n),
87
+ onClick(ev){
88
+ const id = it.n
89
+ const removed = sel.filter(x => x !== id)
90
+ setSel(removed.length < sel.length ? removed : [...sel, id])
91
+ ev.stopPropagation()
92
+ },
93
+ }),
94
+ h(ListItemIcon, {}, h(it.k ? FolderIcon : FileIcon)),
95
+ h(ListItemText, {}, it.n),
96
+ it.k !== 'd' && it.s !== undefined && h(Typography, { variant:'body2', color:'text.secondary', ml:4 }, formatBytes(it.s) )
97
+ )
98
)
111
- )
99
+ ),
100
+ h(Box, { display:'flex', gap: 1 },
101
+ h(Button, {
102
+ variant: 'contained',
103
+ disabled: !sel.length,
104
+ sx: { minWidth: 'max-content' },
105
+ onClick() {
106
+ onSelect(sel.map(x => cwdPostfixed + x))
107
+ }
108
+ }, `Select (${sel.length})`),
109
+ h(TextField, {
110
+ value: filter,
111
+ label: 'Filter results',
112
+ onChange(ev) {
113
+ setFilterBounced(ev.target.value)
114
+ },
115
+ sx: { minWidth: '20em' },
116
+ fullWidth: true,
117
+ }),
118
+ ),
119
)
120
)
121
}