Add toolbox library page with editable examples
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 7s
This commit is contained in:
parent
8eb622e05d
commit
9b72f4934c
20 changed files with 4774 additions and 31 deletions
|
|
@ -32,18 +32,27 @@ export function validateSiteContent(site) {
|
|||
"navigation.home",
|
||||
"navigation.toolboxes",
|
||||
"navigation.games",
|
||||
"navigation.library",
|
||||
"navigation.about",
|
||||
"navigation.mobileLibrary",
|
||||
"navigation.mobileGames",
|
||||
"sidebar.badge",
|
||||
"sidebar.note",
|
||||
"topbar.dashboard",
|
||||
"topbar.toolbox",
|
||||
"topbar.library",
|
||||
"topbar.games",
|
||||
"gamesPage.eyebrow",
|
||||
"gamesPage.title",
|
||||
"gamesPage.description",
|
||||
"gamesPage.emptyTitle",
|
||||
"gamesPage.emptyText",
|
||||
"library.eyebrow",
|
||||
"library.title",
|
||||
"library.description",
|
||||
"library.summaryLabel",
|
||||
"library.tocLabel",
|
||||
"library.toolsLabel",
|
||||
"home.hero.eyebrow",
|
||||
"home.hero.title",
|
||||
"home.hero.description",
|
||||
|
|
@ -65,6 +74,7 @@ export function validateSiteContent(site) {
|
|||
"about.title",
|
||||
"about.description",
|
||||
"about.toolsTitle",
|
||||
"about.toolsLibraryLink",
|
||||
"about.limitsTitle",
|
||||
"about.contribute.eyebrow",
|
||||
"about.contribute.title",
|
||||
|
|
@ -76,6 +86,7 @@ export function validateSiteContent(site) {
|
|||
"toolboxes.eyebrow",
|
||||
"toolboxes.title",
|
||||
"toolboxes.newButton",
|
||||
"toolboxes.libraryLink",
|
||||
"toolboxes.importAll",
|
||||
"toolboxes.exportAll",
|
||||
"toolboxes.importOne",
|
||||
|
|
@ -340,6 +351,16 @@ export function validateSiteContent(site) {
|
|||
|
||||
assertStringArray(site, "toolboxes.storageHelp.items", 3);
|
||||
|
||||
const librarySummaryItems = valueAt(site, "library.summaryItems");
|
||||
assert.ok(Array.isArray(librarySummaryItems), "library.summaryItems must be an array");
|
||||
assert.ok(librarySummaryItems.length >= 3, "library.summaryItems must contain at least 3 items");
|
||||
librarySummaryItems.forEach((item, index) => {
|
||||
assertNonEmptyString({ item }, `item.icon`);
|
||||
assertNonEmptyString({ item }, `item.title`);
|
||||
assertNonEmptyString({ item }, `item.text`);
|
||||
assert.equal(typeof item, "object", `library.summaryItems[${index}] must be an object`);
|
||||
});
|
||||
|
||||
const aboutLimits = valueAt(site, "about.limits");
|
||||
assert.ok(Array.isArray(aboutLimits), "about.limits must be an array");
|
||||
assert.ok(aboutLimits.length >= 3, "about.limits must contain at least 3 items");
|
||||
|
|
@ -381,6 +402,43 @@ export function validateSiteContent(site) {
|
|||
});
|
||||
}
|
||||
|
||||
export function validateLibraryData(payload) {
|
||||
assert.equal(typeof payload?.toolbox, "object", "library.toolbox must be an object");
|
||||
assert.equal(typeof payload?.modules, "object", "library.modules must be an object");
|
||||
assertNonEmptyString(payload, "toolbox.name");
|
||||
assert.ok(Array.isArray(payload.toolbox.modules), "library.toolbox.modules must be an array");
|
||||
assert.ok(payload.toolbox.modules.length >= 1, "library.toolbox.modules must not be empty");
|
||||
|
||||
const moduleIds = new Set();
|
||||
payload.toolbox.modules.forEach((module, index) => {
|
||||
assertNonEmptyString({ module }, "module.id");
|
||||
assertNonEmptyString({ module }, "module.type");
|
||||
assert.ok(!moduleIds.has(module.id), `library.toolbox.modules[${index}].id must be unique`);
|
||||
moduleIds.add(module.id);
|
||||
assert.equal(typeof payload.modules[module.id], "object", `library.modules.${module.id} must be an object`);
|
||||
});
|
||||
|
||||
["notepad", "checklist", "images", "links", "counters", "combos", "calculator", "table", "timer", "taskPlanner", "imageAnnotation"].forEach((type) => {
|
||||
assert.ok(payload.toolbox.modules.some((module) => module.type === type), `library must include a ${type} example`);
|
||||
});
|
||||
|
||||
const imagesModule = payload.toolbox.modules.find((module) => module.type === "images");
|
||||
const imagesData = payload.modules[imagesModule.id];
|
||||
assert.ok(Array.isArray(imagesData.images), "library images example must contain images");
|
||||
assert.ok(imagesData.images.length >= 1, "library images example must not be empty");
|
||||
imagesData.images.forEach((image, index) => {
|
||||
assertNonEmptyString({ image }, "image.id");
|
||||
assertNonEmptyString({ image }, "image.dataUrl");
|
||||
assert.match(image.dataUrl, /^data:image\//, `library images[${index}].dataUrl must be an inline image`);
|
||||
});
|
||||
|
||||
const taskModule = payload.toolbox.modules.find((module) => module.type === "taskPlanner");
|
||||
const taskData = payload.modules[taskModule.id];
|
||||
assert.ok(Array.isArray(taskData.tasks), "library task planner example must contain tasks");
|
||||
assert.ok(Array.isArray(taskData.relations), "library task planner example must contain relations");
|
||||
assert.ok(taskData.relations.length >= 1, "library task planner example must include a parent/child relation");
|
||||
}
|
||||
|
||||
function assertSnakeCase(value, path) {
|
||||
assert.equal(typeof value, "string", `${path} must be a string`);
|
||||
assert.match(value, SNAKE_CASE_RE, `${path} must be snake_case`);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue