|
|
|
@@ -1,10 +1,12 @@
|
|
|
|
import { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from "react";
|
|
|
|
import { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from "react";
|
|
|
|
import { Edit3, Plus, RefreshCw, Save, XCircle } from "lucide-react";
|
|
|
|
import { Edit3, Plus, RefreshCw } from "lucide-react";
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
|
|
|
|
AdminIconButton,
|
|
|
|
ApiError,
|
|
|
|
ApiError,
|
|
|
|
Button,
|
|
|
|
Button,
|
|
|
|
Card,
|
|
|
|
Card,
|
|
|
|
DataGrid,
|
|
|
|
DataGrid,
|
|
|
|
|
|
|
|
Dialog,
|
|
|
|
DismissibleAlert,
|
|
|
|
DismissibleAlert,
|
|
|
|
FormField,
|
|
|
|
FormField,
|
|
|
|
LoadingFrame,
|
|
|
|
LoadingFrame,
|
|
|
|
@@ -57,6 +59,7 @@ import {
|
|
|
|
|
|
|
|
|
|
|
|
export type OrganizationSection = "model" | "units" | "relations" | "functions";
|
|
|
|
export type OrganizationSection = "model" | "units" | "relations" | "functions";
|
|
|
|
type OrganizationsPageMode = "workspace" | "admin";
|
|
|
|
type OrganizationsPageMode = "workspace" | "admin";
|
|
|
|
|
|
|
|
type OrganizationEditor = "unitType" | "structure" | "relationType" | "unit" | "relation" | "functionType" | "function";
|
|
|
|
|
|
|
|
|
|
|
|
type OrganizationsPageProps = {
|
|
|
|
type OrganizationsPageProps = {
|
|
|
|
settings: ApiSettings;
|
|
|
|
settings: ApiSettings;
|
|
|
|
@@ -113,11 +116,6 @@ type FunctionDraft = SluggedDraft & {
|
|
|
|
act_in_place_allowed: boolean;
|
|
|
|
act_in_place_allowed: boolean;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
type ActiveItem = {
|
|
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
|
|
is_active: boolean;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type OrganizationsInitialQuery = {
|
|
|
|
type OrganizationsInitialQuery = {
|
|
|
|
section: OrganizationSection | "";
|
|
|
|
section: OrganizationSection | "";
|
|
|
|
unitId: string;
|
|
|
|
unitId: string;
|
|
|
|
@@ -295,22 +293,10 @@ 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 ActiveToggleButton({ item, disabled, onToggle }: { item: ActiveItem; disabled: boolean; onToggle: () => void }) {
|
|
|
|
function RowActions({ disabled, onEdit, extra }: { disabled: boolean; onEdit: () => void; extra?: JSX.Element[] }) {
|
|
|
|
const label = item.is_active ? "i18n:govoplan-organizations.deactivate.46ab070d" : "i18n:govoplan-organizations.reactivate.58f2855d";
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Button type="button" variant={item.is_active ? "secondary" : "primary"} disabled={disabled} onClick={onToggle} title={label}>
|
|
|
|
|
|
|
|
{label}
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function RowActions({ item, disabled, onEdit, onToggle, extra }: { item: ActiveItem; disabled: boolean; onEdit: () => void; onToggle: () => void; extra?: JSX.Element[] }) {
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="organizations-row-actions">
|
|
|
|
<div className="organizations-row-actions">
|
|
|
|
<Button type="button" variant="ghost" disabled={disabled} onClick={onEdit} title="i18n:govoplan-organizations.edit.7dce1220">
|
|
|
|
<AdminIconButton label="i18n:govoplan-organizations.edit.7dce1220" icon={<Edit3 size={16} aria-hidden="true" />} disabled={disabled} onClick={onEdit} />
|
|
|
|
<Edit3 size={16} aria-hidden="true" /> i18n:govoplan-organizations.edit.7dce1220
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
<ActiveToggleButton item={item} disabled={disabled} onToggle={onToggle} />
|
|
|
|
|
|
|
|
{extra}
|
|
|
|
{extra}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@@ -390,6 +376,7 @@ export default function OrganizationsPage({
|
|
|
|
const [editingRelationId, setEditingRelationId] = useState<string | null>(null);
|
|
|
|
const [editingRelationId, setEditingRelationId] = useState<string | null>(null);
|
|
|
|
const [editingFunctionTypeId, setEditingFunctionTypeId] = useState<string | null>(null);
|
|
|
|
const [editingFunctionTypeId, setEditingFunctionTypeId] = useState<string | null>(null);
|
|
|
|
const [editingFunctionId, setEditingFunctionId] = useState<string | null>(null);
|
|
|
|
const [editingFunctionId, setEditingFunctionId] = useState<string | null>(null);
|
|
|
|
|
|
|
|
const [activeEditor, setActiveEditor] = useState<OrganizationEditor | null>(null);
|
|
|
|
const [selectedUnitId, setSelectedUnitId] = useState("");
|
|
|
|
const [selectedUnitId, setSelectedUnitId] = useState("");
|
|
|
|
const [changeRequestId, setChangeRequestId] = useState("");
|
|
|
|
const [changeRequestId, setChangeRequestId] = useState("");
|
|
|
|
const functionActionCapabilities = usePlatformUiCapabilities<OrganizationFunctionActionsUiCapability>("organizations.functionActions");
|
|
|
|
const functionActionCapabilities = usePlatformUiCapabilities<OrganizationFunctionActionsUiCapability>("organizations.functionActions");
|
|
|
|
@@ -490,6 +477,8 @@ export default function OrganizationsPage({
|
|
|
|
setEditingRelationId(null);
|
|
|
|
setEditingRelationId(null);
|
|
|
|
setEditingFunctionTypeId(null);
|
|
|
|
setEditingFunctionTypeId(null);
|
|
|
|
setEditingFunctionId(null);
|
|
|
|
setEditingFunctionId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
function rejectMissingName(): Promise<boolean> {
|
|
|
|
function rejectMissingName(): Promise<boolean> {
|
|
|
|
@@ -513,6 +502,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setUnitTypeDraft(emptySluggedDraft());
|
|
|
|
setUnitTypeDraft(emptySluggedDraft());
|
|
|
|
setEditingUnitTypeId(null);
|
|
|
|
setEditingUnitTypeId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteModel, editingUnitTypeId, runAction, settings, unitTypeDraft, withChangeRequest]);
|
|
|
|
}, [canWriteModel, editingUnitTypeId, runAction, settings, unitTypeDraft, withChangeRequest]);
|
|
|
|
@@ -530,6 +521,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setStructureDraft(emptyStructureDraft());
|
|
|
|
setStructureDraft(emptyStructureDraft());
|
|
|
|
setEditingStructureId(null);
|
|
|
|
setEditingStructureId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteModel, editingStructureId, runAction, settings, structureDraft, withChangeRequest]);
|
|
|
|
}, [canWriteModel, editingStructureId, runAction, settings, structureDraft, withChangeRequest]);
|
|
|
|
@@ -561,6 +554,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setRelationTypeDraft(emptyRelationTypeDraft());
|
|
|
|
setRelationTypeDraft(emptyRelationTypeDraft());
|
|
|
|
setEditingRelationTypeId(null);
|
|
|
|
setEditingRelationTypeId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteModel, editingRelationTypeId, relationTypeDraft, runAction, settings, withChangeRequest]);
|
|
|
|
}, [canWriteModel, editingRelationTypeId, relationTypeDraft, runAction, settings, withChangeRequest]);
|
|
|
|
@@ -586,6 +581,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setUnitDraft(emptyUnitDraft());
|
|
|
|
setUnitDraft(emptyUnitDraft());
|
|
|
|
setEditingUnitId(null);
|
|
|
|
setEditingUnitId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteUnits, editingUnitId, runAction, settings, unitDraft, withChangeRequest]);
|
|
|
|
}, [canWriteUnits, editingUnitId, runAction, settings, unitDraft, withChangeRequest]);
|
|
|
|
@@ -606,6 +603,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setRelationDraft(emptyRelationDraft());
|
|
|
|
setRelationDraft(emptyRelationDraft());
|
|
|
|
setEditingRelationId(null);
|
|
|
|
setEditingRelationId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteUnits, editingRelationId, relationDraft, runAction, settings, withChangeRequest]);
|
|
|
|
}, [canWriteUnits, editingRelationId, relationDraft, runAction, settings, withChangeRequest]);
|
|
|
|
@@ -633,6 +632,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setFunctionTypeDraft(emptyFunctionTypeDraft());
|
|
|
|
setFunctionTypeDraft(emptyFunctionTypeDraft());
|
|
|
|
setEditingFunctionTypeId(null);
|
|
|
|
setEditingFunctionTypeId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteModel, editingFunctionTypeId, functionTypeDraft, runAction, settings, withChangeRequest]);
|
|
|
|
}, [canWriteModel, editingFunctionTypeId, functionTypeDraft, runAction, settings, withChangeRequest]);
|
|
|
|
@@ -666,6 +667,8 @@ export default function OrganizationsPage({
|
|
|
|
if (ok) {
|
|
|
|
if (ok) {
|
|
|
|
setFunctionDraft(emptyFunctionDraft());
|
|
|
|
setFunctionDraft(emptyFunctionDraft());
|
|
|
|
setEditingFunctionId(null);
|
|
|
|
setEditingFunctionId(null);
|
|
|
|
|
|
|
|
setActiveEditor(null);
|
|
|
|
|
|
|
|
setChangeRequestId("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
return ok;
|
|
|
|
}, [canWriteFunctions, editingFunctionId, functionDraft, runAction, settings, withChangeRequest]);
|
|
|
|
}, [canWriteFunctions, editingFunctionId, functionDraft, runAction, settings, withChangeRequest]);
|
|
|
|
@@ -704,44 +707,68 @@ export default function OrganizationsPage({
|
|
|
|
message: "i18n:govoplan-core.this_page_has_unsaved_changes_save_them_before_l.419a9d8b"
|
|
|
|
message: "i18n:govoplan-core.this_page_has_unsaved_changes_save_them_before_l.419a9d8b"
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const toggleUnitType = useCallback((item: OrganizationUnitTypeItem) => {
|
|
|
|
const openUnitTypeCreate = useCallback(() => {
|
|
|
|
void runAction(() => patchUnitType(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingUnitTypeId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setUnitTypeDraft(emptySluggedDraft());
|
|
|
|
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("unitType");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const toggleStructure = useCallback((item: OrganizationStructureItem) => {
|
|
|
|
const openStructureCreate = useCallback(() => {
|
|
|
|
void runAction(() => patchStructure(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingStructureId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setStructureDraft(emptyStructureDraft());
|
|
|
|
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("structure");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const toggleRelationType = useCallback((item: OrganizationRelationTypeItem) => {
|
|
|
|
const openRelationTypeCreate = useCallback(() => {
|
|
|
|
void runAction(() => patchRelationType(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingRelationTypeId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setRelationTypeDraft(emptyRelationTypeDraft());
|
|
|
|
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("relationType");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const toggleUnit = useCallback((item: OrganizationUnitItem) => {
|
|
|
|
const openUnitCreate = useCallback((parentId = "") => {
|
|
|
|
void runAction(() => patchUnit(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingUnitId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setUnitDraft({ ...emptyUnitDraft(), parent_id: parentId });
|
|
|
|
|
|
|
|
if (parentId) setSelectedUnitId(parentId);
|
|
|
|
|
|
|
|
setActive("units");
|
|
|
|
|
|
|
|
setActiveEditor("unit");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const toggleRelation = useCallback((item: OrganizationRelationItem) => {
|
|
|
|
const openRelationCreate = useCallback(() => {
|
|
|
|
void runAction(() => patchRelation(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingRelationId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setRelationDraft(emptyRelationDraft());
|
|
|
|
|
|
|
|
setActive("relations");
|
|
|
|
|
|
|
|
setActiveEditor("relation");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const toggleFunctionType = useCallback((item: OrganizationFunctionTypeItem) => {
|
|
|
|
const openFunctionTypeCreate = useCallback(() => {
|
|
|
|
void runAction(() => patchFunctionType(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingFunctionTypeId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setFunctionTypeDraft(emptyFunctionTypeDraft());
|
|
|
|
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("functionType");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const toggleFunction = useCallback((item: OrganizationFunctionItem) => {
|
|
|
|
const openFunctionCreate = useCallback((organizationUnitId = "") => {
|
|
|
|
void runAction(() => patchFunction(settings, item.id, withChangeRequest({ is_active: !item.is_active })));
|
|
|
|
setEditingFunctionId(null);
|
|
|
|
}, [runAction, settings, withChangeRequest]);
|
|
|
|
setFunctionDraft({ ...emptyFunctionDraft(), organization_unit_id: organizationUnitId || selectedUnitId });
|
|
|
|
|
|
|
|
setActive("functions");
|
|
|
|
|
|
|
|
setActiveEditor("function");
|
|
|
|
|
|
|
|
}, [selectedUnitId]);
|
|
|
|
|
|
|
|
|
|
|
|
const editUnitType = useCallback((item: OrganizationUnitTypeItem) => {
|
|
|
|
const editUnitType = useCallback((item: OrganizationUnitTypeItem) => {
|
|
|
|
setEditingUnitTypeId(item.id);
|
|
|
|
setEditingUnitTypeId(item.id);
|
|
|
|
setUnitTypeDraft(sluggedDraftFrom(item));
|
|
|
|
setUnitTypeDraft(sluggedDraftFrom(item));
|
|
|
|
setActive("model");
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("unitType");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const editStructure = useCallback((item: OrganizationStructureItem) => {
|
|
|
|
const editStructure = useCallback((item: OrganizationStructureItem) => {
|
|
|
|
setEditingStructureId(item.id);
|
|
|
|
setEditingStructureId(item.id);
|
|
|
|
setStructureDraft({ ...sluggedDraftFrom(item), structure_kind: item.structure_kind as OrganizationStructureKind });
|
|
|
|
setStructureDraft({ ...sluggedDraftFrom(item), structure_kind: item.structure_kind as OrganizationStructureKind });
|
|
|
|
setActive("model");
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("structure");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const editRelationType = useCallback((item: OrganizationRelationTypeItem) => {
|
|
|
|
const editRelationType = useCallback((item: OrganizationRelationTypeItem) => {
|
|
|
|
@@ -755,6 +782,7 @@ export default function OrganizationsPage({
|
|
|
|
allow_cycles: item.allow_cycles
|
|
|
|
allow_cycles: item.allow_cycles
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setActive("model");
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("relationType");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const editUnit = useCallback((item: OrganizationUnitItem) => {
|
|
|
|
const editUnit = useCallback((item: OrganizationUnitItem) => {
|
|
|
|
@@ -762,14 +790,12 @@ export default function OrganizationsPage({
|
|
|
|
setSelectedUnitId(item.id);
|
|
|
|
setSelectedUnitId(item.id);
|
|
|
|
setUnitDraft({ ...sluggedDraftFrom(item), unit_type_id: item.unit_type_id ?? "", parent_id: item.parent_id ?? "" });
|
|
|
|
setUnitDraft({ ...sluggedDraftFrom(item), unit_type_id: item.unit_type_id ?? "", parent_id: item.parent_id ?? "" });
|
|
|
|
setActive("units");
|
|
|
|
setActive("units");
|
|
|
|
|
|
|
|
setActiveEditor("unit");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const addSubunit = useCallback((item: OrganizationUnitItem) => {
|
|
|
|
const addSubunit = useCallback((item: OrganizationUnitItem) => {
|
|
|
|
setSelectedUnitId(item.id);
|
|
|
|
openUnitCreate(item.id);
|
|
|
|
setEditingUnitId(null);
|
|
|
|
}, [openUnitCreate]);
|
|
|
|
setUnitDraft({ ...emptyUnitDraft(), parent_id: item.id });
|
|
|
|
|
|
|
|
setActive("units");
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const editRelation = useCallback((item: OrganizationRelationItem) => {
|
|
|
|
const editRelation = useCallback((item: OrganizationRelationItem) => {
|
|
|
|
setEditingRelationId(item.id);
|
|
|
|
setEditingRelationId(item.id);
|
|
|
|
@@ -781,6 +807,7 @@ export default function OrganizationsPage({
|
|
|
|
is_active: item.is_active
|
|
|
|
is_active: item.is_active
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setActive("relations");
|
|
|
|
setActive("relations");
|
|
|
|
|
|
|
|
setActiveEditor("relation");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const editFunctionType = useCallback((item: OrganizationFunctionTypeItem) => {
|
|
|
|
const editFunctionType = useCallback((item: OrganizationFunctionTypeItem) => {
|
|
|
|
@@ -792,6 +819,7 @@ export default function OrganizationsPage({
|
|
|
|
act_in_place_allowed: item.act_in_place_allowed
|
|
|
|
act_in_place_allowed: item.act_in_place_allowed
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setActive("model");
|
|
|
|
setActive("model");
|
|
|
|
|
|
|
|
setActiveEditor("functionType");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
const editFunction = useCallback((item: OrganizationFunctionItem) => {
|
|
|
|
const editFunction = useCallback((item: OrganizationFunctionItem) => {
|
|
|
|
@@ -805,6 +833,7 @@ export default function OrganizationsPage({
|
|
|
|
act_in_place_allowed: item.act_in_place_allowed
|
|
|
|
act_in_place_allowed: item.act_in_place_allowed
|
|
|
|
});
|
|
|
|
});
|
|
|
|
setActive("functions");
|
|
|
|
setActive("functions");
|
|
|
|
|
|
|
|
setActiveEditor("function");
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
useEffect(() => {
|
|
|
|
@@ -836,7 +865,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: 220, sticky: "end", render: (row) => <RowActions item={row} disabled={!canWriteModel || busy} onEdit={() => editUnitType(row)} onToggle={() => toggleUnitType(row)} /> }
|
|
|
|
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editUnitType(row)} /> }
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const structureColumns: DataGridColumn<OrganizationStructureItem>[] = [
|
|
|
|
const structureColumns: DataGridColumn<OrganizationStructureItem>[] = [
|
|
|
|
@@ -844,7 +873,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: 220, sticky: "end", render: (row) => <RowActions item={row} disabled={!canWriteModel || busy} onEdit={() => editStructure(row)} onToggle={() => toggleStructure(row)} /> }
|
|
|
|
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editStructure(row)} /> }
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const relationTypeColumns: DataGridColumn<OrganizationRelationTypeItem>[] = [
|
|
|
|
const relationTypeColumns: DataGridColumn<OrganizationRelationTypeItem>[] = [
|
|
|
|
@@ -854,7 +883,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: 220, sticky: "end", render: (row) => <RowActions item={row} disabled={!canWriteModel || busy} onEdit={() => editRelationType(row)} onToggle={() => toggleRelationType(row)} /> }
|
|
|
|
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editRelationType(row)} /> }
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const unitColumns: DataGridColumn<OrganizationUnitItem>[] = [
|
|
|
|
const unitColumns: DataGridColumn<OrganizationUnitItem>[] = [
|
|
|
|
@@ -863,7 +892,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: 220, sticky: "end", render: (row) => <RowActions item={row} disabled={!canWriteUnits || busy} onEdit={() => editUnit(row)} onToggle={() => toggleUnit(row)} /> }
|
|
|
|
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteUnits || busy} onEdit={() => editUnit(row)} /> }
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const relationColumns: DataGridColumn<OrganizationRelationItem>[] = [
|
|
|
|
const relationColumns: DataGridColumn<OrganizationRelationItem>[] = [
|
|
|
|
@@ -872,7 +901,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: 220, sticky: "end", render: (row) => <RowActions item={row} disabled={!canWriteUnits || busy} onEdit={() => editRelation(row)} onToggle={() => toggleRelation(row)} /> }
|
|
|
|
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteUnits || busy} onEdit={() => editRelation(row)} /> }
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const functionTypeColumns: DataGridColumn<OrganizationFunctionTypeItem>[] = [
|
|
|
|
const functionTypeColumns: DataGridColumn<OrganizationFunctionTypeItem>[] = [
|
|
|
|
@@ -881,7 +910,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: 220, sticky: "end", render: (row) => <RowActions item={row} disabled={!canWriteModel || busy} onEdit={() => editFunctionType(row)} onToggle={() => toggleFunctionType(row)} /> }
|
|
|
|
{ id: "actions", header: "", width: 88, sticky: "end", render: (row) => <RowActions disabled={!canWriteModel || busy} onEdit={() => editFunctionType(row)} /> }
|
|
|
|
];
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const functionColumns: DataGridColumn<OrganizationFunctionItem>[] = [
|
|
|
|
const functionColumns: DataGridColumn<OrganizationFunctionItem>[] = [
|
|
|
|
@@ -893,14 +922,12 @@ export default function OrganizationsPage({
|
|
|
|
{
|
|
|
|
{
|
|
|
|
id: "actions",
|
|
|
|
id: "actions",
|
|
|
|
header: "",
|
|
|
|
header: "",
|
|
|
|
width: functionActionContributions.length ? 340 : 220,
|
|
|
|
width: functionActionContributions.length ? 220 : 88,
|
|
|
|
sticky: "end",
|
|
|
|
sticky: "end",
|
|
|
|
render: (row) => (
|
|
|
|
render: (row) => (
|
|
|
|
<RowActions
|
|
|
|
<RowActions
|
|
|
|
item={row}
|
|
|
|
|
|
|
|
disabled={!canWriteFunctions || busy}
|
|
|
|
disabled={!canWriteFunctions || busy}
|
|
|
|
onEdit={() => editFunction(row)}
|
|
|
|
onEdit={() => editFunction(row)}
|
|
|
|
onToggle={() => toggleFunction(row)}
|
|
|
|
|
|
|
|
extra={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 })}
|
|
|
|
@@ -913,10 +940,6 @@ export default function OrganizationsPage({
|
|
|
|
|
|
|
|
|
|
|
|
const canWriteActive = active === "model" ? canWriteModel : active === "units" || active === "relations" ? canWriteUnits : canWriteFunctions;
|
|
|
|
const canWriteActive = active === "model" ? canWriteModel : active === "units" || active === "relations" ? canWriteUnits : canWriteFunctions;
|
|
|
|
|
|
|
|
|
|
|
|
function cancelEditButton(onCancel: () => void) {
|
|
|
|
|
|
|
|
return <Button type="button" variant="ghost" onClick={onCancel} disabled={busy}>i18n:govoplan-organizations.cancel_edit.309c2a6f</Button>;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const content = (
|
|
|
|
const content = (
|
|
|
|
<div className={`${mode === "workspace" ? "content-pad " : ""}organizations-page ${mode === "admin" ? "organizations-admin-page" : ""}`.trim()}>
|
|
|
|
<div className={`${mode === "workspace" ? "content-pad " : ""}organizations-page ${mode === "admin" ? "organizations-admin-page" : ""}`.trim()}>
|
|
|
|
<div className="page-heading split organizations-heading">
|
|
|
|
<div className="page-heading split organizations-heading">
|
|
|
|
@@ -925,23 +948,9 @@ export default function OrganizationsPage({
|
|
|
|
<p>{description}</p>
|
|
|
|
<p>{description}</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="organizations-toolbar">
|
|
|
|
<div className="organizations-toolbar">
|
|
|
|
<label className="organizations-change-request">
|
|
|
|
|
|
|
|
<span>i18n:govoplan-organizations.change_request_id.a6e7fd6b</span>
|
|
|
|
|
|
|
|
<input value={changeRequestId} onChange={(event) => setChangeRequestId(event.target.value)} placeholder="cfgreq-..." disabled={busy} />
|
|
|
|
|
|
|
|
</label>
|
|
|
|
|
|
|
|
<Button type="button" onClick={() => void loadModel()} disabled={loading || busy} title="i18n:govoplan-organizations.reload.cce71553">
|
|
|
|
<Button type="button" onClick={() => void loadModel()} disabled={loading || busy} title="i18n:govoplan-organizations.reload.cce71553">
|
|
|
|
<RefreshCw size={16} aria-hidden="true" /> i18n:govoplan-organizations.reload.cce71553
|
|
|
|
<RefreshCw size={16} aria-hidden="true" /> i18n:govoplan-organizations.reload.cce71553
|
|
|
|
</Button>
|
|
|
|
</Button>
|
|
|
|
{hasDirtyDraft && (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<Button type="button" onClick={() => void saveDrafts()} disabled={busy} title="i18n:govoplan-organizations.save_drafts.606f9401">
|
|
|
|
|
|
|
|
<Save size={16} aria-hidden="true" /> i18n:govoplan-organizations.save_drafts.606f9401
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
<Button type="button" variant="ghost" onClick={discardDrafts} disabled={busy} title="i18n:govoplan-organizations.discard_organization_drafts.766d5f46">
|
|
|
|
|
|
|
|
<XCircle size={16} aria-hidden="true" /> i18n:govoplan-organizations.discard_organization_drafts.766d5f46
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
@@ -955,6 +964,7 @@ export default function OrganizationsPage({
|
|
|
|
{active === "relations" && renderRelationsSection()}
|
|
|
|
{active === "relations" && renderRelationsSection()}
|
|
|
|
{active === "functions" && renderFunctionsSection()}
|
|
|
|
{active === "functions" && renderFunctionsSection()}
|
|
|
|
</LoadingFrame>
|
|
|
|
</LoadingFrame>
|
|
|
|
|
|
|
|
{renderEditorDialog()}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
@@ -972,100 +982,19 @@ export default function OrganizationsPage({
|
|
|
|
function renderModelSection() {
|
|
|
|
function renderModelSection() {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="organizations-table-stack">
|
|
|
|
<div className="organizations-table-stack">
|
|
|
|
<div className="organizations-section-grid">
|
|
|
|
<Card title="i18n:govoplan-organizations.unit_types.c7afc174" collapsible collapseKey="organizations.unit-types" actions={<AdminIconButton label="i18n:govoplan-organizations.add_unit_type.58f2c05a" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteModel || busy} onClick={openUnitTypeCreate} />}>
|
|
|
|
<Card title="i18n:govoplan-organizations.unit_types.c7afc174">
|
|
|
|
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitUnitType(event)}>
|
|
|
|
|
|
|
|
<SluggedFields draft={unitTypeDraft} onChange={setUnitTypeDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteModel || busy}>{editingUnitTypeId ? "i18n:govoplan-organizations.update_unit_type.b96fc0ad" : "i18n:govoplan-organizations.add_unit_type.58f2c05a"}</Button>
|
|
|
|
|
|
|
|
{editingUnitTypeId && cancelEditButton(() => { setEditingUnitTypeId(null); setUnitTypeDraft(emptySluggedDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.unit_types.c7afc174">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-unit-types" rows={model.unit_types} columns={unitTypeColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_unit_types_found.c81fb2a7" initialFit="container" />
|
|
|
|
<DataGrid id="organizations-unit-types" rows={model.unit_types} columns={unitTypeColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_unit_types_found.c81fb2a7" initialFit="container" />
|
|
|
|
</Card>
|
|
|
|
</Card>
|
|
|
|
</div>
|
|
|
|
<Card title="i18n:govoplan-organizations.structures.f9b7f3b4" collapsible collapseKey="organizations.structures" actions={<AdminIconButton label="i18n:govoplan-organizations.add_structure.b722042a" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteModel || busy} onClick={openStructureCreate} />}>
|
|
|
|
<div className="organizations-section-grid">
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.structures.f9b7f3b4">
|
|
|
|
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitStructure(event)}>
|
|
|
|
|
|
|
|
<SluggedFields draft={structureDraft} onChange={setStructureDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.kind.794c9d9c">
|
|
|
|
|
|
|
|
<select value={structureDraft.structure_kind} disabled={!canWriteModel || busy} onChange={(event) => setStructureDraft({ ...structureDraft, structure_kind: event.target.value as OrganizationStructureKind })}>
|
|
|
|
|
|
|
|
{STRUCTURE_KINDS.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteModel || busy}>{editingStructureId ? "i18n:govoplan-organizations.update_structure.b2e25446" : "i18n:govoplan-organizations.add_structure.b722042a"}</Button>
|
|
|
|
|
|
|
|
{editingStructureId && cancelEditButton(() => { setEditingStructureId(null); setStructureDraft(emptyStructureDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.structures.f9b7f3b4">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-structures" rows={model.structures} columns={structureColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_structures_found.20b382d0" initialFit="container" />
|
|
|
|
<DataGrid id="organizations-structures" rows={model.structures} columns={structureColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_structures_found.20b382d0" initialFit="container" />
|
|
|
|
</Card>
|
|
|
|
</Card>
|
|
|
|
</div>
|
|
|
|
<Card title="i18n:govoplan-organizations.relation_types.e5890528" collapsible collapseKey="organizations.relation-types" actions={<AdminIconButton label="i18n:govoplan-organizations.add_relation_type.2ad19d03" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteModel || busy} onClick={openRelationTypeCreate} />}>
|
|
|
|
<div className="organizations-section-grid">
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.relation_types.e5890528">
|
|
|
|
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitRelationType(event)}>
|
|
|
|
|
|
|
|
<SluggedFields draft={relationTypeDraft} onChange={setRelationTypeDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.structure.7732fb0b">
|
|
|
|
|
|
|
|
<select value={relationTypeDraft.structure_id} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, structure_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.structures.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.source_unit.2fbd8baa">
|
|
|
|
|
|
|
|
<select value={relationTypeDraft.source_unit_type_id} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, source_unit_type_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.unit_types.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.target_unit.a1507d86">
|
|
|
|
|
|
|
|
<select value={relationTypeDraft.target_unit_type_id} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, target_unit_type_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.unit_types.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<div className="organizations-check-list">
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={relationTypeDraft.is_hierarchical} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, is_hierarchical: event.target.checked })} /> i18n:govoplan-organizations.hierarchical.8964f313</label>
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={relationTypeDraft.allow_cycles} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, allow_cycles: event.target.checked })} /> i18n:govoplan-organizations.allow_cycles.31327578</label>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteModel || busy}>{editingRelationTypeId ? "i18n:govoplan-organizations.update_relation_type.e6e7f30c" : "i18n:govoplan-organizations.add_relation_type.2ad19d03"}</Button>
|
|
|
|
|
|
|
|
{editingRelationTypeId && cancelEditButton(() => { setEditingRelationTypeId(null); setRelationTypeDraft(emptyRelationTypeDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.relation_types.e5890528">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-relation-types" rows={model.relation_types} columns={relationTypeColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_relation_types_found.6f90bb81" initialFit="container" />
|
|
|
|
<DataGrid id="organizations-relation-types" rows={model.relation_types} columns={relationTypeColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_relation_types_found.6f90bb81" initialFit="container" />
|
|
|
|
</Card>
|
|
|
|
</Card>
|
|
|
|
</div>
|
|
|
|
<Card title="i18n:govoplan-organizations.function_types.172c01fe" collapsible collapseKey="organizations.function-types" actions={<AdminIconButton label="i18n:govoplan-organizations.add_function_type.90d793f1" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteModel || busy} onClick={openFunctionTypeCreate} />}>
|
|
|
|
<div className="organizations-section-grid">
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.function_types.172c01fe">
|
|
|
|
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitFunctionType(event)}>
|
|
|
|
|
|
|
|
<SluggedFields draft={functionTypeDraft} onChange={setFunctionTypeDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.unit_type.9e62810d">
|
|
|
|
|
|
|
|
<select value={functionTypeDraft.organization_unit_type_id} disabled={!canWriteModel || busy} onChange={(event) => setFunctionTypeDraft({ ...functionTypeDraft, organization_unit_type_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.unit_types.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<div className="organizations-check-list">
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={functionTypeDraft.delegable} disabled={!canWriteModel || busy} onChange={(event) => setFunctionTypeDraft({ ...functionTypeDraft, delegable: event.target.checked })} /> i18n:govoplan-organizations.delegable.b4f0137d</label>
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={functionTypeDraft.act_in_place_allowed} disabled={!canWriteModel || busy} onChange={(event) => setFunctionTypeDraft({ ...functionTypeDraft, act_in_place_allowed: event.target.checked })} /> i18n:govoplan-organizations.act_in_place.49b942bd</label>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteModel || busy}>{editingFunctionTypeId ? "i18n:govoplan-organizations.update_function_type.0b7e07d3" : "i18n:govoplan-organizations.add_function_type.90d793f1"}</Button>
|
|
|
|
|
|
|
|
{editingFunctionTypeId && cancelEditButton(() => { setEditingFunctionTypeId(null); setFunctionTypeDraft(emptyFunctionTypeDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.function_types.172c01fe">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-function-types" rows={model.function_types} columns={functionTypeColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_function_types_found.5eef31b1" initialFit="container" />
|
|
|
|
<DataGrid id="organizations-function-types" rows={model.function_types} columns={functionTypeColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_function_types_found.5eef31b1" initialFit="container" />
|
|
|
|
</Card>
|
|
|
|
</Card>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1096,20 +1025,167 @@ export default function OrganizationsPage({
|
|
|
|
|
|
|
|
|
|
|
|
function renderUnitsSection() {
|
|
|
|
function renderUnitsSection() {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="organizations-editor-grid">
|
|
|
|
<div className="organizations-table-stack">
|
|
|
|
<Card title="i18n:govoplan-organizations.organization_tree.e5bfb195">
|
|
|
|
<Card title="i18n:govoplan-organizations.organization_tree.e5bfb195" collapsible collapseKey="organizations.tree" 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="organizations-tree-toolbar">
|
|
|
|
<Button type="button" variant="secondary" disabled={!canWriteUnits || busy} onClick={() => { setEditingUnitId(null); setUnitDraft(emptyUnitDraft()); }} title="i18n:govoplan-organizations.add_root_unit.1ef8a9f5">
|
|
|
|
{selectedUnitId && <Button type="button" variant="ghost" disabled={busy} onClick={() => setSelectedUnitId("")}>i18n:govoplan-organizations.none.334c4a4c</Button>}
|
|
|
|
<Plus size={16} aria-hidden="true" /> i18n:govoplan-organizations.add_root_unit.1ef8a9f5
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="organizations-tree-list">
|
|
|
|
<div className="organizations-tree-list">
|
|
|
|
{model.units.length ? renderUnitTreeNodes() : <p className="muted small-note">i18n:govoplan-organizations.no_units_found.eea2dd0c</p>}
|
|
|
|
{model.units.length ? renderUnitTreeNodes() : <p className="muted small-note">i18n:govoplan-organizations.no_units_found.eea2dd0c</p>}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</Card>
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.units.e14d0d92" collapsible collapseKey="organizations.units" 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" />
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function renderRelationsSection() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="organizations-table-stack">
|
|
|
|
<div className="organizations-table-stack">
|
|
|
|
<Card title="i18n:govoplan-organizations.add_unit.8fa12fb1">
|
|
|
|
<Card title="i18n:govoplan-organizations.relations.1c796711" collapsible collapseKey="organizations.relations" actions={<AdminIconButton label="i18n:govoplan-organizations.add_relation.6b6e67ea" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteUnits || busy} onClick={openRelationCreate} />}>
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitUnit(event)}>
|
|
|
|
<DataGrid id="organizations-relations" rows={model.relations} columns={relationColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_relations_found.4e75b11d" initialFit="container" />
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function renderFunctionsSection() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div className="organizations-table-stack">
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.functions.805dc49b" collapsible collapseKey="organizations.functions" actions={<AdminIconButton label="i18n:govoplan-organizations.add_function.6abafee0" icon={<Plus size={16} aria-hidden="true" />} variant="primary" disabled={!canWriteFunctions || busy} onClick={() => openFunctionCreate()} />}>
|
|
|
|
|
|
|
|
<DataGrid id="organizations-functions" rows={model.functions} columns={functionColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_functions_found.54e759a0" initialFit="container" />
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function renderChangeRequestField() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div className="wide organizations-dialog-change-request">
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.change_request_id.a6e7fd6b">
|
|
|
|
|
|
|
|
<input value={changeRequestId} onChange={(event) => setChangeRequestId(event.target.value)} placeholder="cfgreq-..." disabled={busy} />
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<p className="organizations-field-note">i18n:govoplan-organizations.change_request_id_help.0c119a5d</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function editorTitle(): string {
|
|
|
|
|
|
|
|
switch (activeEditor) {
|
|
|
|
|
|
|
|
case "unitType": return editingUnitTypeId ? "i18n:govoplan-organizations.update_unit_type.b96fc0ad" : "i18n:govoplan-organizations.add_unit_type.58f2c05a";
|
|
|
|
|
|
|
|
case "structure": return editingStructureId ? "i18n:govoplan-organizations.update_structure.b2e25446" : "i18n:govoplan-organizations.add_structure.b722042a";
|
|
|
|
|
|
|
|
case "relationType": return editingRelationTypeId ? "i18n:govoplan-organizations.update_relation_type.e6e7f30c" : "i18n:govoplan-organizations.add_relation_type.2ad19d03";
|
|
|
|
|
|
|
|
case "unit": return editingUnitId ? "i18n:govoplan-organizations.update_unit.67e2500f" : "i18n:govoplan-organizations.add_unit.8fa12fb1";
|
|
|
|
|
|
|
|
case "relation": return editingRelationId ? "i18n:govoplan-organizations.update_relation.4c44ce83" : "i18n:govoplan-organizations.add_relation.6b6e67ea";
|
|
|
|
|
|
|
|
case "functionType": return editingFunctionTypeId ? "i18n:govoplan-organizations.update_function_type.0b7e07d3" : "i18n:govoplan-organizations.add_function_type.90d793f1";
|
|
|
|
|
|
|
|
case "function": return editingFunctionId ? "i18n:govoplan-organizations.update_function.504f03e5" : "i18n:govoplan-organizations.add_function.6abafee0";
|
|
|
|
|
|
|
|
default: return "i18n:govoplan-organizations.organizations.220edf64";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function editorSubmitDisabled(): boolean {
|
|
|
|
|
|
|
|
if (busy || !activeEditor) return true;
|
|
|
|
|
|
|
|
if ((activeEditor === "unitType" || activeEditor === "structure" || activeEditor === "relationType" || activeEditor === "functionType") && !canWriteModel) return true;
|
|
|
|
|
|
|
|
if ((activeEditor === "unit" || activeEditor === "relation") && !canWriteUnits) return true;
|
|
|
|
|
|
|
|
if (activeEditor === "function" && !canWriteFunctions) return true;
|
|
|
|
|
|
|
|
if (activeEditor === "unitType") return !unitTypeDraft.name.trim();
|
|
|
|
|
|
|
|
if (activeEditor === "structure") return !structureDraft.name.trim();
|
|
|
|
|
|
|
|
if (activeEditor === "relationType") return !relationTypeDraft.name.trim();
|
|
|
|
|
|
|
|
if (activeEditor === "unit") return !unitDraft.name.trim();
|
|
|
|
|
|
|
|
if (activeEditor === "relation") return !relationDraft.structure_id || !relationDraft.relation_type_id || !relationDraft.source_unit_id || !relationDraft.target_unit_id;
|
|
|
|
|
|
|
|
if (activeEditor === "functionType") return !functionTypeDraft.name.trim();
|
|
|
|
|
|
|
|
if (activeEditor === "function") return !functionDraft.name.trim() || !functionDraft.organization_unit_id;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function renderEditorDialog() {
|
|
|
|
|
|
|
|
if (!activeEditor) return null;
|
|
|
|
|
|
|
|
const formId = `organizations-${activeEditor}-editor`;
|
|
|
|
|
|
|
|
const submit = activeEditor === "unitType" ? submitUnitType :
|
|
|
|
|
|
|
|
activeEditor === "structure" ? submitStructure :
|
|
|
|
|
|
|
|
activeEditor === "relationType" ? submitRelationType :
|
|
|
|
|
|
|
|
activeEditor === "unit" ? submitUnit :
|
|
|
|
|
|
|
|
activeEditor === "relation" ? submitRelation :
|
|
|
|
|
|
|
|
activeEditor === "functionType" ? submitFunctionType :
|
|
|
|
|
|
|
|
submitFunction;
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<Dialog
|
|
|
|
|
|
|
|
open={Boolean(activeEditor)}
|
|
|
|
|
|
|
|
title={editorTitle()}
|
|
|
|
|
|
|
|
onClose={() => !busy && discardDrafts()}
|
|
|
|
|
|
|
|
closeDisabled={busy}
|
|
|
|
|
|
|
|
className="admin-dialog admin-dialog-wide organizations-editor-dialog"
|
|
|
|
|
|
|
|
footer={(
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<Button type="button" onClick={discardDrafts} disabled={busy}>i18n:govoplan-organizations.cancel_edit.309c2a6f</Button>
|
|
|
|
|
|
|
|
<Button type="submit" form={formId} variant="primary" disabled={editorSubmitDisabled()}>{editorTitle()}</Button>
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<form id={formId} className="organizations-form-grid" onSubmit={(event) => void submit(event)}>
|
|
|
|
|
|
|
|
{renderEditorFields()}
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Dialog>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function renderEditorFields() {
|
|
|
|
|
|
|
|
if (activeEditor === "unitType") {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<SluggedFields draft={unitTypeDraft} onChange={setUnitTypeDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (activeEditor === "structure") {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<SluggedFields draft={structureDraft} onChange={setStructureDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.kind.794c9d9c">
|
|
|
|
|
|
|
|
<select value={structureDraft.structure_kind} disabled={!canWriteModel || busy} onChange={(event) => setStructureDraft({ ...structureDraft, structure_kind: event.target.value as OrganizationStructureKind })}>
|
|
|
|
|
|
|
|
{STRUCTURE_KINDS.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (activeEditor === "relationType") {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
|
|
|
|
<SluggedFields draft={relationTypeDraft} onChange={setRelationTypeDraft} disabled={!canWriteModel || busy} />
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.structure.7732fb0b">
|
|
|
|
|
|
|
|
<select value={relationTypeDraft.structure_id} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, structure_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.structures.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.source_unit.2fbd8baa">
|
|
|
|
|
|
|
|
<select value={relationTypeDraft.source_unit_type_id} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, source_unit_type_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.unit_types.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.target_unit.a1507d86">
|
|
|
|
|
|
|
|
<select value={relationTypeDraft.target_unit_type_id} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, target_unit_type_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.unit_types.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<div className="organizations-check-list">
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={relationTypeDraft.is_hierarchical} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, is_hierarchical: event.target.checked })} /> i18n:govoplan-organizations.hierarchical.8964f313</label>
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={relationTypeDraft.allow_cycles} disabled={!canWriteModel || busy} onChange={(event) => setRelationTypeDraft({ ...relationTypeDraft, allow_cycles: event.target.checked })} /> i18n:govoplan-organizations.allow_cycles.31327578</label>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (activeEditor === "unit") {
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
<SluggedFields draft={unitDraft} onChange={setUnitDraft} disabled={!canWriteUnits || busy} />
|
|
|
|
<SluggedFields draft={unitDraft} onChange={setUnitDraft} disabled={!canWriteUnits || busy} />
|
|
|
|
<FormField label="i18n:govoplan-organizations.unit_type.9e62810d">
|
|
|
|
<FormField label="i18n:govoplan-organizations.unit_type.9e62810d">
|
|
|
|
<select value={unitDraft.unit_type_id} disabled={!canWriteUnits || busy} onChange={(event) => setUnitDraft({ ...unitDraft, unit_type_id: event.target.value })}>
|
|
|
|
<select value={unitDraft.unit_type_id} disabled={!canWriteUnits || busy} onChange={(event) => setUnitDraft({ ...unitDraft, unit_type_id: event.target.value })}>
|
|
|
|
@@ -1128,25 +1204,13 @@ export default function OrganizationsPage({
|
|
|
|
i18n:govoplan-organizations.selected_parent.0e013d44 <strong>{unitById.get(unitDraft.parent_id)?.name ?? unitDraft.parent_id}</strong>
|
|
|
|
i18n:govoplan-organizations.selected_parent.0e013d44 <strong>{unitById.get(unitDraft.parent_id)?.name ?? unitDraft.parent_id}</strong>
|
|
|
|
</p>
|
|
|
|
</p>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteUnits || busy}>{editingUnitId ? "i18n:govoplan-organizations.update_unit.67e2500f" : "i18n:govoplan-organizations.add_unit.8fa12fb1"}</Button>
|
|
|
|
</>
|
|
|
|
{editingUnitId && cancelEditButton(() => { setEditingUnitId(null); setUnitDraft(emptyUnitDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.units.e14d0d92">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-units" rows={model.units} columns={unitColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_units_found.eea2dd0c" initialFit="container" />
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (activeEditor === "relation") {
|
|
|
|
function renderRelationsSection() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="organizations-section-grid">
|
|
|
|
<>
|
|
|
|
<Card title="i18n:govoplan-organizations.add_relation.6b6e67ea">
|
|
|
|
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitRelation(event)}>
|
|
|
|
|
|
|
|
<FormField label="i18n:govoplan-organizations.structure.7732fb0b">
|
|
|
|
<FormField label="i18n:govoplan-organizations.structure.7732fb0b">
|
|
|
|
<select value={relationDraft.structure_id} disabled={!canWriteUnits || busy} onChange={(event) => setRelationDraft({ ...relationDraft, structure_id: event.target.value })}>
|
|
|
|
<select value={relationDraft.structure_id} disabled={!canWriteUnits || busy} onChange={(event) => setRelationDraft({ ...relationDraft, structure_id: event.target.value })}>
|
|
|
|
<option value="">i18n:govoplan-organizations.select_structure.c10f551c</option>
|
|
|
|
<option value="">i18n:govoplan-organizations.select_structure.c10f551c</option>
|
|
|
|
@@ -1175,24 +1239,30 @@ export default function OrganizationsPage({
|
|
|
|
<input type="checkbox" checked={relationDraft.is_active} disabled={!canWriteUnits || busy} onChange={(event) => setRelationDraft({ ...relationDraft, is_active: event.target.checked })} />
|
|
|
|
<input type="checkbox" checked={relationDraft.is_active} disabled={!canWriteUnits || busy} onChange={(event) => setRelationDraft({ ...relationDraft, is_active: event.target.checked })} />
|
|
|
|
<span>i18n:govoplan-organizations.active.a733b809</span>
|
|
|
|
<span>i18n:govoplan-organizations.active.a733b809</span>
|
|
|
|
</label>
|
|
|
|
</label>
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteUnits || busy}>{editingRelationId ? "i18n:govoplan-organizations.update_relation.4c44ce83" : "i18n:govoplan-organizations.add_relation.6b6e67ea"}</Button>
|
|
|
|
</>
|
|
|
|
{editingRelationId && cancelEditButton(() => { setEditingRelationId(null); setRelationDraft(emptyRelationDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.relations.1c796711">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-relations" rows={model.relations} columns={relationColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_relations_found.4e75b11d" initialFit="container" />
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (activeEditor === "functionType") {
|
|
|
|
function renderFunctionsSection() {
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div className="organizations-section-grid">
|
|
|
|
<>
|
|
|
|
<Card title="i18n:govoplan-organizations.add_function.6abafee0">
|
|
|
|
<SluggedFields draft={functionTypeDraft} onChange={setFunctionTypeDraft} disabled={!canWriteModel || busy} />
|
|
|
|
<form className="organizations-form-grid" onSubmit={(event) => void submitFunction(event)}>
|
|
|
|
<FormField label="i18n:govoplan-organizations.unit_type.9e62810d">
|
|
|
|
|
|
|
|
<select value={functionTypeDraft.organization_unit_type_id} disabled={!canWriteModel || busy} onChange={(event) => setFunctionTypeDraft({ ...functionTypeDraft, organization_unit_type_id: event.target.value })}>
|
|
|
|
|
|
|
|
<option value="">i18n:govoplan-organizations.none.334c4a4c</option>
|
|
|
|
|
|
|
|
{model.unit_types.map((item) => <option key={item.id} value={item.id}>{item.name}</option>)}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</FormField>
|
|
|
|
|
|
|
|
<div className="organizations-check-list">
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={functionTypeDraft.delegable} disabled={!canWriteModel || busy} onChange={(event) => setFunctionTypeDraft({ ...functionTypeDraft, delegable: event.target.checked })} /> i18n:govoplan-organizations.delegable.b4f0137d</label>
|
|
|
|
|
|
|
|
<label><input type="checkbox" checked={functionTypeDraft.act_in_place_allowed} disabled={!canWriteModel || busy} onChange={(event) => setFunctionTypeDraft({ ...functionTypeDraft, act_in_place_allowed: event.target.checked })} /> i18n:govoplan-organizations.act_in_place.49b942bd</label>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<>
|
|
|
|
<SluggedFields draft={functionDraft} onChange={setFunctionDraft} disabled={!canWriteFunctions || busy} />
|
|
|
|
<SluggedFields draft={functionDraft} onChange={setFunctionDraft} disabled={!canWriteFunctions || busy} />
|
|
|
|
<FormField label="i18n:govoplan-organizations.unit.8fe4d595">
|
|
|
|
<FormField label="i18n:govoplan-organizations.unit.8fe4d595">
|
|
|
|
<select value={functionDraft.organization_unit_id} disabled={!canWriteFunctions || busy} onChange={(event) => setFunctionDraft({ ...functionDraft, organization_unit_id: event.target.value })}>
|
|
|
|
<select value={functionDraft.organization_unit_id} disabled={!canWriteFunctions || busy} onChange={(event) => setFunctionDraft({ ...functionDraft, organization_unit_id: event.target.value })}>
|
|
|
|
@@ -1210,16 +1280,8 @@ export default function OrganizationsPage({
|
|
|
|
<label><input type="checkbox" checked={functionDraft.delegable} disabled={!canWriteFunctions || busy} onChange={(event) => setFunctionDraft({ ...functionDraft, delegable: event.target.checked })} /> i18n:govoplan-organizations.delegable.b4f0137d</label>
|
|
|
|
<label><input type="checkbox" checked={functionDraft.delegable} disabled={!canWriteFunctions || busy} onChange={(event) => setFunctionDraft({ ...functionDraft, delegable: event.target.checked })} /> i18n:govoplan-organizations.delegable.b4f0137d</label>
|
|
|
|
<label><input type="checkbox" checked={functionDraft.act_in_place_allowed} disabled={!canWriteFunctions || busy} onChange={(event) => setFunctionDraft({ ...functionDraft, act_in_place_allowed: event.target.checked })} /> i18n:govoplan-organizations.act_in_place.49b942bd</label>
|
|
|
|
<label><input type="checkbox" checked={functionDraft.act_in_place_allowed} disabled={!canWriteFunctions || busy} onChange={(event) => setFunctionDraft({ ...functionDraft, act_in_place_allowed: event.target.checked })} /> i18n:govoplan-organizations.act_in_place.49b942bd</label>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="organizations-form-actions wide">
|
|
|
|
{renderChangeRequestField()}
|
|
|
|
<Button type="submit" variant="primary" disabled={!canWriteFunctions || busy}>{editingFunctionId ? "i18n:govoplan-organizations.update_function.504f03e5" : "i18n:govoplan-organizations.add_function.6abafee0"}</Button>
|
|
|
|
</>
|
|
|
|
{editingFunctionId && cancelEditButton(() => { setEditingFunctionId(null); setFunctionDraft(emptyFunctionDraft()); })}
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
<Card title="i18n:govoplan-organizations.functions.805dc49b">
|
|
|
|
|
|
|
|
<DataGrid id="organizations-functions" rows={model.functions} columns={functionColumns} getRowKey={(row) => row.id} emptyText="i18n:govoplan-organizations.no_functions_found.54e759a0" initialFit="container" />
|
|
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|