fix: admin/accounts: got empty form after creating new account

Massimo Melina committed Mar 30, 2022 at 18:12 UTC 65b5b56ccc65f7a8ee94ecdf123d382ac7936e99
1 file changed +22 -32
admin/src/AccountsPage.ts
+22 -32
@@ -32,18 +32,16 @@ interface Account {
32
33 export default function AccountsPage() {
34 const [res, reload] = useApiComp('get_accounts')
35 - const [sel, setSel] = useState<string[]>([])
36 - const [addGroup, setAddGroup] = useState<boolean|null>(null)
35 + const [sel, setSel] = useState<string[] | 'new-group' | 'new-user'>([])
36 + const selectionMode = Array.isArray(sel)
37 const styles = useStyles()
38 useEffect(() => { // if accounts are reloaded, review the selection to remove elements that don't exist anymore
39 - if (isValidElement(res) || !Array.isArray(res?.list)) return
40 - setSel( sel.filter(u => res.list.find((e:any) => e?.username === u)) ) // remove elements that don't exist anymore
39 + if (Array.isArray(res?.list) && selectionMode)
40 + setSel( sel.filter(u => res.list.find((e:any) => e?.username === u)) ) // remove elements that don't exist anymore
41 }, [res]) //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
42 if (isValidElement(res))
43 return res
44 const { list }: { list: Account[] } = res
45 - const account = addGroup !== null ? { username: '', hasPassword: !addGroup }
46 - : sel.length === 1 && list.find(x => x.username === sel[0])
45 return h(Grid, { container: true, maxWidth: '60em' },
46 h(Grid, { item: true, xs: 12 },
47 h(Box, {
@@ -63,14 +61,15 @@ export default function AccountsPage() {
61 variant: 'contained',
62 startIcon: h(PersonAdd),
63 items: [
66 - { children: "user", onClick: () => switchTo(false) },
67 - { children: "group", onClick: () => switchTo(true) }
64 + { children: "user", onClick: () => setSel('new-user') },
65 + { children: "group", onClick: () => setSel('new-group') }
66 ]
67 }, 'Add'),
68 h(Button, {
71 - disabled: !sel.length,
69 + disabled: !selectionMode,
70 startIcon: h(Delete),
71 async onClick(){
72 + if (!selectionMode) return
73 if (!await confirmDialog(`You are going to delete ${sel.length} account(s)`))
74 return
75 const errors = onlyTruthy(await Promise.all(sel.map(username =>
@@ -87,9 +86,9 @@ export default function AccountsPage() {
86 h(TreeView, {
87 multiSelect: true,
88 sx: { pr: 4, pb: 2, minWidth: '15em' },
90 - selected: sel,
89 + selected: selectionMode ? sel : [],
90 onNodeSelect(ev, ids) {
92 - switchTo(ids)
91 + setSel(ids)
92 }
93 },
94 list.map((ac: Account) =>
@@ -107,37 +106,28 @@ export default function AccountsPage() {
106 )
107 )
108 ),
110 - (addGroup !== null || sel.length > 0) && h(Grid, { item: true, md: 6 },
109 + sel.length > 0 // this clever test is true both when some accounts are selected and when we are in "new account" modes
110 + && h(Grid, { item: true, md: 6 },
111 h(Card, {},
112 h(CardContent, {},
113 - account ? h(AccountForm, {
114 - account,
113 + selectionMode && sel.length > 1 ? h(Box, {},
114 + h(Typography, {}, sel.length + " selected"),
115 + h(List, {},
116 + sel.map(username =>
117 + h(ListItem, { key: username },
118 + h(ListItemText, {}, username))))
119 + ) : h(AccountForm, {
120 + account: selectionMode && list.find(x => x.username === sel[0])
121 + || { username: '', hasPassword: sel === 'new-user' },
122 groups: list.filter(x => !x.hasPassword).map( x => x.username ),
123 close(){ setSel([]) },
124 done(username) {
125 setSel([username])
126 reload()
127 }
121 - }) : h(Box, {},
122 - h(Typography, {}, sel.length + " selected"),
123 - h(List, {},
124 - sel.map(username =>
125 - h(ListItem, { key: username },
126 - h(ListItemText, {}, username))))
127 - )
128 + })
129 )))
130 )
130 -
131 - function switchTo(what: boolean | string[]) {
132 - if (Array.isArray(what)) {
133 - setAddGroup(null)
134 - setSel(what)
135 - }
136 - else {
137 - setSel([])
138 - setAddGroup(what)
139 - }
140 - }
131 }
132
133 function hList(heading: string, list: any[]) {