refactor(webui): use central forms and table actions
This commit is contained in:
@@ -121,7 +121,7 @@ export default function OrganizationsAdminPanel({ settings, auth }: { settings:
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card title="i18n:govoplan-organizations.audit_and_retention.3ba1d2fc">
|
<Card title="i18n:govoplan-organizations.audit_and_retention.3ba1d2fc">
|
||||||
<div className="organizations-form-grid">
|
<div className="admin-form-grid two-columns">
|
||||||
<FormField label="i18n:govoplan-organizations.audit_detail_level.7397355d">
|
<FormField label="i18n:govoplan-organizations.audit_detail_level.7397355d">
|
||||||
<select value={draft.audit_detail_level} disabled={!canWrite || busy} onChange={(event) => setDraft({ ...draft, audit_detail_level: event.target.value as OrganizationAuditDetailLevel })}>
|
<select value={draft.audit_detail_level} disabled={!canWrite || busy} onChange={(event) => setDraft({ ...draft, audit_detail_level: event.target.value as OrganizationAuditDetailLevel })}>
|
||||||
{AUDIT_DETAIL_LEVELS.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
|
{AUDIT_DETAIL_LEVELS.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from "react";
|
||||||
import { Edit3, Plus, RefreshCw } from "lucide-react";
|
import { Edit3, Plus, RefreshCw } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
AdminIconButton,
|
|
||||||
ApiError,
|
ApiError,
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
@@ -13,6 +12,7 @@ import {
|
|||||||
ModuleSubnav,
|
ModuleSubnav,
|
||||||
PageTitle,
|
PageTitle,
|
||||||
StatusBadge,
|
StatusBadge,
|
||||||
|
TableActionGroup,
|
||||||
ToggleSwitch,
|
ToggleSwitch,
|
||||||
hasScope,
|
hasScope,
|
||||||
useUnsavedDraftGuard,
|
useUnsavedDraftGuard,
|
||||||
@@ -294,15 +294,6 @@ function activeStatus(active: boolean): JSX.Element {
|
|||||||
return <StatusBadge status={active ? "success" : "inactive"} label={active ? "i18n:govoplan-organizations.active.a733b809" : "i18n:govoplan-organizations.inactive.09af574c"} />;
|
return <StatusBadge status={active ? "success" : "inactive"} label={active ? "i18n:govoplan-organizations.active.a733b809" : "i18n:govoplan-organizations.inactive.09af574c"} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
function RowActions({ disabled, onEdit, extra }: { disabled: boolean; onEdit: () => void; extra?: JSX.Element[] }) {
|
|
||||||
return (
|
|
||||||
<div className="organizations-row-actions">
|
|
||||||
<AdminIconButton label="i18n:govoplan-organizations.edit.7dce1220" icon={<Edit3 size={16} aria-hidden="true" />} disabled={disabled} onClick={onEdit} />
|
|
||||||
{extra}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function SluggedFields({
|
function SluggedFields({
|
||||||
draft,
|
draft,
|
||||||
onChange,
|
onChange,
|
||||||
@@ -870,7 +861,7 @@ export default function OrganizationsPage({
|
|||||||
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, sortable: true, filterable: true, value: (row) => row.slug },
|
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, sortable: true, filterable: true, value: (row) => row.slug },
|
||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{ id: "description", header: "i18n:govoplan-organizations.description.55f8ebc8", minWidth: 220, value: (row) => row.description ?? "" },
|
{ id: "description", header: "i18n:govoplan-organizations.description.55f8ebc8", minWidth: 220, value: (row) => row.description ?? "" },
|
||||||
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editUnitType(row)} /> }
|
{ id: "actions", header: "i18n:govoplan-organizations.actions.c3cd636a", width: 72, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteModel || busy, onClick: () => editUnitType(row) }]} /> }
|
||||||
];
|
];
|
||||||
|
|
||||||
const structureColumns: DataGridColumn<OrganizationStructureItem>[] = [
|
const structureColumns: DataGridColumn<OrganizationStructureItem>[] = [
|
||||||
@@ -878,7 +869,7 @@ export default function OrganizationsPage({
|
|||||||
{ id: "kind", header: "i18n:govoplan-organizations.kind.794c9d9c", width: 140, sortable: true, filterable: true, value: (row) => row.structure_kind },
|
{ id: "kind", header: "i18n:govoplan-organizations.kind.794c9d9c", width: 140, sortable: true, filterable: true, value: (row) => row.structure_kind },
|
||||||
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, value: (row) => row.slug },
|
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, value: (row) => row.slug },
|
||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editStructure(row)} /> }
|
{ id: "actions", header: "i18n:govoplan-organizations.actions.c3cd636a", width: 72, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteModel || busy, onClick: () => editStructure(row) }]} /> }
|
||||||
];
|
];
|
||||||
|
|
||||||
const relationTypeColumns: DataGridColumn<OrganizationRelationTypeItem>[] = [
|
const relationTypeColumns: DataGridColumn<OrganizationRelationTypeItem>[] = [
|
||||||
@@ -888,7 +879,7 @@ export default function OrganizationsPage({
|
|||||||
{ id: "target", header: "i18n:govoplan-organizations.target_unit.a1507d86", minWidth: 170, render: (row) => optionalLabel(unitTypeById.get(row.target_unit_type_id || "")?.name) },
|
{ id: "target", header: "i18n:govoplan-organizations.target_unit.a1507d86", minWidth: 170, render: (row) => optionalLabel(unitTypeById.get(row.target_unit_type_id || "")?.name) },
|
||||||
{ id: "hierarchical", header: "i18n:govoplan-organizations.hierarchical.8964f313", width: 130, render: (row) => activeStatus(row.is_hierarchical) },
|
{ id: "hierarchical", header: "i18n:govoplan-organizations.hierarchical.8964f313", width: 130, render: (row) => activeStatus(row.is_hierarchical) },
|
||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editRelationType(row)} /> }
|
{ id: "actions", header: "i18n:govoplan-organizations.actions.c3cd636a", width: 72, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteModel || busy, onClick: () => editRelationType(row) }]} /> }
|
||||||
];
|
];
|
||||||
|
|
||||||
const unitColumns: DataGridColumn<OrganizationUnitItem>[] = [
|
const unitColumns: DataGridColumn<OrganizationUnitItem>[] = [
|
||||||
@@ -897,7 +888,7 @@ export default function OrganizationsPage({
|
|||||||
{ id: "parent", header: "i18n:govoplan-organizations.parent_unit.1986c35e", minWidth: 180, render: (row) => optionalLabel(unitById.get(row.parent_id || "")?.name) },
|
{ id: "parent", header: "i18n:govoplan-organizations.parent_unit.1986c35e", minWidth: 180, render: (row) => optionalLabel(unitById.get(row.parent_id || "")?.name) },
|
||||||
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, value: (row) => row.slug },
|
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, value: (row) => row.slug },
|
||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteUnits || busy} onEdit={() => editUnit(row)} /> }
|
{ id: "actions", header: "i18n:govoplan-organizations.actions.c3cd636a", width: 72, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteUnits || busy, onClick: () => editUnit(row) }]} /> }
|
||||||
];
|
];
|
||||||
|
|
||||||
const relationColumns: DataGridColumn<OrganizationRelationItem>[] = [
|
const relationColumns: DataGridColumn<OrganizationRelationItem>[] = [
|
||||||
@@ -906,7 +897,7 @@ export default function OrganizationsPage({
|
|||||||
{ id: "source", header: "i18n:govoplan-organizations.source_unit.2fbd8baa", minWidth: 190, render: (row) => optionalLabel(unitById.get(row.source_unit_id)?.name) },
|
{ id: "source", header: "i18n:govoplan-organizations.source_unit.2fbd8baa", minWidth: 190, render: (row) => optionalLabel(unitById.get(row.source_unit_id)?.name) },
|
||||||
{ id: "target", header: "i18n:govoplan-organizations.target_unit.a1507d86", minWidth: 190, render: (row) => optionalLabel(unitById.get(row.target_unit_id)?.name) },
|
{ id: "target", header: "i18n:govoplan-organizations.target_unit.a1507d86", minWidth: 190, render: (row) => optionalLabel(unitById.get(row.target_unit_id)?.name) },
|
||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteUnits || busy} onEdit={() => editRelation(row)} /> }
|
{ id: "actions", header: "i18n:govoplan-organizations.actions.c3cd636a", width: 72, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteUnits || busy, onClick: () => editRelation(row) }]} /> }
|
||||||
];
|
];
|
||||||
|
|
||||||
const functionTypeColumns: DataGridColumn<OrganizationFunctionTypeItem>[] = [
|
const functionTypeColumns: DataGridColumn<OrganizationFunctionTypeItem>[] = [
|
||||||
@@ -915,7 +906,7 @@ export default function OrganizationsPage({
|
|||||||
{ id: "delegable", header: "i18n:govoplan-organizations.delegable.b4f0137d", width: 120, render: (row) => activeStatus(row.delegable) },
|
{ id: "delegable", header: "i18n:govoplan-organizations.delegable.b4f0137d", width: 120, render: (row) => activeStatus(row.delegable) },
|
||||||
{ id: "actInPlace", header: "i18n:govoplan-organizations.act_in_place.49b942bd", width: 140, render: (row) => activeStatus(row.act_in_place_allowed) },
|
{ id: "actInPlace", header: "i18n:govoplan-organizations.act_in_place.49b942bd", width: 140, render: (row) => activeStatus(row.act_in_place_allowed) },
|
||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editFunctionType(row)} /> }
|
{ id: "actions", header: "i18n:govoplan-organizations.actions.c3cd636a", width: 72, sticky: "end", resizable: false, align: "right", render: (row) => <TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteModel || busy, onClick: () => editFunctionType(row) }]} /> }
|
||||||
];
|
];
|
||||||
|
|
||||||
const functionColumns: DataGridColumn<OrganizationFunctionItem>[] = [
|
const functionColumns: DataGridColumn<OrganizationFunctionItem>[] = [
|
||||||
@@ -926,19 +917,20 @@ export default function OrganizationsPage({
|
|||||||
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
{ id: "status", header: "i18n:govoplan-organizations.status.bae7d5be", width: 120, render: (row) => activeStatus(row.is_active) },
|
||||||
{
|
{
|
||||||
id: "actions",
|
id: "actions",
|
||||||
header: "",
|
header: "i18n:govoplan-organizations.actions.c3cd636a",
|
||||||
width: functionActionContributions.length ? 220 : 88,
|
width: functionActionContributions.length ? 220 : 88,
|
||||||
sticky: "end",
|
sticky: "end",
|
||||||
|
resizable: false,
|
||||||
|
align: "right",
|
||||||
render: (row) => (
|
render: (row) => (
|
||||||
<RowActions
|
<div className="organizations-row-actions">
|
||||||
disabled={!canWriteFunctions || busy}
|
<TableActionGroup actions={[{ id: "edit", label: "i18n:govoplan-organizations.edit.7dce1220", icon: <Edit3 size={16} aria-hidden="true" />, disabled: !canWriteFunctions || busy, onClick: () => editFunction(row) }]} />
|
||||||
onEdit={() => editFunction(row)}
|
{functionActionContributions.map((contribution) => (
|
||||||
extra={functionActionContributions.map((contribution) => (
|
|
||||||
<span className="organizations-contributed-action" key={contribution.id}>
|
<span className="organizations-contributed-action" key={contribution.id}>
|
||||||
{contribution.render({ settings, auth, function: row })}
|
{contribution.render({ settings, auth, function: row })}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
/>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@@ -1129,7 +1121,7 @@ export default function OrganizationsPage({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<form id={formId} className="organizations-form-grid" onSubmit={(event) => void submit(event)}>
|
<form id={formId} className="admin-form-grid two-columns" onSubmit={(event) => void submit(event)}>
|
||||||
{renderEditorFields()}
|
{renderEditorFields()}
|
||||||
</form>
|
</form>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -30,17 +30,6 @@
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.organizations-form-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
||||||
gap: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.organizations-form-grid .wide {
|
|
||||||
grid-column: 1 / -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.organizations-form-actions,
|
|
||||||
.organizations-row-actions {
|
.organizations-row-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -148,7 +137,7 @@
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.organizations-form-grid {
|
.organizations-page .admin-form-grid.two-columns {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user