add multi-page notepad and memos toolbox tool
All checks were successful
Deploy Sokko G / deploy (push) Successful in 16s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 16s
This commit is contained in:
parent
fcabbe8029
commit
6125336338
33 changed files with 3787 additions and 138 deletions
|
|
@ -8,6 +8,7 @@ import { compactEquipmentPlannerDataForStorage } from "./equipmentPlanner.js";
|
|||
import { compactGoalTreeDataForStorage } from "./goalTree.js";
|
||||
import { compactImageAnnotationDataForStorage, compactImagesDataForStorage } from "./imageAnnotation.js";
|
||||
import { compactLinksDataForStorage } from "./links.js";
|
||||
import { compactMemosDataForStorage } from "./memos.js";
|
||||
import { compactNotepadDataForStorage } from "./notepad.js";
|
||||
import { compactTableDataForStorage } from "./table.js";
|
||||
import { compactTaskPlannerDataForStorage } from "./taskPlanner.js";
|
||||
|
|
@ -15,6 +16,7 @@ import { compactTimerDataForStorage } from "./timer.js";
|
|||
|
||||
export const MODULE_DATA_COMPACTORS = {
|
||||
notepad: compactNotepadDataForStorage,
|
||||
memos: compactMemosDataForStorage,
|
||||
checklist: compactChecklistDataForStorage,
|
||||
images: compactImagesDataForStorage,
|
||||
imageAnnotation: compactImageAnnotationDataForStorage,
|
||||
|
|
|
|||
43
website/src/features/toolboxes/storage/modules/memos.js
Normal file
43
website/src/features/toolboxes/storage/modules/memos.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Rôle : normalise et compacte les mémos courts des toolboxes.
|
||||
import { NOTEPAD_ALLOWED_COLORS } from "./drawing.js";
|
||||
import { normalizeIsoDate, uid } from "./shared.js";
|
||||
|
||||
const DEFAULT_MEMO_COLOR = "#f6c453";
|
||||
|
||||
function normalizeMemoItem(item) {
|
||||
const text = String(item?.text || "").trim();
|
||||
if (!text) return null;
|
||||
const color = NOTEPAD_ALLOWED_COLORS.has(String(item?.color || "").toLowerCase()) ? String(item.color).toLowerCase() : DEFAULT_MEMO_COLOR;
|
||||
return {
|
||||
id: item?.id || uid("memo"),
|
||||
text,
|
||||
color,
|
||||
updatedAt: normalizeIsoDate(item?.updatedAt)
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeMemosData(data) {
|
||||
const source = data && typeof data === "object" ? data : {};
|
||||
return {
|
||||
tickerEnabled: source.tickerEnabled !== false,
|
||||
items: (Array.isArray(source.items) ? source.items : []).map(normalizeMemoItem).filter(Boolean)
|
||||
};
|
||||
}
|
||||
|
||||
export function compactMemosDataForStorage(value) {
|
||||
const normalized = normalizeMemosData(value);
|
||||
const compact = {};
|
||||
if (normalized.tickerEnabled === false) compact.tickerEnabled = false;
|
||||
if (normalized.items.length) {
|
||||
compact.items = normalized.items.map((item) => {
|
||||
const compactItem = {
|
||||
id: item.id,
|
||||
text: item.text,
|
||||
color: item.color
|
||||
};
|
||||
if (item.updatedAt) compactItem.updatedAt = item.updatedAt;
|
||||
return compactItem;
|
||||
});
|
||||
}
|
||||
return Object.keys(compact).length ? compact : null;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// Rôle : normalise, nettoie et compacte les données du bloc-notes riche.
|
||||
// Rôle : normalise, nettoie et compacte les pages du bloc-note riche.
|
||||
import { NOTEPAD_ALLOWED_COLORS, normalizeDrawingData } from "./drawing.js";
|
||||
import { normalizeIsoDate } from "./shared.js";
|
||||
import { normalizeIsoDate, uid } from "./shared.js";
|
||||
|
||||
const NOTEPAD_ALLOWED_TAGS = new Set(["p", "div", "br", "strong", "b", "em", "i", "u", "s", "strike", "ul", "ol", "li", "h3", "h4", "span", "mark"]);
|
||||
const NOTEPAD_RGB_COLOR_MAP = {
|
||||
|
|
@ -106,24 +106,66 @@ function notepadHtmlToText(value) {
|
|||
.trim();
|
||||
}
|
||||
|
||||
export function normalizeNotepadData(data) {
|
||||
const source = data && typeof data === "object" ? data : {};
|
||||
function normalizeNotepadPage(page, index = 0) {
|
||||
const source = page && typeof page === "object" ? page : {};
|
||||
const legacyText = String(source.text || "");
|
||||
const html = sanitizeNotepadHtml(source.html ? source.html : textToNotepadHtml(legacyText));
|
||||
const text = notepadHtmlToText(html) || legacyText.trim();
|
||||
const updatedAt = normalizeIsoDate(source.updatedAt);
|
||||
const drawingMode = source.drawingMode === "permanent" ? "permanent" : "temporary";
|
||||
const drawings = normalizeDrawingData(source.drawings);
|
||||
return { html, text, updatedAt, drawingMode, drawings };
|
||||
return {
|
||||
id: source.id || uid("page"),
|
||||
title: String(source.title || `Page ${index + 1}`).trim() || `Page ${index + 1}`,
|
||||
html,
|
||||
text,
|
||||
updatedAt,
|
||||
drawingMode,
|
||||
drawings
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeLegacyNotepadData(data) {
|
||||
const source = data && typeof data === "object" ? data : {};
|
||||
return normalizeNotepadPage({ ...source, id: source.id || uid("page"), title: source.title || "Page 1" }, 0);
|
||||
}
|
||||
|
||||
export function normalizeNotepadData(data) {
|
||||
const source = data && typeof data === "object" ? data : {};
|
||||
const pages = (Array.isArray(source.pages) ? source.pages : [normalizeLegacyNotepadData(source)])
|
||||
.map((page, index) => normalizeNotepadPage(page, index))
|
||||
.filter(Boolean);
|
||||
const normalizedPages = pages.length ? pages : [normalizeNotepadPage({ title: "Page 1" }, 0)];
|
||||
const activePageId = normalizedPages.some((page) => page.id === source.activePageId) ? source.activePageId : normalizedPages[0].id;
|
||||
const activePage = normalizedPages.find((page) => page.id === activePageId) || normalizedPages[0];
|
||||
return {
|
||||
activePageId,
|
||||
pages: normalizedPages,
|
||||
html: activePage.html,
|
||||
text: activePage.text,
|
||||
updatedAt: activePage.updatedAt,
|
||||
drawingMode: activePage.drawingMode,
|
||||
drawings: activePage.drawings
|
||||
};
|
||||
}
|
||||
|
||||
export function compactNotepadDataForStorage(value) {
|
||||
const normalized = normalizeNotepadData(value);
|
||||
const compact = {};
|
||||
if (normalized.html && normalized.text) compact.html = normalized.html;
|
||||
if (normalized.text) compact.text = normalized.text;
|
||||
if (normalized.updatedAt) compact.updatedAt = normalized.updatedAt;
|
||||
if (normalized.drawingMode === "permanent") compact.drawingMode = "permanent";
|
||||
if (normalized.drawingMode === "permanent" && normalized.drawings.strokes.length) compact.drawings = normalized.drawings;
|
||||
return Object.keys(compact).length ? compact : null;
|
||||
const hasMultiplePages = normalized.pages.length > 1;
|
||||
const pages = normalized.pages.map((page, index) => {
|
||||
const compact = {
|
||||
id: page.id,
|
||||
title: page.title || `Page ${index + 1}`
|
||||
};
|
||||
if (page.html && page.text) compact.html = page.html;
|
||||
if (page.text) compact.text = page.text;
|
||||
if (page.updatedAt) compact.updatedAt = page.updatedAt;
|
||||
if (page.drawingMode === "permanent") compact.drawingMode = "permanent";
|
||||
if (page.drawingMode === "permanent" && page.drawings.strokes.length) compact.drawings = page.drawings;
|
||||
return compact;
|
||||
}).filter((page) => hasMultiplePages || page.text || page.html || page.drawings?.strokes?.length || page.title !== "Page 1");
|
||||
if (!pages.length) return null;
|
||||
const compact = { pages };
|
||||
if (pages.some((page) => page.id === normalized.activePageId) && normalized.activePageId !== pages[0].id) compact.activePageId = normalized.activePageId;
|
||||
return compact;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ export const ID_PREFIXES = {
|
|||
goal: "g",
|
||||
relation: "e",
|
||||
stroke: "d",
|
||||
page: "p",
|
||||
memo: "w",
|
||||
equipmentType: "y",
|
||||
equipment: "q",
|
||||
trait: "v",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export { normalizeEquipmentPlannerData, summarizeEquipmentPlannerData } from "./
|
|||
export { normalizeGoalTreeData } from "./modules/goalTree.js";
|
||||
export { labelFromFileName, normalizeImageAnnotationData } from "./modules/imageAnnotation.js";
|
||||
export { hostnameFromUrl, normalizeLinksData, normalizeUrl } from "./modules/links.js";
|
||||
export { normalizeMemosData } from "./modules/memos.js";
|
||||
export { normalizeNotepadData, sanitizeNotepadHtml } from "./modules/notepad.js";
|
||||
export { uid } from "./modules/shared.js";
|
||||
export { normalizeTableData } from "./modules/table.js";
|
||||
|
|
@ -215,6 +216,28 @@ function remapModuleDataForExport(type, data, nextId) {
|
|||
return { counters: compact.counters.map((counter) => ({ ...counter, id: nextId("counter") })) };
|
||||
}
|
||||
|
||||
if (type === "memos") {
|
||||
const remapped = {};
|
||||
if (compact.tickerEnabled === false) remapped.tickerEnabled = false;
|
||||
if (compact.items) remapped.items = compact.items.map((memo) => ({ ...memo, id: nextId("memo") }));
|
||||
return remapped;
|
||||
}
|
||||
|
||||
if (type === "notepad") {
|
||||
const remapped = {
|
||||
pages: compact.pages.map((page) => ({
|
||||
...page,
|
||||
id: nextId("page"),
|
||||
drawings: page.drawings?.strokes?.length
|
||||
? { strokes: page.drawings.strokes.map((stroke) => ({ ...stroke, id: nextId("stroke") })) }
|
||||
: page.drawings
|
||||
}))
|
||||
};
|
||||
const activeIndex = compact.pages.findIndex((page) => page.id === compact.activePageId);
|
||||
if (activeIndex > 0) remapped.activePageId = remapped.pages[activeIndex].id;
|
||||
return remapped;
|
||||
}
|
||||
|
||||
if (type === "combos") {
|
||||
const remapped = {};
|
||||
if (compact.device) remapped.device = compact.device;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue