UI: portal/header refinements, board index UX, and user settings
This commit is contained in:
@@ -12,6 +12,7 @@ export default function Acp({ isAdmin }) {
|
||||
const [selectedId, setSelectedId] = useState(null)
|
||||
const [draggingId, setDraggingId] = useState(null)
|
||||
const [overId, setOverId] = useState(null)
|
||||
const pendingOrder = useRef(null)
|
||||
const [createType, setCreateType] = useState(null)
|
||||
const [users, setUsers] = useState([])
|
||||
const [usersLoading, setUsersLoading] = useState(false)
|
||||
@@ -232,7 +233,7 @@ export default function Acp({ isAdmin }) {
|
||||
setError('')
|
||||
try {
|
||||
const data = await listAllForums()
|
||||
setForums(data)
|
||||
setForums(data.filter((forum) => !forum.deleted_at))
|
||||
} catch (err) {
|
||||
setError(err.message)
|
||||
} finally {
|
||||
@@ -394,6 +395,18 @@ export default function Acp({ isAdmin }) {
|
||||
})
|
||||
}
|
||||
|
||||
const handleStartCreateChild = (type, parentId) => {
|
||||
setSelectedId(null)
|
||||
setShowModal(true)
|
||||
setCreateType(type)
|
||||
setForm({
|
||||
name: '',
|
||||
description: '',
|
||||
type,
|
||||
parentId: parentId ? String(parentId) : '',
|
||||
})
|
||||
}
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault()
|
||||
setError('')
|
||||
@@ -402,6 +415,10 @@ export default function Acp({ isAdmin }) {
|
||||
setError(t('acp.forums_name_required'))
|
||||
return
|
||||
}
|
||||
if (form.type === 'forum' && !form.parentId) {
|
||||
setError(t('acp.forums_parent_required'))
|
||||
return
|
||||
}
|
||||
try {
|
||||
if (selectedId) {
|
||||
await updateForum(selectedId, {
|
||||
@@ -448,6 +465,11 @@ export default function Acp({ isAdmin }) {
|
||||
}
|
||||
|
||||
const handleDragEnd = () => {
|
||||
if (pendingOrder.current) {
|
||||
const { parentId, ordered } = pendingOrder.current
|
||||
pendingOrder.current = null
|
||||
reorderForums(parentId, ordered).catch((err) => setError(err.message))
|
||||
}
|
||||
setDraggingId(null)
|
||||
setOverId(null)
|
||||
}
|
||||
@@ -504,6 +526,7 @@ export default function Acp({ isAdmin }) {
|
||||
ordered.splice(toIndex, 0, ordered.splice(fromIndex, 1)[0])
|
||||
setOverId(String(targetId))
|
||||
applyLocalOrder(parentId, ordered)
|
||||
pendingOrder.current = { parentId, ordered }
|
||||
}
|
||||
|
||||
const handleDragEnter = (forumId) => {
|
||||
@@ -550,6 +573,7 @@ export default function Acp({ isAdmin }) {
|
||||
}
|
||||
|
||||
ordered.splice(toIndex, 0, ordered.splice(fromIndex, 1)[0])
|
||||
pendingOrder.current = null
|
||||
|
||||
try {
|
||||
await reorderForums(parentId, ordered)
|
||||
@@ -622,6 +646,24 @@ export default function Acp({ isAdmin }) {
|
||||
<i className="bi bi-arrow-down-up" aria-hidden="true" />
|
||||
</span>
|
||||
<ButtonGroup size="sm" className="bb-action-group">
|
||||
{node.type === 'category' && (
|
||||
<>
|
||||
<Button
|
||||
variant="dark"
|
||||
onClick={() => handleStartCreateChild('category', node.id)}
|
||||
title={t('acp.add_category')}
|
||||
>
|
||||
<i className="bi bi-folder-plus" aria-hidden="true" />
|
||||
</Button>
|
||||
<Button
|
||||
variant="dark"
|
||||
onClick={() => handleStartCreateChild('forum', node.id)}
|
||||
title={t('acp.add_forum')}
|
||||
>
|
||||
<i className="bi bi-chat-left-text" aria-hidden="true" />
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Button variant="dark" onClick={() => handleSelectForum(node)} title={t('acp.edit')}>
|
||||
<i className="bi bi-pencil" aria-hidden="true" />
|
||||
</Button>
|
||||
@@ -793,7 +835,9 @@ export default function Acp({ isAdmin }) {
|
||||
value={form.parentId}
|
||||
onChange={(event) => setForm({ ...form, parentId: event.target.value })}
|
||||
>
|
||||
<option value="">{t('acp.forums_parent_root')}</option>
|
||||
<option value="" disabled={form.type === 'forum'}>
|
||||
{t('acp.forums_parent_root')}
|
||||
</option>
|
||||
{categoryOptions
|
||||
.filter((option) => String(option.id) !== String(selectedId))
|
||||
.map((option) => (
|
||||
|
||||
Reference in New Issue
Block a user