feat(FN-3711): consolidate graph position storage and remove scopedStorage

Consolidated graph position storage into a canonical shared helper (`projectStorage.ts`) with hardened persistence logic and removed the duplicate `scopedStorage` module. Updated integration tests and documented the canonical storage approach. A smaller fix (`FN-3628`) addressed mobile touch targets

Fusion-Task-Id: FN-3711
This commit is contained in:
Fusion
2026-05-07 13:29:26 -07:00
committed by gsxdsm
parent 4f495fcc77
commit 7b6bc2e531
11 changed files with 79 additions and 132 deletions

View File

@@ -1,8 +1,8 @@
import { getScopedItem, removeScopedItem, setScopedItem } from "./scopedStorage";
import { getScopedItem, removeScopedItem, setScopedItem } from "@fusion/dashboard/app/utils/projectStorage";
export type NodePositions = Record<string, { x: number; y: number }>;
const STORAGE_KEY = "dependency-graph-positions";
const STORAGE_KEY = "fusion-plugin-dependency-graph:positions";
function isPosition(value: unknown): value is { x: number; y: number } {
if (!value || typeof value !== "object") return false;

View File

@@ -1,49 +0,0 @@
// Duplicated from packages/dashboard/app/utils/projectStorage.ts for plugin isolation.
// Keeps the same project-scoped key convention: kb:${projectId}:${baseKey}.
export function scopedKey(baseKey: string, projectId?: string | null): string {
if (typeof projectId !== "string" || projectId.length === 0) {
return baseKey;
}
return `kb:${projectId}:${baseKey}`;
}
export function getScopedItem(baseKey: string, projectId?: string | null): string | null {
if (typeof window === "undefined") {
return null;
}
const getItem = window.localStorage?.getItem;
if (typeof getItem !== "function") {
return null;
}
return getItem.call(window.localStorage, scopedKey(baseKey, projectId));
}
export function setScopedItem(baseKey: string, value: string, projectId?: string | null): void {
if (typeof window === "undefined") {
return;
}
const setItem = window.localStorage?.setItem;
if (typeof setItem !== "function") {
return;
}
setItem.call(window.localStorage, scopedKey(baseKey, projectId), value);
}
export function removeScopedItem(baseKey: string, projectId?: string | null): void {
if (typeof window === "undefined") {
return;
}
const removeItem = window.localStorage?.removeItem;
if (typeof removeItem !== "function") {
return;
}
removeItem.call(window.localStorage, scopedKey(baseKey, projectId));
}