推进 INI 面板 workflow overview embedding mount render state

This commit is contained in:
2026-06-15 20:57:50 +08:00
parent fc9e6a3514
commit 1a863fa0b4
12 changed files with 233 additions and 5 deletions

View File

@@ -50,6 +50,7 @@ import {
renderIniPanelShellWorkflowOverviewEmbeddingState,
mountIniPanelShellWorkflowOverviewEmbeddingState,
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
renderIniPanelShellSessionHandoffWorkflowState,
mountIniPanelShellSessionHandoffWorkflow,
renderIniPanelShellSessionHandoffMountState,
@@ -358,6 +359,12 @@ when an outer shell needs that mount workflow result compressed into stable
`title`, `statusText`, `detailText`, and read-only label/value rows. The
workflow overview page also exposes
`linuxCncIniPanelWorkflowOverviewApi.getWorkflowOverviewEmbeddingMountDisplayViewModel()`.
Use `createIniPanelShellWorkflowOverviewEmbeddingMountRenderState()` or
`linuxCncIniPanelLaunchApi.getWorkflowOverviewEmbeddingMountRenderState()` when
an outer shell needs that mount display view-model compressed into stable
`statusLine`, `dataset`, and rows for a shared DOM renderer. The workflow
overview page also exposes
`linuxCncIniPanelWorkflowOverviewApi.getWorkflowOverviewEmbeddingMountRenderState()`.
Use
`renderIniPanelShellSessionHandoffMountState()` or
`linuxCncIniPanelLaunchApi.renderShellSessionHandoffMountState()` when an outer

View File

@@ -305,6 +305,9 @@
getWorkflowOverviewEmbeddingMountDisplayViewModel: (mountResult) => (
shellViewModel.createWorkflowOverviewEmbeddingMountDisplayViewModel(mountResult)
),
getWorkflowOverviewEmbeddingMountRenderState: (displayViewModel) => (
shellViewModel.createWorkflowOverviewEmbeddingMountRenderState(displayViewModel)
),
isSupportedShellSessionHandoffPackage: shellViewModel.isSupportedShellSessionHandoffPackage,
getLauncherLinks: () => shellViewModel.launcherLinks,
getControlPageApiMethods: () => shellViewModel.controlPage.browserApiMethods,

View File

@@ -167,6 +167,7 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr
"renderWorkflowOverviewEmbeddingState",
"mountWorkflowOverviewEmbeddingState",
"getWorkflowOverviewEmbeddingMountDisplayViewModel",
"getWorkflowOverviewEmbeddingMountRenderState",
"isSupportedShellSessionHandoffPackage",
"getLauncherLinks",
"getControlPageApiMethods",
@@ -2193,6 +2194,38 @@ export function createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewMode
};
}
export function createIniPanelShellWorkflowOverviewEmbeddingMountRenderState(
displayViewModel = createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel(),
) {
const rows = Array.isArray(displayViewModel?.rows)
? displayViewModel.rows.map(({ id, label, value }) => ({
id,
label,
value: value == null ? "" : String(value),
}))
: [];
const ready = displayViewModel?.phase === "ready" && displayViewModel?.statusText === "Ready";
const statusText = displayViewModel?.statusText ?? (ready ? "Ready" : "Blocked");
const detailText = displayViewModel?.detailText ?? "No blocking reasons";
return {
apiName: "ini-panel-shell-workflow-overview-embedding-mount-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: displayViewModel?.title ?? "Workflow overview embedding mount",
statusText,
detailText,
statusLine: `${statusText}: ${detailText}`,
rows,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-embedding-mount",
},
};
}
export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries()) {
const shellIntegrationManifest = createIniPanelShellIntegrationManifest(entries);
const shellIntegrationReadiness = createIniPanelShellIntegrationReadiness(shellIntegrationManifest);
@@ -2360,6 +2393,8 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
mountWorkflowOverviewEmbeddingState: mountIniPanelShellWorkflowOverviewEmbeddingState,
createWorkflowOverviewEmbeddingMountDisplayViewModel:
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createWorkflowOverviewEmbeddingMountRenderState:
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
isSupportedShellSessionHandoffPackage: isSupportedIniPanelShellSessionHandoffPackage,
controlPage: {
browserApiSchema: createControlPageBrowserApiSchema(),

View File

@@ -98,6 +98,7 @@
renderIniPanelShellWorkflowOverviewEmbeddingState,
mountIniPanelShellWorkflowOverviewEmbeddingState,
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
renderIniPanelShellSessionHandoffWorkflowState,
mountIniPanelShellSessionHandoffWorkflow,
} from "./ui-shell.js";
@@ -165,6 +166,9 @@
getWorkflowOverviewEmbeddingMountDisplayViewModel: (mountResult) => (
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel(mountResult)
),
getWorkflowOverviewEmbeddingMountRenderState: (displayViewModel) => (
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState(displayViewModel)
),
};
</script>
</body>

