Support deep links into IDM assignments
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, RefreshCw, Save, XCircle } from "lucide-react";
|
||||
import {
|
||||
ApiError,
|
||||
@@ -219,6 +219,15 @@ function sourceLabel(value: string): string {
|
||||
return SOURCE_OPTIONS.find((item) => item.value === value)?.label ?? value;
|
||||
}
|
||||
|
||||
function idmInitialQuery(): { assignmentId: string; functionId: string } {
|
||||
if (typeof window === "undefined") return { assignmentId: "", functionId: "" };
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
return {
|
||||
assignmentId: params.get("assignment_id") || "",
|
||||
functionId: params.get("function_id") || ""
|
||||
};
|
||||
}
|
||||
|
||||
export default function IdmPage({ settings, auth }: IdmPageProps) {
|
||||
const [model, setModel] = useState<OrganizationModel>(EMPTY_MODEL);
|
||||
const [assignments, setAssignments] = useState<OrganizationFunctionAssignmentItem[]>([]);
|
||||
@@ -237,6 +246,8 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [error, setError] = useState("");
|
||||
const [success, setSuccess] = useState("");
|
||||
const initialQuery = useMemo(() => idmInitialQuery(), []);
|
||||
const appliedInitialQueryRef = useRef(false);
|
||||
|
||||
const canManage = hasScope(auth, "idm:organization_assignment:write") || hasScope(auth, "organizations:function:assign");
|
||||
const canSearchIdentities = canManage || hasScope(auth, "idm:organization_identity:read") || hasScope(auth, "admin:users:read");
|
||||
@@ -286,10 +297,7 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
||||
if (assignmentDraft.acting_for_account_id) values.add(assignmentDraft.acting_for_account_id);
|
||||
return Array.from(values).sort((left, right) => left.localeCompare(right));
|
||||
}, [actingForOptionById, actingForOptions, assignmentDraft.acting_for_account_id, identityOptionById, sourceAssignment]);
|
||||
const initialFunctionFilter = useMemo(() => {
|
||||
if (typeof window === "undefined") return "";
|
||||
return new URLSearchParams(window.location.search).get("function_id") || "";
|
||||
}, []);
|
||||
const initialFunctionFilter = initialQuery.functionId;
|
||||
const hasDirtyAssignmentDraft = isAssignmentDirty(assignmentDraft);
|
||||
const hasDirtySettingsDraft = canReadSettings && isSettingsDirty(settingsDraft, idmSettings);
|
||||
const hasDirtyDraft = hasDirtyAssignmentDraft || hasDirtySettingsDraft;
|
||||
@@ -307,7 +315,16 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
||||
setAssignments(nextAssignments.assignments);
|
||||
setIdmSettings(nextSettings);
|
||||
if (nextSettings) setSettingsDraft(settingsDraftFrom(nextSettings));
|
||||
if (initialFunctionFilter && nextModel.functions.some((item) => item.id === initialFunctionFilter)) {
|
||||
if (!appliedInitialQueryRef.current && initialQuery.assignmentId) {
|
||||
const initialAssignment = nextAssignments.assignments.find((item) => item.id === initialQuery.assignmentId);
|
||||
if (initialAssignment) {
|
||||
appliedInitialQueryRef.current = true;
|
||||
setEditingAssignmentId(initialAssignment.id);
|
||||
setAssignmentDraft(assignmentDraftFrom(initialAssignment));
|
||||
}
|
||||
}
|
||||
if (!appliedInitialQueryRef.current && initialFunctionFilter && nextModel.functions.some((item) => item.id === initialFunctionFilter)) {
|
||||
appliedInitialQueryRef.current = true;
|
||||
setAssignmentDraft((draft) => draft.function_id ? draft : { ...draft, function_id: initialFunctionFilter });
|
||||
}
|
||||
if (canSearchIdentities) {
|
||||
@@ -326,7 +343,7 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [canReadSettings, canSearchIdentities, initialFunctionFilter, settings]);
|
||||
}, [canReadSettings, canSearchIdentities, initialFunctionFilter, initialQuery.assignmentId, settings]);
|
||||
|
||||
useEffect(() => {
|
||||
void loadData();
|
||||
|
||||
Reference in New Issue
Block a user