Support deep links into organization editor
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useCallback, useEffect, useMemo, 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 {
|
||||
ApiError,
|
||||
@@ -118,6 +118,26 @@ type ActiveItem = {
|
||||
is_active: boolean;
|
||||
};
|
||||
|
||||
type OrganizationsInitialQuery = {
|
||||
section: OrganizationSection | "";
|
||||
unitId: string;
|
||||
functionId: string;
|
||||
};
|
||||
|
||||
function organizationSectionFromQuery(value: string | null): OrganizationSection | "" {
|
||||
return value === "model" || value === "units" || value === "relations" || value === "functions" ? value : "";
|
||||
}
|
||||
|
||||
function organizationsInitialQuery(): OrganizationsInitialQuery {
|
||||
if (typeof window === "undefined") return { section: "", unitId: "", functionId: "" };
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
section: organizationSectionFromQuery(params.get("section")),
|
||||
unitId: params.get("unit_id") || "",
|
||||
functionId: params.get("function_id") || ""
|
||||
};
|
||||
}
|
||||
|
||||
const EMPTY_MODEL: OrganizationModel = {
|
||||
unit_types: [],
|
||||
structures: [],
|
||||
@@ -345,7 +365,10 @@ export default function OrganizationsPage({
|
||||
}: OrganizationsPageProps) {
|
||||
const sectionSet = useMemo(() => new Set(availableSections.length ? availableSections : ALL_SECTIONS), [availableSections]);
|
||||
const firstAvailableSection = availableSections.find((section) => sectionSet.has(section)) ?? "model";
|
||||
const [active, setActive] = useState<OrganizationSection>(sectionSet.has(initialSection) ? initialSection : firstAvailableSection);
|
||||
const initialQuery = useMemo(() => organizationsInitialQuery(), []);
|
||||
const requestedInitialSection = initialQuery.section && sectionSet.has(initialQuery.section) ? initialQuery.section : initialSection;
|
||||
const [active, setActive] = useState<OrganizationSection>(sectionSet.has(requestedInitialSection) ? requestedInitialSection : firstAvailableSection);
|
||||
const appliedInitialQueryRef = useRef(false);
|
||||
const visibleSectionGroups = useMemo(() => sectionGroupsFor(sectionSet), [sectionSet]);
|
||||
const [model, setModel] = useState<OrganizationModel>(EMPTY_MODEL);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -784,6 +807,30 @@ export default function OrganizationsPage({
|
||||
setActive("functions");
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (appliedInitialQueryRef.current || loading) return;
|
||||
if (initialQuery.functionId) {
|
||||
const item = functionById.get(initialQuery.functionId);
|
||||
if (item) {
|
||||
appliedInitialQueryRef.current = true;
|
||||
editFunction(item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (initialQuery.unitId) {
|
||||
const item = unitById.get(initialQuery.unitId);
|
||||
if (item) {
|
||||
appliedInitialQueryRef.current = true;
|
||||
editUnit(item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (initialQuery.section && sectionSet.has(initialQuery.section)) {
|
||||
appliedInitialQueryRef.current = true;
|
||||
setActive(initialQuery.section);
|
||||
}
|
||||
}, [editFunction, editUnit, functionById, initialQuery, loading, sectionSet, unitById]);
|
||||
|
||||
const unitTypeColumns: DataGridColumn<OrganizationUnitTypeItem>[] = [
|
||||
{ id: "name", header: "i18n:govoplan-organizations.name.709a2322", minWidth: 180, sortable: true, filterable: true, value: (row) => row.name },
|
||||
{ id: "slug", header: "i18n:govoplan-organizations.slug.094da9b9", width: 160, sortable: true, filterable: true, value: (row) => row.slug },
|
||||
|
||||
Reference in New Issue
Block a user