Add toolbox spaces and recover from stale asset bundles
All checks were successful
Deploy Sokko G / deploy (push) Successful in 18s

This commit is contained in:
Shinuwa 2026-09-29 21:31:49 +02:00
parent 0959c6740b
commit 0acf5ecf21
30 changed files with 1252 additions and 179 deletions

View file

@ -5,12 +5,14 @@ import {
createToolboxExportPayload,
globalModuleKey,
labelFromFileName,
MAX_TOOLBOX_SPACES,
normalizeToolbox,
remapModuleOrderIds,
uid
} from "./storage/toolboxStorage.js";
import { compressImage } from "../../utils/imageCompression.js";
import { getBackupFileName } from "./storage/autoBackup.js";
import { addModuleToToolboxSpace } from "./toolboxSpaceUtils.js";
function downloadJson(payload, filename) {
const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
@ -38,7 +40,7 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
title: creationTemplate?.links?.title || "Librairie des outils",
url: getLibraryUrl()
};
const toolbox = {
const toolbox = normalizeToolbox({
id: uid("tbx"),
name: name.trim() || "Nouvelle toolbox",
updatedAt: now,
@ -46,7 +48,7 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
{ id: memosModuleId, type: "memos", title: creationTemplate?.memos?.title || "Mémos" },
{ id: linksModuleId, type: "links", title: creationTemplate?.links?.moduleTitle || "Liens utiles" }
]
};
});
if (options.tutorial === true) toolbox.tutorial = true;
const memos = compactModuleDataForStorage("memos", { items: [{ id: uid("memo"), text: welcomeText, color: "#f6c453", updatedAt: now }] });
const links = compactModuleDataForStorage("links", { links: [libraryLink] });
@ -141,7 +143,7 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
if (!confirmed) return;
const updatedAt = new Date().toISOString();
store.setToolboxes((toolboxes) => toolboxes.map((item) => item.id === toolboxId
? { ...item, modules: [...item.modules, { id: moduleId, type: "checklist", title: list.title || "Checklist" }], updatedAt }
? { ...addModuleToToolboxSpace(item, { id: moduleId, type: "checklist", title: list.title || "Checklist" }, item.activeSpaceId), updatedAt }
: item));
store.updateModuleData(toolboxId, moduleId, { sections }, "checklist");
notify("Checklist créée dans la toolbox associée.");
@ -153,6 +155,9 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
async function importToolboxPayload(file, gameId = "") {
const payload = JSON.parse(await file.text());
if (!payload.toolbox?.modules) throw new Error("Format d'outils invalide");
if (Array.isArray(payload.toolbox.spaces) && payload.toolbox.spaces.length > MAX_TOOLBOX_SPACES) {
throw new Error(`Une toolbox ne peut pas contenir plus de ${MAX_TOOLBOX_SPACES} espaces.`);
}
const imported = normalizeToolbox({ ...payload.toolbox, id: uid("tbx"), updatedAt: new Date().toISOString() });
const moduleIdMap = new Map();
imported.modules = imported.modules.map((module) => {
@ -160,7 +165,14 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
moduleIdMap.set(module.id, nextId);
return { ...module, id: nextId };
});
imported.moduleOrder = remapModuleOrderIds(imported.moduleOrder, moduleIdMap);
const spaceIdMap = new Map(imported.spaces.map((space) => [space.id, uid("space")]));
imported.spaces = imported.spaces.map((space) => ({
...space,
id: spaceIdMap.get(space.id),
moduleOrder: remapModuleOrderIds(space.moduleOrder, moduleIdMap)
}));
imported.defaultSpaceId = spaceIdMap.get(imported.defaultSpaceId);
imported.activeSpaceId = spaceIdMap.get(imported.activeSpaceId);
const normalizedImport = normalizeToolbox(imported);
const nextModuleData = {};
Object.entries(payload.modules || {}).forEach(([oldId, data]) => {
@ -185,6 +197,9 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
if (!Array.isArray(payload.toolboxes) || !payload.modules || typeof payload.modules !== "object") {
throw new Error("Format d'import global invalide");
}
if (payload.toolboxes.some((toolbox) => Array.isArray(toolbox.spaces) && toolbox.spaces.length > MAX_TOOLBOX_SPACES)) {
throw new Error(`Une toolbox ne peut pas contenir plus de ${MAX_TOOLBOX_SPACES} espaces.`);
}
const toolboxIdMap = new Map();
const moduleIdMap = new Map();
const importedToolboxes = payload.toolboxes.map((toolbox) => {
@ -197,8 +212,23 @@ export function useToolboxActions({ store, notify, creationTemplate, setConfirmM
localModuleIdMap.set(module.id, nextModuleId);
return { ...module, id: nextModuleId };
});
const moduleOrder = remapModuleOrderIds(toolbox.moduleOrder, localModuleIdMap);
return normalizeToolbox({ ...toolbox, id: nextToolboxId, name: `${toolbox.name || "Toolbox"} (import)`, modules, moduleOrder, updatedAt: new Date().toISOString() });
const normalizedSource = normalizeToolbox({ ...toolbox, modules: toolbox.modules || [] });
const spaceIdMap = new Map(normalizedSource.spaces.map((space) => [space.id, uid("space")]));
const spaces = normalizedSource.spaces.map((space) => ({
...space,
id: spaceIdMap.get(space.id),
moduleOrder: remapModuleOrderIds(space.moduleOrder, localModuleIdMap)
}));
return normalizeToolbox({
...toolbox,
id: nextToolboxId,
name: `${toolbox.name || "Toolbox"} (import)`,
modules,
spaces,
defaultSpaceId: spaceIdMap.get(normalizedSource.defaultSpaceId),
activeSpaceId: spaceIdMap.get(normalizedSource.activeSpaceId),
updatedAt: new Date().toISOString()
});
});
const nextLinks = {};
Object.entries(payload.links || {}).forEach(([gameId, oldToolboxId]) => {