Add full shell, replaceable Omics adapter and bilingual interaction
Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
const SCHEMA_VERSION = 1;
|
||||
const RESERVED = ["back", "exit", "other"];
|
||||
const { gateText } = require("./locale.js");
|
||||
|
||||
const VALID_ACTION_KINDS = new Set(["confirm", "approve_reject", "view_only"]);
|
||||
const VALID_INFO_LEVELS = new Set(["info", "warning", "error"]);
|
||||
@@ -38,6 +39,7 @@ function requireArray(value, name, ctx) {
|
||||
// highlight as "(consigliato)".
|
||||
function buildSelectRequest({
|
||||
id, phase, title, options, intro = null, recommended = null,
|
||||
titleI18n,
|
||||
}) {
|
||||
requireString(title, "title", "select");
|
||||
const opts = requireArray(options, "options", "select");
|
||||
@@ -48,6 +50,7 @@ function buildSelectRequest({
|
||||
schema_version: SCHEMA_VERSION,
|
||||
widget: "select",
|
||||
title,
|
||||
...(titleI18n ? { title_i18n: titleI18n } : {}),
|
||||
intro,
|
||||
recommended,
|
||||
options: [...opts],
|
||||
@@ -61,7 +64,7 @@ function buildSelectRequest({
|
||||
// `allowEmpty:false` with zero options is a broken widget and throws.
|
||||
function buildMultiselectRequest({
|
||||
id, phase, title, options, content = null, selected = [], allowEmpty = false,
|
||||
selectionLabel, confirmLabel,
|
||||
selectionLabel, confirmLabel, titleI18n, selectionLabelI18n, confirmLabelI18n,
|
||||
}) {
|
||||
requireString(title, "title", "multiselect");
|
||||
const opts = requireArray(options, "options", "multiselect");
|
||||
@@ -77,6 +80,7 @@ function buildMultiselectRequest({
|
||||
schema_version: SCHEMA_VERSION,
|
||||
widget: "multiselect",
|
||||
title,
|
||||
...(titleI18n ? { title_i18n: titleI18n } : {}),
|
||||
allow_empty: allowEmpty,
|
||||
options: opts.map((option) => ({ ...option, selected: selected.includes(option.id) })),
|
||||
selected: [...selected],
|
||||
@@ -84,13 +88,15 @@ function buildMultiselectRequest({
|
||||
reserved: RESERVED,
|
||||
...(selectionLabel ? { selection_label: selectionLabel } : {}),
|
||||
...(confirmLabel ? { confirm_label: confirmLabel } : {}),
|
||||
...(selectionLabelI18n ? { selection_label_i18n: selectionLabelI18n } : {}),
|
||||
...(confirmLabelI18n ? { confirm_label_i18n: confirmLabelI18n } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
// Build an `artifact-gate` ui_request: a rendered artifact + a disposition list
|
||||
// (confirm / approve_reject / view_only). The decision is load-bearing on the
|
||||
// document, so the artifact is never shown alone (spec §4.1).
|
||||
function buildArtifactGate({ id, phase, title, artifact, action }) {
|
||||
function buildArtifactGate({ id, phase, title, artifact, action, locale = "en" }) {
|
||||
requireString(title, "title", "artifact-gate");
|
||||
if (!artifact || typeof artifact !== "object") {
|
||||
throw new Error("builders: artifact-gate requires an artifact object");
|
||||
@@ -105,10 +111,10 @@ function buildArtifactGate({ id, phase, title, artifact, action }) {
|
||||
}
|
||||
const ACTION_OPTIONS = {
|
||||
approve_reject: [
|
||||
{ id: "approve", label: "Salva e procedi", recommended: true },
|
||||
{ id: "reject", label: "Rifiuta" },
|
||||
{ id: "approve", label: gateText(locale, "save"), label_i18n: gateText("en", "save"), recommended: true },
|
||||
{ id: "reject", label: gateText(locale, "reject"), label_i18n: gateText("en", "reject") },
|
||||
],
|
||||
confirm: [{ id: "approve", label: "Salva e procedi", recommended: true }],
|
||||
confirm: [{ id: "approve", label: gateText(locale, "save"), label_i18n: gateText("en", "save"), recommended: true }],
|
||||
view_only: [],
|
||||
};
|
||||
return {
|
||||
@@ -180,7 +186,7 @@ function buildSchemaLinkingRequest({ id, phase, title, tables }) {
|
||||
// Build a blocking, read-only join review. The reviewer can accept the complete
|
||||
// proposal or use Other to request a textual correction; individual joins are
|
||||
// deliberately not selectable because omitting one could create a Cartesian product.
|
||||
function buildJoinReviewRequest({ id, phase, title, options }) {
|
||||
function buildJoinReviewRequest({ id, phase, title, options, locale = "en" }) {
|
||||
requireString(title, "title", "join-review");
|
||||
const opts = requireArray(options, "options", "join-review");
|
||||
if (opts.length === 0) {
|
||||
@@ -194,7 +200,8 @@ function buildJoinReviewRequest({ id, phase, title, options }) {
|
||||
widget: "join-review",
|
||||
title,
|
||||
options: [...opts],
|
||||
confirm_label: "Continue",
|
||||
confirm_label: gateText(locale, "continue"),
|
||||
confirm_label_i18n: gateText("en", "continue"),
|
||||
reserved: RESERVED,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user