177 lines
5.9 KiB
JavaScript
177 lines
5.9 KiB
JavaScript
(function () {
|
||
"use strict";
|
||
|
||
const VUE_VERSION = "3.5.21";
|
||
const vue = window.Vue;
|
||
const unavailable = {
|
||
available: false,
|
||
version: VUE_VERSION,
|
||
renderDispatchedControls: () => false,
|
||
renderModeChips: () => false,
|
||
};
|
||
if (!vue?.createApp || !vue?.h || !vue?.reactive) {
|
||
window.CognitiveAgentVueUI = unavailable;
|
||
return;
|
||
}
|
||
|
||
const { Fragment, createApp, h, nextTick, reactive } = vue;
|
||
const modeMounts = new WeakMap();
|
||
const commandMounts = new WeakMap();
|
||
const text = (value, fallback = "") => String(value ?? fallback);
|
||
|
||
function refreshIcons() {
|
||
nextTick(() => window.lucide?.createIcons({ attrs: { "aria-hidden": "true" } }));
|
||
}
|
||
|
||
function replaceReactiveArray(target, values) {
|
||
target.splice(0, target.length, ...values.map((value) => ({ ...value })));
|
||
}
|
||
|
||
function renderModeEntry(entry) {
|
||
const key = text(entry.key || `${entry.type}-${entry.id || entry.label}`);
|
||
if (entry.type === "label") {
|
||
return h("span", {
|
||
key,
|
||
class: "mode-group-label",
|
||
"data-mode-group-label": text(entry.id),
|
||
}, text(entry.label));
|
||
}
|
||
if (entry.type === "divider") {
|
||
return h("span", {
|
||
key,
|
||
class: "mode-group-divider",
|
||
"data-mode-divider": text(entry.id),
|
||
"aria-hidden": "true",
|
||
});
|
||
}
|
||
const children = [
|
||
h("i", {
|
||
class: "mode-chip-icon",
|
||
"data-lucide": text(entry.icon, "bookmark"),
|
||
}),
|
||
h("span", { class: "mode-chip-label" }, text(entry.label, "模式")),
|
||
h("small", { class: "mode-chip-summary" }, text(entry.summary, "整车联动")),
|
||
];
|
||
if (entry.cycleLabel) {
|
||
children.push(h("small", { class: "mode-cycle-badge" }, text(entry.cycleLabel)));
|
||
}
|
||
children.push(h("i", {
|
||
class: "mode-chip-run",
|
||
"data-lucide": "play",
|
||
"data-mode-run": "true",
|
||
title: `执行${text(entry.label, "模式")}`,
|
||
}));
|
||
return h("button", {
|
||
key,
|
||
type: "button",
|
||
title: text(entry.title),
|
||
"data-mode-profile-id": text(entry.id),
|
||
"data-mode-command": text(entry.command),
|
||
"data-mode-origin": text(entry.origin, "preset"),
|
||
...(entry.behavior ? { "data-mode-behavior": text(entry.behavior) } : {}),
|
||
"aria-label": text(entry.ariaLabel, `${text(entry.label, "模式")},点击执行`),
|
||
"aria-pressed": "false",
|
||
}, children);
|
||
}
|
||
|
||
function createModeMount(container) {
|
||
const state = reactive({ entries: [] });
|
||
const app = createApp({
|
||
name: "N7ModeChipRail",
|
||
setup() {
|
||
return () => h(Fragment, null, state.entries.map(renderModeEntry));
|
||
},
|
||
});
|
||
app.mount(container);
|
||
const mount = { app, state };
|
||
modeMounts.set(container, mount);
|
||
return mount;
|
||
}
|
||
|
||
function renderModeChips(container, entries) {
|
||
if (!(container instanceof Element) || !Array.isArray(entries)) return false;
|
||
const mount = modeMounts.get(container) || createModeMount(container);
|
||
replaceReactiveArray(mount.state.entries, entries);
|
||
container.dataset.vueSurface = "mode-chips";
|
||
refreshIcons();
|
||
return true;
|
||
}
|
||
|
||
function renderCommandRow(command, index) {
|
||
const semantic = text(command.semantic);
|
||
const actual = text(command.command);
|
||
const accessibleText = [
|
||
semantic ? `语义控制指令:${semantic}` : "",
|
||
actual ? `实际控制指令:${actual}` : "",
|
||
command.deliveryLabel
|
||
? `下发状态:${text(command.deliveryLabel)}${command.deliveryDetail ? `(${text(command.deliveryDetail)})` : ""}`
|
||
: "",
|
||
].filter(Boolean).join(";");
|
||
return h("li", {
|
||
key: text(command.key, `command-${index}`),
|
||
title: accessibleText,
|
||
"data-delivery-state": text(command.deliveryState, "not_submitted"),
|
||
}, [
|
||
h("span", { class: "assistant-dispatched-control-icon" }, [
|
||
h("i", { "data-lucide": text(command.icon, "binary") }),
|
||
]),
|
||
h("span", { class: "assistant-dispatched-control-label" }, text(command.category, "控制指令")),
|
||
h("strong", { class: "assistant-dispatched-control-value" }, text(command.value, "控制")),
|
||
h("small", { class: "visually-hidden" }, accessibleText),
|
||
]);
|
||
}
|
||
|
||
function createCommandMount(container) {
|
||
const state = reactive({ commands: [], open: true });
|
||
const app = createApp({
|
||
name: "N7DispatchedControlsCard",
|
||
setup() {
|
||
return () => h("details", {
|
||
class: "assistant-dispatched-controls",
|
||
open: state.open,
|
||
onToggle(event) {
|
||
state.open = event.currentTarget.open;
|
||
},
|
||
}, [
|
||
h("summary", null, [
|
||
h("span", { class: "assistant-dispatched-controls-heading-icon" }, [
|
||
h("i", { "data-lucide": "list-tree" }),
|
||
]),
|
||
h("b", null, "下发控制指令"),
|
||
h("strong", { class: "assistant-dispatched-controls-count" }, String(state.commands.length)),
|
||
h("i", {
|
||
class: "assistant-dispatched-controls-chevron",
|
||
"data-lucide": "chevron-down",
|
||
}),
|
||
]),
|
||
h("ol", { class: "assistant-dispatched-controls-list" }, state.commands.map(renderCommandRow)),
|
||
]);
|
||
},
|
||
});
|
||
app.mount(container);
|
||
const mount = { app, state };
|
||
commandMounts.set(container, mount);
|
||
return mount;
|
||
}
|
||
|
||
function renderDispatchedControls(container, commands) {
|
||
if (!(container instanceof Element) || !Array.isArray(commands) || !commands.length) {
|
||
return false;
|
||
}
|
||
const mount = commandMounts.get(container) || createCommandMount(container);
|
||
replaceReactiveArray(mount.state.commands, commands);
|
||
container.dataset.vueSurface = "dispatched-controls";
|
||
refreshIcons();
|
||
return true;
|
||
}
|
||
|
||
document.documentElement.classList.add("vue-presentation-enabled");
|
||
document.documentElement.dataset.vueVersion = VUE_VERSION;
|
||
window.CognitiveAgentVueUI = Object.freeze({
|
||
available: true,
|
||
version: VUE_VERSION,
|
||
renderDispatchedControls,
|
||
renderModeChips,
|
||
});
|
||
}());
|