89 lines
2.5 KiB
TypeScript
89 lines
2.5 KiB
TypeScript
import { h } from 'preact'
|
|
import { useCallback, useEffect, useState } from 'preact/hooks'
|
|
import { route } from 'preact-router'
|
|
import rek, { type FetchError } from 'rek'
|
|
import type { Selectable } from 'kysely'
|
|
|
|
import { useNotifications } from '../contexts/notifications.tsx'
|
|
import useItemsReducer from '../hooks/use_items_reducer.ts'
|
|
import RoleForm from './role_form.tsx'
|
|
import Modal from './modal.tsx'
|
|
import RolesTable from './roles_table.tsx'
|
|
import PageHeader from './page_header.tsx'
|
|
import Section from './section.tsx'
|
|
|
|
import type { Role } from '../../../shared/types.db.ts'
|
|
|
|
const RolesPage = () => {
|
|
const { notify } = useNotifications()
|
|
const [roles, actions] = useItemsReducer<Selectable<Role>>()
|
|
const [edit, setEdit] = useState<Selectable<Role> | null | undefined>(null)
|
|
|
|
useEffect(() => {
|
|
rek('/api/roles' + location.search).then(actions.reset)
|
|
}, [location.search])
|
|
|
|
const onDelete = useCallback(async (id: number) => {
|
|
if (confirm(`Delete role ${id}?`)) {
|
|
try {
|
|
await rek.delete(`/api/roles/${id}`)
|
|
|
|
actions.del(id)
|
|
|
|
notify.success(`Role ${id} deleted`)
|
|
} catch (err) {
|
|
notify.error((err as FetchError).body?.message || (err as FetchError).toString())
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
const onEdit = useCallback(
|
|
async (id: number) => {
|
|
setEdit(id ? roles.find((role) => role.id === id) : null)
|
|
},
|
|
[roles],
|
|
)
|
|
|
|
const onSortBy = useCallback((column: string | null) => {
|
|
const searchParams = new URLSearchParams(location.search)
|
|
|
|
const newSort = (searchParams.get('sort') || 'id') === column ? '-' + column : column
|
|
|
|
route(location.pathname + (newSort !== 'id' ? `?sort=${newSort}` : ''))
|
|
}, [])
|
|
|
|
return (
|
|
<section>
|
|
<PageHeader>Roles</PageHeader>
|
|
|
|
<Section maxWidth='50%'>
|
|
<Section.Heading>Create New Role</Section.Heading>
|
|
|
|
<Section.Body>
|
|
<RoleForm onCreate={actions.add} />
|
|
</Section.Body>
|
|
</Section>
|
|
|
|
<Section>
|
|
<Section.Heading>List</Section.Heading>
|
|
|
|
<Section.Body noPadding>
|
|
<RolesTable roles={roles} onDelete={onDelete} onEdit={onEdit} onSortBy={onSortBy} />
|
|
</Section.Body>
|
|
</Section>
|
|
|
|
{edit != null && (
|
|
<Modal onClose={() => setEdit(null)}>
|
|
<RoleForm
|
|
onCancel={() => setEdit(null)}
|
|
onUpdate={(role: ANY) => actions.update(role.id, role)}
|
|
role={edit}
|
|
/>
|
|
</Modal>
|
|
)}
|
|
</section>
|
|
)
|
|
}
|
|
|
|
export default RolesPage
|