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 { Edit3, RefreshCw, Save, XCircle } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
ApiError,
|
ApiError,
|
||||||
@@ -219,6 +219,15 @@ function sourceLabel(value: string): string {
|
|||||||
return SOURCE_OPTIONS.find((item) => item.value === value)?.label ?? value;
|
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) {
|
export default function IdmPage({ settings, auth }: IdmPageProps) {
|
||||||
const [model, setModel] = useState<OrganizationModel>(EMPTY_MODEL);
|
const [model, setModel] = useState<OrganizationModel>(EMPTY_MODEL);
|
||||||
const [assignments, setAssignments] = useState<OrganizationFunctionAssignmentItem[]>([]);
|
const [assignments, setAssignments] = useState<OrganizationFunctionAssignmentItem[]>([]);
|
||||||
@@ -237,6 +246,8 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
|||||||
const [busy, setBusy] = useState(false);
|
const [busy, setBusy] = useState(false);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const [success, setSuccess] = 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 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");
|
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);
|
if (assignmentDraft.acting_for_account_id) values.add(assignmentDraft.acting_for_account_id);
|
||||||
return Array.from(values).sort((left, right) => left.localeCompare(right));
|
return Array.from(values).sort((left, right) => left.localeCompare(right));
|
||||||
}, [actingForOptionById, actingForOptions, assignmentDraft.acting_for_account_id, identityOptionById, sourceAssignment]);
|
}, [actingForOptionById, actingForOptions, assignmentDraft.acting_for_account_id, identityOptionById, sourceAssignment]);
|
||||||
const initialFunctionFilter = useMemo(() => {
|
const initialFunctionFilter = initialQuery.functionId;
|
||||||
if (typeof window === "undefined") return "";
|
|
||||||
return new URLSearchParams(window.location.search).get("function_id") || "";
|
|
||||||
}, []);
|
|
||||||
const hasDirtyAssignmentDraft = isAssignmentDirty(assignmentDraft);
|
const hasDirtyAssignmentDraft = isAssignmentDirty(assignmentDraft);
|
||||||
const hasDirtySettingsDraft = canReadSettings && isSettingsDirty(settingsDraft, idmSettings);
|
const hasDirtySettingsDraft = canReadSettings && isSettingsDirty(settingsDraft, idmSettings);
|
||||||
const hasDirtyDraft = hasDirtyAssignmentDraft || hasDirtySettingsDraft;
|
const hasDirtyDraft = hasDirtyAssignmentDraft || hasDirtySettingsDraft;
|
||||||
@@ -307,7 +315,16 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
|||||||
setAssignments(nextAssignments.assignments);
|
setAssignments(nextAssignments.assignments);
|
||||||
setIdmSettings(nextSettings);
|
setIdmSettings(nextSettings);
|
||||||
if (nextSettings) setSettingsDraft(settingsDraftFrom(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 });
|
setAssignmentDraft((draft) => draft.function_id ? draft : { ...draft, function_id: initialFunctionFilter });
|
||||||
}
|
}
|
||||||
if (canSearchIdentities) {
|
if (canSearchIdentities) {
|
||||||
@@ -326,7 +343,7 @@ export default function IdmPage({ settings, auth }: IdmPageProps) {
|
|||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
}, [canReadSettings, canSearchIdentities, initialFunctionFilter, settings]);
|
}, [canReadSettings, canSearchIdentities, initialFunctionFilter, initialQuery.assignmentId, settings]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
void loadData();
|
void loadData();
|
||||||
|
|||||||
Reference in New Issue
Block a user