refactor(webui): use shared organization explorer tree
This commit is contained in:
@@ -8,7 +8,9 @@ import {
|
||||
DataGrid,
|
||||
Dialog,
|
||||
DismissibleAlert,
|
||||
ExplorerTree,
|
||||
FormField,
|
||||
IconButton,
|
||||
LoadingFrame,
|
||||
ModuleSubnav,
|
||||
PageTitle,
|
||||
@@ -1000,41 +1002,42 @@ export default function OrganizationsPage({
|
||||
);
|
||||
}
|
||||
|
||||
function renderUnitTreeNodes(parentId = "", depth = 0, seen: ReadonlySet<string> = new Set()): JSX.Element[] {
|
||||
return (unitsByParentId.get(parentId) ?? []).flatMap((unit) => {
|
||||
if (seen.has(unit.id)) return [];
|
||||
const nextSeen = new Set(seen);
|
||||
nextSeen.add(unit.id);
|
||||
return [
|
||||
<div className="organizations-tree-row" key={unit.id}>
|
||||
<button
|
||||
type="button"
|
||||
className={`organizations-tree-node ${selectedUnitId === unit.id ? "active" : ""}`.trim()}
|
||||
style={{ paddingLeft: `${10 + depth * 18}px` }}
|
||||
onClick={() => setSelectedUnitId(unit.id)}
|
||||
>
|
||||
<strong>{unit.name}</strong>
|
||||
<span>{unitTypeById.get(unit.unit_type_id || "")?.name ?? "i18n:govoplan-organizations.no_unit_type.73e799f5"}</span>
|
||||
</button>
|
||||
<Button type="button" variant="ghost" disabled={!canWriteUnits || busy} onClick={() => addSubunit(unit)} title="i18n:govoplan-organizations.add_subunit.8256a8f7">
|
||||
<Plus size={16} aria-hidden="true" /> i18n:govoplan-organizations.add_subunit.8256a8f7
|
||||
</Button>
|
||||
</div>,
|
||||
...renderUnitTreeNodes(unit.id, depth + 1, nextSeen)
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
function renderUnitsSection() {
|
||||
return (
|
||||
<div className="organizations-table-stack">
|
||||
<Card title="i18n:govoplan-organizations.organization_tree.e5bfb195" actions={<AdminIconButton label="i18n:govoplan-organizations.add_root_unit.1ef8a9f5" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteUnits || busy} onClick={() => openUnitCreate()} />}>
|
||||
<div className="organizations-tree-toolbar">
|
||||
<div className="explorer-tree-toolbar">
|
||||
{selectedUnitId && <Button type="button" variant="ghost" disabled={busy} onClick={() => setSelectedUnitId("")}>i18n:govoplan-organizations.none.334c4a4c</Button>}
|
||||
</div>
|
||||
<div className="organizations-tree-list">
|
||||
{model.units.length ? renderUnitTreeNodes() : <p className="muted small-note">i18n:govoplan-organizations.no_units_found.eea2dd0c</p>}
|
||||
</div>
|
||||
{model.units.length ? (
|
||||
<ExplorerTree
|
||||
nodes={unitsByParentId.get("") ?? []}
|
||||
getNodeId={(unit) => unit.id}
|
||||
getNodeLabel={(unit) => unit.name}
|
||||
getNodeChildren={(unit) => unitsByParentId.get(unit.id) ?? []}
|
||||
activeId={selectedUnitId}
|
||||
collapsible={false}
|
||||
depth={0}
|
||||
className="explorer-tree-scroll-region"
|
||||
getNodeWrapStyle={(_unit, context) => ({ paddingLeft: `${Math.min(context.depth * 18, 72)}px` })}
|
||||
onOpen={(unit) => setSelectedUnitId(unit.id)}
|
||||
renderNodeContent={(unit) => (
|
||||
<span className="explorer-tree-node-content">
|
||||
<strong>{unit.name}</strong>
|
||||
<small>{unitTypeById.get(unit.unit_type_id || "")?.name ?? "i18n:govoplan-organizations.no_unit_type.73e799f5"}</small>
|
||||
</span>
|
||||
)}
|
||||
renderNodeActions={(unit) => (
|
||||
<IconButton
|
||||
label="i18n:govoplan-organizations.add_subunit.8256a8f7"
|
||||
icon={<Plus size={16} aria-hidden="true" />}
|
||||
variant="ghost"
|
||||
disabled={!canWriteUnits || busy}
|
||||
onClick={() => addSubunit(unit)}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
) : <p className="muted small-note">i18n:govoplan-organizations.no_units_found.eea2dd0c</p>}
|
||||
</Card>
|
||||
<Card title="i18n:govoplan-organizations.units.e14d0d92" actions={<AdminIconButton label="i18n:govoplan-organizations.add_unit.8fa12fb1" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteUnits || busy} onClick={() => openUnitCreate()} />}>
|
||||
<DataGrid id="organizations-units" rows={model.units} columns={unitColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_units_found.eea2dd0c" initialFit="container" />
|
||||
|
||||
Reference in New Issue
Block a user