admin/accounts: delete multiple accounts
Massimo Melina committed
Feb 4, 2023 at 17:28 UTC
270a0488ccb60095063b8780fef45e941438d8d5
1 file changed
+30
-4
admin/src/AccountsPage.ts
+30
-4
@@ -1,15 +1,18 @@
1
// This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt
2
3
import { createElement as h, useState, useEffect, Fragment } from "react"
4
-import { useApiEx } from './api'
5
-import { Alert, Box, Card, CardContent, Grid, List, ListItem, ListItemText, Typography } from '@mui/material'
6
-import { Close, Group, MilitaryTech, Person, PersonAdd, Refresh } from '@mui/icons-material'
4
+import { apiCall, useApiEx } from './api'
5
+import { Alert, Box, Button, Card, CardContent, Grid, List, ListItem, ListItemText, Typography } from '@mui/material'
6
+import { Close, Delete, Group, MilitaryTech, Person, PersonAdd, Refresh } from '@mui/icons-material'
7
import { IconBtn, iconTooltip, newDialog, useBreakpoint } from './misc'
8
import { TreeItem, TreeView } from '@mui/lab'
9
import MenuButton from './MenuButton'
10
import AccountForm from './AccountForm'
11
import md from './md'
12
import _ from 'lodash'
13
+import { Flex } from '@hfs/frontend/src/components'
14
+import { alertDialog, confirmDialog } from './dialog'
15
+import { useSnapState } from './state'
16
17
export interface Account {
18
username: string
@@ -22,6 +25,7 @@ export interface Account {
25
}
26
27
export default function AccountsPage() {
28
+ const { username } = useSnapState()
29
const { data, reload, element } = useApiEx('get_accounts')
30
const [sel, setSel] = useState<string[] | 'new-group' | 'new-user'>([])
31
const selectionMode = Array.isArray(sel)
@@ -41,7 +45,10 @@ export default function AccountsPage() {
45
46
const sideContent = !(sel.length > 0) || !list ? null // this clever test is true both when some accounts are selected and when we are in "new account" modes
47
: selectionMode && sel.length > 1 ? h(Fragment, {},
44
- h(Typography, {}, sel.length + " selected"),
48
+ h(Flex, { alignItems: 'center' },
49
+ h(Typography, {variant: 'h6'}, sel.length + " selected"),
50
+ h(Button, { onClick: deleteAccounts, startIcon: h(Delete) }, "Remove"),
51
+ ),
52
h(List, {},
53
sel.map(username =>
54
h(ListItem, { key: username },
@@ -135,6 +142,25 @@ export default function AccountsPage() {
142
isSideBreakpoint && sideContent && h(Grid, { item: true, md: 7 },
143
h(Card, {}, h(CardContent, {}, sideContent) )),
144
)
145
+
146
+ async function deleteAccounts() {
147
+ if (sel.length > _.pull(sel, username).length)
148
+ await alertDialog("Won't delete current account", 'warning')
149
+ if (!sel.length) return
150
+ if (!await confirmDialog(`Delete ${sel.length} item(s)?`)) return
151
+ try {
152
+ const errors = []
153
+ for (const username of sel)
154
+ if (!await apiCall('del_account', { username }).then(() => 1, () => 0))
155
+ errors.push(username)
156
+ reload()
157
+ if (errors.length)
158
+ return alertDialog("Following elements couldn't be deleted: " + errors.join(', '), 'error')
159
+ }
160
+ catch(e) {
161
+ await alertDialog(e as Error)
162
+ }
163
+ }
164
}
165
166
export function account2icon(ac: Account, props={}) {