admin/accounts: sorted list #747
Massimo Melina committed
Sep 22, 2024 at 12:31 UTC
c361da2fb954d6b7db70336f4715528bd7428fc2
2 files changed
+13
-13
admin/src/AccountsPage.ts
+11
-11
@@ -1,6 +1,6 @@
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"
3
+import { createElement as h, useState, useEffect, Fragment, useMemo } from "react"
4
import { apiCall, useApiEx } from './api'
5
import { Alert, Box, Card, CardContent, Grid, List, ListItem, ListItemText, Typography } from '@mui/material'
6
import { Close, Delete, DoNotDisturb, Group, MilitaryTech, Person, PersonAdd, Schedule } from '@mui/icons-material'
@@ -13,20 +13,20 @@ import _ from 'lodash'
13
import { alertDialog, confirmDialog, toast } from './dialog'
14
import { useSnapState } from './state'
15
import { importAccountsCsv } from './importAccountsCsv'
16
-import { AccountAdminSend } from '../../src/api.accounts'
16
+import apiAccounts from '../../src/api.accounts'
17
18
-export type Account = AccountAdminSend
18
+export type Account = ReturnType<typeof apiAccounts.get_accounts>['list'][0]
19
20
export default function AccountsPage() {
21
const { username } = useSnapState()
22
- const { data, reload, element } = useApiEx('get_accounts')
22
+ const { data, reload, element } = useApiEx<typeof apiAccounts.get_accounts>('get_accounts')
23
const [sel, setSel] = useState<string[] | 'new-group' | 'new-user'>([])
24
const selectionMode = Array.isArray(sel)
25
useEffect(() => { // if accounts are reloaded, review the selection to remove elements that don't exist anymore
26
if (Array.isArray(data?.list) && selectionMode)
27
- setSel( sel.filter(u => data.list.find((e:any) => e?.username === u)) ) // remove elements that don't exist anymore
27
+ setSel( sel.filter(u => data!.list.find((e:any) => e?.username === u)) ) // remove elements that don't exist anymore
28
}, [data]) //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
29
- const list: Account[] | undefined = data?.list
29
+ const list = useMemo(() => data && _.sortBy(data.list, [x => !x.adminActualAccess, 'username']), [data])
30
const selectedAccount = selectionMode && _.find(list, { username: sel[0] })
31
const sideBreakpoint = 'md'
32
const isSideBreakpoint = useBreakpoint(sideBreakpoint)
@@ -109,7 +109,7 @@ export default function AccountsPage() {
109
setSel(ids)
110
}
111
},
112
- list?.map((ac: Account) =>
112
+ list?.map(ac =>
113
h(TreeItem, {
114
key: ac.username,
115
nodeId: ac.username,
@@ -155,8 +155,8 @@ export default function AccountsPage() {
155
if (errors.length)
156
return alertDialog("Following elements couldn't be deleted: " + errors.join(', '), 'error')
157
}
158
-}
158
160
-export function account2icon(ac: Account, props={}) {
161
- return h(ac.hasPassword ? Person : Group, props)
162
-}
159
+ function account2icon(ac: Account, props={}) {
160
+ return h(ac.hasPassword ? Person : Group, props)
161
+ }
162
+}
\ No newline at end of file
src/api.accounts.ts
+2
-2
@@ -6,7 +6,7 @@ import { Account, accountCanLoginAdmin, accountHasPassword, accountsConfig, addA
6
import _ from 'lodash'
7
import { HTTP_BAD_REQUEST, HTTP_CONFLICT, HTTP_NOT_FOUND } from './const'
8
import { getCurrentUsername, invalidateSessionBefore } from './auth'
9
-import { apiAssertTypes } from './misc'
9
+import { apiAssertTypes, onlyTruthy } from './misc'
10
11
export type AccountAdminSend = NonNullable<ReturnType<typeof prepareAccount>>
12
function prepareAccount(ac: Account | undefined) {
@@ -31,7 +31,7 @@ export default {
31
},
32
33
get_accounts() {
34
- return { list: Object.values(accountsConfig.get()).map(prepareAccount) }
34
+ return { list: onlyTruthy(Object.values(accountsConfig.get()).map(prepareAccount)) }
35
},
36
37
get_admins() {