View File

@@ -111,6 +111,7 @@
!launchApi?.renderWorkflowOverviewEmbeddingState ||
!launchApi?.mountWorkflowOverviewEmbeddingState ||
!launchApi?.getWorkflowOverviewEmbeddingMountDisplayViewModel ||
!launchApi?.getWorkflowOverviewEmbeddingMountRenderState ||
!launchApi?.isSupportedShellSessionHandoffPackage ||
!launchApi?.getLauncherLinks ||
!launchApi?.getControlPageApiMethods
@@ -643,7 +644,8 @@
!workflowOverviewApi?.getWorkflowOverviewEmbeddingDomReadiness ||
!workflowOverviewApi?.renderWorkflowOverviewEmbeddingState ||
!workflowOverviewApi?.mountWorkflowOverviewEmbeddingState ||
!workflowOverviewApi?.getWorkflowOverviewEmbeddingMountDisplayViewModel
!workflowOverviewApi?.getWorkflowOverviewEmbeddingMountDisplayViewModel ||
!workflowOverviewApi?.getWorkflowOverviewEmbeddingMountRenderState
) {
throw new Error("workflow overview API namespace did not expose shell helpers");
}

View File

@@ -117,6 +117,7 @@ TOOL_TABLE = browser-shell-tool.tbl
!launchApi?.renderWorkflowOverviewEmbeddingState ||
!launchApi?.mountWorkflowOverviewEmbeddingState ||
!launchApi?.getWorkflowOverviewEmbeddingMountDisplayViewModel ||
!launchApi?.getWorkflowOverviewEmbeddingMountRenderState ||
!launchApi?.isSupportedShellSessionHandoffPackage
) {
throw new Error("launch API namespace did not expose shell integration helpers");
@@ -336,6 +337,9 @@ TOOL_TABLE = browser-shell-tool.tbl
const workflowOverviewEmbeddingMountDisplay = launchApi.getWorkflowOverviewEmbeddingMountDisplayViewModel(
workflowOverviewEmbeddingMountState,
);
const workflowOverviewEmbeddingMountRenderState = launchApi.getWorkflowOverviewEmbeddingMountRenderState(
workflowOverviewEmbeddingMountDisplay,
);
assertEqual(workflowOverviewReadiness.ready, true, "shell workflow overview iframe readiness");
assertEqual(workflowOverviewReadiness.missing.join(","), "", "shell workflow overview iframe missing methods");
assertEqual(workflowOverviewEmbedding.apiName, "ini-panel-shell-workflow-overview-embedding", "shell workflow overview embedding API");
@@ -368,6 +372,8 @@ TOOL_TABLE = browser-shell-tool.tbl
assertEqual(workflowOverviewEmbeddingMountDisplay.title, "Workflow overview embedding mount", "shell workflow overview embedding mount display title");
assertEqual(workflowOverviewEmbeddingMountDisplay.rows.length, 7, "shell workflow overview embedding mount display rows");
assertEqual(workflowOverviewEmbeddingMountDisplay.detailText, "mount:blocked", "shell workflow overview embedding mount display detail");
assertEqual(workflowOverviewEmbeddingMountRenderState.statusLine, "Blocked: mount:blocked", "shell workflow overview embedding mount render status");
assertEqual(workflowOverviewEmbeddingMountRenderState.dataset.handoffScope, "workflow-overview-embedding-mount", "shell workflow overview embedding mount render scope");
const controlDoc = await loadFrame(`../../runtime/ui/ini-panel/${controlTarget.href.slice(2)}`);
const controlPageApi = controlDoc.defaultView.linuxCncIniPanelControlPageApi;

View File

@@ -43,7 +43,8 @@
!workflowApi?.getWorkflowOverviewEmbeddingDomReadiness ||
!workflowApi?.renderWorkflowOverviewEmbeddingState ||
!workflowApi?.mountWorkflowOverviewEmbeddingState ||
!workflowApi?.getWorkflowOverviewEmbeddingMountDisplayViewModel
!workflowApi?.getWorkflowOverviewEmbeddingMountDisplayViewModel ||
!workflowApi?.getWorkflowOverviewEmbeddingMountRenderState
) {
throw new Error("workflow overview API namespace did not expose overview helpers");
}
@@ -110,6 +111,9 @@
const embeddingMountDisplay = workflowApi.getWorkflowOverviewEmbeddingMountDisplayViewModel(
embeddingMountState,
);
const embeddingMountRenderState = workflowApi.getWorkflowOverviewEmbeddingMountRenderState(
embeddingMountDisplay,
);
assertEqual(embeddingRenderResult.rendered, true, "workflow overview embedding render result");
assertEqual(embeddingRenderResult.rowCount, 6, "workflow overview embedding render row count");
assertEqual(embeddingRenderResult.dataset.handoffScope, "workflow-overview-embedding", "workflow overview embedding render scope");
@@ -119,6 +123,8 @@
assertEqual(embeddingMountState.renderResult.rowCount, 6, "workflow overview embedding mount row count");
assertEqual(embeddingMountDisplay.statusText, "Blocked", "workflow overview embedding mount display status");
assertEqual(embeddingMountDisplay.rows.length, 7, "workflow overview embedding mount display rows");
assertEqual(embeddingMountRenderState.statusLine, "Blocked: mount:blocked", "workflow overview embedding mount render status");
assertEqual(embeddingMountRenderState.rows.length, 7, "workflow overview embedding mount render rows");
assertEqual(
workflowDoc.querySelector("[data-handoff-workflow]").dataset.handoffScope,
"workflow",

View File

@@ -48,6 +48,7 @@ import {
renderIniPanelShellWorkflowOverviewEmbeddingState,
mountIniPanelShellWorkflowOverviewEmbeddingState,
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
renderIniPanelShellSessionHandoffWorkflowState,
mountIniPanelShellSessionHandoffWorkflow,
renderIniPanelShellSessionHandoffMountState,
@@ -137,6 +138,7 @@ const requiredShellExports = [
"renderIniPanelShellWorkflowOverviewEmbeddingState",
"mountIniPanelShellWorkflowOverviewEmbeddingState",
"createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel",
"createIniPanelShellWorkflowOverviewEmbeddingMountRenderState",
"renderIniPanelShellSessionHandoffWorkflowState",
"mountIniPanelShellSessionHandoffWorkflow",
"renderIniPanelShellSessionHandoffMountState",
@@ -444,6 +446,7 @@ assert.match(shellText, /\bexport function createIniPanelShellWorkflowOverviewEm
assert.match(shellText, /\bexport function renderIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(shellText, /\bexport function mountIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(shellText, /\bexport function createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(shellText, /\bexport function createIniPanelShellWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelControlPageApiManifest\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelLaunchApiManifest\b/);
assert.match(shellText, /\bexport function isSupportedIniPanelShellIntegrationManifest\b/);
@@ -480,6 +483,7 @@ assert.match(launchText, /\bgetWorkflowOverviewEmbeddingDomReadiness\b/);
assert.match(launchText, /\brenderWorkflowOverviewEmbeddingState\b/);
assert.match(launchText, /\bmountWorkflowOverviewEmbeddingState\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/);
assert.match(launchText, /\bdata-handoff-shell\b/);
assert.match(launchText, /\bdata-handoff-status\b/);
@@ -521,6 +525,7 @@ assert.match(docText, /\bcreateIniPanelShellWorkflowOverviewEmbeddingDomReadines
assert.match(docText, /\brenderIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(docText, /\bmountIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(docText, /\bcreateIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(docText, /\bcreateIniPanelShellWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(docText, /\bisSupportedIniPanelControlPageApiManifest\b/);
assert.match(docText, /\bisSupportedIniPanelLaunchApiManifest\b/);
assert.match(docText, /\bisSupportedIniPanelShellIntegrationManifest\b/);
@@ -552,6 +557,7 @@ assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getWorkflowOverviewEmbedding
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.renderWorkflowOverviewEmbeddingState\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.mountWorkflowOverviewEmbeddingState\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.getWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(docText, /\blinuxCncIniPanelLaunchApi\.isSupportedShellSessionHandoffPackage\b/);
assert.match(docText, /\bdata-handoff-shell\b/);
assert.match(docText, /\bdata-handoff-status\b/);

View File

@@ -87,6 +87,7 @@ assert.deepEqual(manifest, {
"renderWorkflowOverviewEmbeddingState",
"mountWorkflowOverviewEmbeddingState",
"getWorkflowOverviewEmbeddingMountDisplayViewModel",
"getWorkflowOverviewEmbeddingMountRenderState",
"isSupportedShellSessionHandoffPackage",
"getLauncherLinks",
"getControlPageApiMethods",
@@ -238,6 +239,7 @@ assert.match(launchText, /\bgetWorkflowOverviewEmbeddingDomReadiness\b/);
assert.match(launchText, /\brenderWorkflowOverviewEmbeddingState\b/);
assert.match(launchText, /\bmountWorkflowOverviewEmbeddingState\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(launchText, /\bgetWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(launchText, /\bisSupportedShellSessionHandoffPackage\b/);
assert.match(launchText, /\bdata-handoff-workflow\b/);
assert.match(launchText, /\bdata-handoff-workflow-status\b/);

View File

@@ -44,6 +44,7 @@ import {
renderIniPanelShellWorkflowOverviewEmbeddingState,
mountIniPanelShellWorkflowOverviewEmbeddingState,
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
renderIniPanelShellSessionHandoffWorkflowState,
mountIniPanelShellSessionHandoffWorkflow,
createIniPanelShellSessionHandoffPackageReport,
@@ -172,7 +173,7 @@ assert.deepEqual(readiness, {
counts: {
pages: 3,
launcherLinks: 3,
launchMethods: 50,
launchMethods: 51,
controlPageMethods: 11,
persistenceCapabilities: 3,
},
@@ -234,7 +235,7 @@ assert.deepEqual(handoffSummary, {
counts: {
pages: 3,
launcherLinks: 3,
launchMethods: 50,
launchMethods: 51,
controlPageMethods: 11,
persistenceCapabilities: 3,
},
@@ -798,6 +799,7 @@ assert.equal(createIniPanelShellWorkflowOverviewEmbeddingDomReadiness().ready, f
assert.equal(typeof renderIniPanelShellWorkflowOverviewEmbeddingState, "function");
assert.equal(typeof mountIniPanelShellWorkflowOverviewEmbeddingState, "function");
assert.equal(typeof createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel, "function");
assert.equal(typeof createIniPanelShellWorkflowOverviewEmbeddingMountRenderState, "function");
assert.deepEqual(
createIniPanelShellWorkflowOverviewReadiness({
overviewApi: {
@@ -1226,7 +1228,7 @@ assert.deepEqual(createIniPanelShellIntegrationReadiness(blockedManifest), {
counts: {
pages: 3,
launcherLinks: 3,
launchMethods: 50,
launchMethods: 51,
controlPageMethods: 11,
persistenceCapabilities: 3,
},
@@ -1416,6 +1418,7 @@ assert.match(shellText, /\bexport function createIniPanelShellWorkflowOverviewEm
assert.match(shellText, /\bexport function renderIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(shellText, /\bexport function mountIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(shellText, /\bexport function createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(shellText, /\bexport function createIniPanelShellWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageRenderState\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffPackageSchema\b/);
assert.match(shellText, /\bexport function createIniPanelShellSessionHandoffRenderState\b/);
@@ -1461,6 +1464,7 @@ assert.match(docText, /\bcreateIniPanelShellWorkflowOverviewEmbeddingDomReadines
assert.match(docText, /\brenderIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(docText, /\bmountIniPanelShellWorkflowOverviewEmbeddingState\b/);
assert.match(docText, /\bcreateIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel\b/);
assert.match(docText, /\bcreateIniPanelShellWorkflowOverviewEmbeddingMountRenderState\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageRenderState\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffPackageSchema\b/);
assert.match(docText, /\bcreateIniPanelShellSessionHandoffRenderState\b/);

View File

@@ -44,6 +44,7 @@ import {
renderIniPanelShellWorkflowOverviewEmbeddingState,
mountIniPanelShellWorkflowOverviewEmbeddingState,
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
renderIniPanelShellSessionHandoffWorkflowState,
mountIniPanelShellSessionHandoffWorkflow,
renderIniPanelShellSessionHandoffMountState,
@@ -138,6 +139,7 @@ assert.equal(typeof mountIniPanelShellWorkflowOverviewEmbedding, "function");
assert.equal(typeof renderIniPanelShellWorkflowOverviewEmbeddingState, "function");
assert.equal(typeof mountIniPanelShellWorkflowOverviewEmbeddingState, "function");
assert.equal(typeof createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel, "function");
assert.equal(typeof createIniPanelShellWorkflowOverviewEmbeddingMountRenderState, "function");
assert.equal(typeof renderIniPanelShellSessionHandoffWorkflowState, "function");
assert.equal(typeof mountIniPanelShellSessionHandoffWorkflow, "function");
assert.equal(typeof renderIniPanelShellSessionHandoffMountState, "function");
@@ -835,6 +837,10 @@ assert.equal(
shellViewModel.createWorkflowOverviewEmbeddingMountDisplayViewModel,
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel,
);
assert.equal(
shellViewModel.createWorkflowOverviewEmbeddingMountRenderState,
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState,
);
assert.equal(shellViewModel.createShellSessionHandoffPackageReport, createIniPanelShellSessionHandoffPackageReport);
assert.equal(shellViewModel.createShellSessionHandoffPackageSchema, createIniPanelShellSessionHandoffPackageSchema);
assert.equal(shellViewModel.isSupportedShellSessionHandoffPackage, isSupportedIniPanelShellSessionHandoffPackage);
@@ -1484,6 +1490,63 @@ assert.deepEqual(
value: "document, mount, status, rows",
},
);
assert.deepEqual(
createIniPanelShellWorkflowOverviewEmbeddingMountRenderState(
createIniPanelShellWorkflowOverviewEmbeddingMountDisplayViewModel(workflowOverviewEmbeddingMountResult),
),
{
apiName: "ini-panel-shell-workflow-overview-embedding-mount-render-state",
renderStateVersion: 1,
phase: "blocked",
ready: false,
title: "Workflow overview embedding mount",
statusText: "Blocked",
detailText: "mount:blocked",
statusLine: "Blocked: mount:blocked",
rows: [
{
id: "mount-ready",
label: "Mount readiness",
value: "blocked",
},
{
id: "dom-readiness",
label: "DOM readiness",
value: "ready",
},
{
id: "missing-dom",
label: "Missing DOM",
value: "none",
},
{
id: "render-state",
label: "Render state",
value: "Blocked: embedding:blocked, mount:blocked",
},
{
id: "render-result",
label: "Render result",
value: "rendered",
},
{
id: "render-row-count",
label: "Render row count",
value: "6",
},
{
id: "error",
label: "Error",
value: "none",
},
],
dataset: {
handoffPhase: "blocked",
handoffReady: "false",
handoffScope: "workflow-overview-embedding-mount",
},
},
);
assert.deepEqual(
mountIniPanelShellWorkflowOverviewEmbedding({ overviewApi: null }).readiness.missing,
shellViewModel.shellWorkflowOverviewContract.methodNames,