This commit is contained in:
j3d1 2026-08-24 21:35:38 +02:00
parent f87b689e27
commit 0c025db799
16 changed files with 555 additions and 105 deletions

View file

@ -86,14 +86,39 @@ export const LABEL_TEMPLATES = [
},
{
id: "rmqr-url", name: "rMQR Token", description: "The code with the encoded text printed next to it.",
required_vars: ["shortUrl","itemId"], tags: ["external"],
layout: [{type: "rmqr", content: c => c.shortUrl},GAP,{type: "text", content: c => c.itemId?.toString().padStart(4, "0")}]
required_vars: ["shortUrl", "itemId"], tags: ["external"],
layout: [{type: "rmqr", content: c => c.shortUrl}, GAP, {
type: "text",
content: c => c.itemId?.toString().padStart(4, "0")
}]
},
{
id: "mqr-tokem-id", name: "rMQR Token", description: "The code with the encoded text printed next to it.",
required_vars: ["shortId","itemId"], tags: ["internal"],
layout: [{type: "mqr", content: c => c.shortId},GAP,{type: "text", content: c => c.itemId?.toString().padStart(4, "0")}]
},...QR_ONLY_TEMPLATES,
required_vars: ["shortId", "itemId"], tags: ["internal"],
layout: [{type: "mqr", content: c => c.shortId}, GAP, {
type: "text",
content: c => c.itemId?.toString().padStart(4, "0")
}]
},
{
id: "location-rmqr-url", name: "rMQR Token", description: "The code with the encoded text printed next to it.",
required_vars: ["shortUrl", "locationId"], tags: ["external"],
layout: [{type: "rmqr", content: c => c.shortUrl}, GAP, {
type: "text",
content: c => c.locationId?.toString().padStart(4, "0")
}]
},
{
id: "location-mqr-tokem-id",
name: "rMQR Token",
description: "The code with the encoded text printed next to it.",
required_vars: ["shortId", "locationId"],
tags: ["internal"],
layout: [{type: "mqr", content: c => c.shortId}, GAP, {
type: "text",
content: c => c.locationId?.toString().padStart(4, "0")
}]
}, ...QR_ONLY_TEMPLATES,
{
id: "qr-text", name: "QR code + text", description: "The code with the encoded text printed next to it.",
@ -110,7 +135,7 @@ export const LABEL_TEMPLATES = [
id: "id-qr-text-vertical", name: "ID + QR code + text below",
description: "The code with the encoded text printed below it.",
required_vars: ["itemId", "text", "userHandle"],
layout: [[{type: "text", content: c => "Item: "+c.itemId}, GAP, {
layout: [[{type: "text", content: c => "Item: " + c.itemId}, GAP, {
type: "qr",
content: c => c.text
}, GAP, {type: "text", content: c => c.userHandle}]]
@ -148,6 +173,17 @@ export const LABEL_TEMPLATES = [
required_vars: ["userHandle", "itemId"], tags: ["internal"],
layout: [{type: "text", content: c => [c.userHandle, c.itemId]}]
},
{
id: "location-id", name: "Location ID", description: "Just the bare storage location id, as text only.",
required_vars: ["locationId"], tags: ["internal"],
layout: [{type: "text", content: c => c.locationId}]
},
{
id: "owner-id-text-location", name: "Owner + location ID",
description: "The owner's handle and the location id, as two lines of text - no code.",
required_vars: ["userHandle", "locationId"], tags: ["internal"],
layout: [{type: "text", content: c => [c.userHandle, c.locationId]}]
},
{
id: "item-url-qr-handle", name: "Item URL + handle",
description: "Scannable item URL, with the item's compact handle printed alongside.",
@ -272,14 +308,15 @@ export function templateIsAvailable(t, fields) {
}
// Resolves t's content leaves against fields into a tree for label.js's
// drawLabel/drawFallbackLabel, or null if nothing to render yet.
// drawLabel/drawFallbackLabel. Throws the same {message, short} shape as label.js's own
// capacity errors (see docs/implementation.md#missing-data-is-a-templatecontent-error) when a
// leaf isn't resolved yet, rather than returning null, so a caller's single catch around
// drawLabel/drawFallbackLabel handles both without a separate isAvailable pre-check.
export function templateContent(t, fields) {
const tree = mapTree(t.layout, leaf => leaf.type === "empty" ? leaf : {...leaf, value: leaf.content(fields)});
let hasContent = false;
walkLeaves(tree, leaf => {
if (leaf.type !== "empty" && leaf.value && (!Array.isArray(leaf.value) || leaf.value.some(Boolean))) {
hasContent = true;
}
});
return hasContent ? tree : null;
if (!templateIsAvailable(t, fields)) {
const err = new Error("This layout needs more fields filled in before it can be drawn.");
err.short = "missing data";
throw err;
}
return mapTree(t.layout, leaf => leaf.type === "empty" ? leaf : {...leaf, value: leaf.content(fields)});
}