Update toolbox library examples and interactions
All checks were successful
Deploy Sokko G / deploy (push) Successful in 6s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 6s
This commit is contained in:
parent
1a35dcae7b
commit
b52f1887dc
5 changed files with 4186 additions and 4144 deletions
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path fill="#000" d="M7.4 3.1c.9 0 1.6.7 1.6 1.6v5.1h.6V3.6c0-.9.7-1.6 1.6-1.6s1.6.7 1.6 1.6v6.2h.6V4.2c0-.9.7-1.6 1.6-1.6s1.6.7 1.6 1.6v6h.6V6.1c0-.9.7-1.6 1.6-1.6s1.6.7 1.6 1.6v7.2c0 5.2-2.7 8.7-7.1 8.7h-2.6c-2.5 0-4.4-1.2-5.7-3.3L2.9 15c-.6-.8-.4-1.8.4-2.4.8-.6 1.8-.4 2.4.3l1.1 1.3V4.7c0-.9.7-1.6 1.6-1.6z"/>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="4.5 2.2 21 27.6">
|
||||
<path fill="#000" d="M23,9.169V6.219l-4-1v-2.5l-6,1.5v2.869C10.462,7.498,9.406,9.439,9.102,11H5v12h4.167C9.5,24.006,10.361,25,12,25h1v2.781l6,1.5v-1.5l4-1v-1.949c1.006-0.333,2-1.193,2-2.831V12C25,10.361,24.006,9.502,23,9.169z M21,7.781V9h-2V7.281L21,7.781z M15,5.781l2-0.5V9h-2V5.781z M15,25h2v1.719l-2-0.5V25z M21,25.219l-2,0.5V25h2V25.219z M21.992,23H12c-0.806,0-0.988-0.55-1-1v-1H7v-8.006h3.988L11,12.005c0.005-0.434,0.134-2.369,2-2.881V11h8.988C22.45,11.012,23,11.195,23,12v1h-2v2h2v1h-2v2h2v1h-2v2h2v1C23,22.803,22.453,22.987,21.992,23z"/>
|
||||
</svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 383 B After Width: | Height: | Size: 621 B |
|
|
@ -33,16 +33,16 @@ const LIBRARY_TOOLBOX_ID = "library";
|
|||
|
||||
const MODULE_COMPONENTS = {
|
||||
notepad: { label: "Bloc notes", mode: "Texte riche", icon: "notepad", Component: NotepadModule },
|
||||
checklist: { label: "Checklist", mode: "Catégories + sans catégorie", icon: "checklist", Component: ChecklistModule, scrollable: true },
|
||||
images: { label: "Images", mode: "Média", icon: "picture", Component: ImagesModule, scrollable: true },
|
||||
links: { label: "Liens", mode: "Liste simple", icon: "link", Component: LinksModule, scrollable: true },
|
||||
counters: { label: "Compteurs", mode: "Valeurs", icon: "abacus", Component: CountersModule, scrollable: true },
|
||||
combos: { label: "Combos", mode: "Catégories", icon: "controller", Component: CombosModule, scrollable: true },
|
||||
checklist: { label: "Checklist", mode: "Catégories + sans catégorie", icon: "checklist", Component: ChecklistModule, editable: true, scrollable: true },
|
||||
images: { label: "Images", mode: "Média", icon: "picture", Component: ImagesModule, editable: true, scrollable: true },
|
||||
links: { label: "Liens", mode: "Liste simple", icon: "link", Component: LinksModule, editable: true, scrollable: true },
|
||||
counters: { label: "Compteurs", mode: "Valeurs", icon: "abacus", Component: CountersModule, editable: true, scrollable: true },
|
||||
combos: { label: "Combos", mode: "Catégories", icon: "controller", Component: CombosModule, editable: true, scrollable: true },
|
||||
calculator: { label: "Calculateur", mode: "Arborescence", icon: "calculator", Component: CalculatorModule },
|
||||
table: { label: "Tableau", mode: "Grille + formules", icon: "table", Component: TableModule, scrollable: true },
|
||||
timer: { label: "Timer", mode: "Chrono + comptes à rebours", icon: "clock", Component: TimerModule },
|
||||
taskPlanner: { label: "Planificateur de tâches", mode: "Catégories + parent/enfant", icon: "tasklist", Component: TaskPlannerModule, scrollable: true },
|
||||
imageAnnotation: { label: "Annotation d'images", mode: "Image + marqueurs", icon: "map", Component: ImageAnnotationModule }
|
||||
taskPlanner: { label: "Planificateur de tâches", mode: "Catégories + parent/enfant", icon: "tasklist", Component: TaskPlannerModule, editable: true, scrollable: true },
|
||||
imageAnnotation: { label: "Annotation d'images", mode: "Image + marqueurs", icon: "map", Component: ImageAnnotationModule, editable: true }
|
||||
};
|
||||
|
||||
function cloneData(value) {
|
||||
|
|
@ -51,6 +51,15 @@ function cloneData(value) {
|
|||
return JSON.parse(JSON.stringify(value));
|
||||
}
|
||||
|
||||
function fileToDataUrl(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener("load", () => resolve(String(reader.result || "")));
|
||||
reader.addEventListener("error", () => reject(reader.error || new Error("Image illisible.")));
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
|
||||
function createModuleDataFromPayload(payload) {
|
||||
return Object.fromEntries((payload?.toolbox?.modules || []).map((module) => [
|
||||
`${LIBRARY_TOOLBOX_ID}:${module.id}`,
|
||||
|
|
@ -134,11 +143,33 @@ export function LibraryPage({ siteContent, actions }) {
|
|||
return true;
|
||||
},
|
||||
notify: actions.notify,
|
||||
compressImageFile: async () => "",
|
||||
addImageFiles: async () => false,
|
||||
compressImageFile: fileToDataUrl,
|
||||
addImageFiles: async (toolboxId, moduleId, files) => {
|
||||
const imageFiles = [...files].filter((file) => file?.type?.startsWith("image/"));
|
||||
if (!imageFiles.length) return false;
|
||||
const images = await Promise.all(imageFiles.map(async (file) => ({
|
||||
id: uid("image"),
|
||||
label: file.name?.replace(/\.[^.]+$/, "").trim() || "",
|
||||
dataUrl: await fileToDataUrl(file)
|
||||
})));
|
||||
setModuleData((current) => {
|
||||
const key = `${toolboxId}:${moduleId}`;
|
||||
const data = current[key] || { images: [] };
|
||||
return { ...current, [key]: { ...data, images: [...(data.images || []), ...images] } };
|
||||
});
|
||||
return true;
|
||||
},
|
||||
setImage: actions.setImage,
|
||||
createImageAnnotationModule: () => {}
|
||||
}), [actions, moduleData, siteContent.toolboxes.modules]);
|
||||
createImageAnnotationModule: (dataUrl) => {
|
||||
const annotationModule = libraryPayload?.toolbox?.modules?.find((module) => module.type === "imageAnnotation");
|
||||
if (!annotationModule || !dataUrl) return;
|
||||
setModuleData((current) => ({
|
||||
...current,
|
||||
[`${LIBRARY_TOOLBOX_ID}:${annotationModule.id}`]: { image: dataUrl, markers: [], drawings: { strokes: [] } }
|
||||
}));
|
||||
requestAnimationFrame(() => scrollToLibraryTool(getLibraryAnchorId(annotationModule), true));
|
||||
}
|
||||
}), [actions, libraryPayload, moduleData, siteContent.toolboxes.modules]);
|
||||
|
||||
return (
|
||||
<div className="library-page">
|
||||
|
|
@ -209,6 +240,7 @@ function LibraryToolExample({ module, sourceData, description, context }) {
|
|||
const definition = MODULE_COMPONENTS[module.type] || MODULE_COMPONENTS.notepad;
|
||||
const Component = definition.Component;
|
||||
const [scrollable, setScrollable] = useState(false);
|
||||
const [editing, setEditing] = useState(false);
|
||||
const title = module.title || definition.label || "Outil";
|
||||
|
||||
return (
|
||||
|
|
@ -243,13 +275,25 @@ function LibraryToolExample({ module, sourceData, description, context }) {
|
|||
<i aria-hidden="true" />
|
||||
</button>
|
||||
)}
|
||||
{definition.editable && (
|
||||
<button
|
||||
className={`module-edit-button ${editing ? "active" : ""}`}
|
||||
type="button"
|
||||
onClick={() => setEditing((value) => !value)}
|
||||
aria-label={`${editing ? "Masquer" : "Afficher"} l'ajout de ${title}`}
|
||||
aria-pressed={editing}
|
||||
title={editing ? "Masquer l'ajout" : "Ajouter"}
|
||||
>
|
||||
<Icon name="add" />
|
||||
</button>
|
||||
)}
|
||||
<button className="library-reset-button" type="button" onClick={() => context.setModuleData(LIBRARY_TOOLBOX_ID, module.id, cloneData(sourceData))} aria-label={`Réinitialiser ${title}`} title="Réinitialiser l'exemple">
|
||||
<Icon name="refresh" />
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
<div className={`module-content ${scrollable ? "is-scrollable legacy-scrollbar" : ""}`}>
|
||||
<Component toolboxId={LIBRARY_TOOLBOX_ID} moduleId={module.id} context={context} editing={false} />
|
||||
<Component toolboxId={LIBRARY_TOOLBOX_ID} moduleId={module.id} context={context} editing={editing} />
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -380,10 +380,6 @@ span {
|
|||
padding: var(--space-4);
|
||||
}
|
||||
|
||||
.library-tool-example .module-add-panel {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.library-tool-example .image-annotation-stage,
|
||||
.library-tool-example .images-grid img {
|
||||
max-height: 260px;
|
||||
|
|
|
|||
|
|
@ -3208,12 +3208,12 @@ button.combo-device-n64.combo-value-down-right:hover {
|
|||
}
|
||||
|
||||
.combo-value-grab .ui-icon {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
width: 24px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
button.combo-input-token.combo-value-grab .ui-icon {
|
||||
width: 23px;
|
||||
width: 25px;
|
||||
height: 23px;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue