按text32继续推进evidence expansion过滤预设

结论:已完成 evidence expansion family/source filter 的 summary/action-plan、query/hash 预选、UI/API/SDK/浏览器验证覆盖,并保持 sim-config inventory baseline=82/82/77/0。
This commit is contained in:
2026-06-20 12:18:08 +08:00
parent 8a1c4699b1
commit a6eda3fbff
18 changed files with 2144 additions and 51 deletions

View File

@@ -219,6 +219,17 @@ export function createIniPanelLaunchApiManifest(entries = getVisibleIniPanelEntr
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewPromotionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan",
"handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange",
"bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls",
"renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"getWorkflowOverviewPromotionFamilySourceFilterViewModel",
"getWorkflowOverviewPromotionFamilySourceFilterDomContract",
"getWorkflowOverviewPromotionFamilySourceFilterDomReadiness",
@@ -1942,6 +1953,17 @@ export function createIniPanelShellWorkflowOverviewContract() {
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
"getWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
"getWorkflowOverviewPromotionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan",
"getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan",
"handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange",
"bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls",
"renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
"getWorkflowOverviewPromotionFamilySourceFilterViewModel",
"getWorkflowOverviewPromotionFamilySourceFilterDomContract",
"getWorkflowOverviewPromotionFamilySourceFilterDomReadiness",
@@ -2600,6 +2622,12 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows
?? []
);
const evidenceExpansionFamilyRows = (
promotionCandidateArtifactSummary.evidenceExpansion?.familyRows
?? workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.familyRows
?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.familyRows
?? []
);
const preferredEvidenceExpansion = Array.isArray(evidenceExpansionRows)
? (evidenceExpansionRows[0] ?? {})
: {};
@@ -2817,6 +2845,40 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
? evidenceExpansionFullRows.map((row) => row.gcodePath).join(", ")
: "not provided",
},
{
id: "evidence-expansion-family-count",
label: "Evidence expansion family count",
value: Array.isArray(evidenceExpansionFamilyRows) && evidenceExpansionFamilyRows.length > 0
? `${evidenceExpansionFamilyRows.length} families`
: "not provided",
},
{
id: "evidence-expansion-family-summary",
label: "Evidence expansion family summary",
value: evidenceExpansion.familySummary ?? (Array.isArray(evidenceExpansionFamilyRows) && evidenceExpansionFamilyRows.length > 0
? evidenceExpansionFamilyRows.map((row) => {
const ready = row.ready === true || (row.complete === true && row.browserDiagnosticsExpansionReady === true);
return `${row.id}: ${row.completeCount ?? 0}/${row.candidateCount ?? 0} ${ready ? "ready" : "blocked"}`;
}).join("; ")
: "not provided"),
},
{
id: "evidence-expansion-family-source-count-list",
label: "Evidence expansion family source counts",
value: Array.isArray(evidenceExpansionFamilyRows) && evidenceExpansionFamilyRows.length > 0
? evidenceExpansionFamilyRows.map((row) =>
`${row.id}:${row.sourceFileCount ?? (Array.isArray(row.sourceFiles) ? row.sourceFiles.length : 0)}`
).join(", ")
: "not provided",
},
...(Array.isArray(evidenceExpansionFamilyRows) ? evidenceExpansionFamilyRows.map((row) => ({
id: `evidence-expansion-family-${row.id}`,
label: `Evidence expansion family ${row.label ?? row.id}`,
value: row.value ?? `${row.completeCount ?? 0}/${row.candidateCount ?? 0} ready; sources=${row.sourceFileCount ?? (Array.isArray(row.sourceFiles) ? row.sourceFiles.length : 0)}`,
candidateIds: Array.isArray(row.candidateIds) ? row.candidateIds : [],
sourceFiles: Array.isArray(row.sourceFiles) ? row.sourceFiles : [],
gcodePaths: Array.isArray(row.gcodePaths) ? row.gcodePaths : [],
})) : []),
{
id: "hard-block-runtime-lock",
label: "Hard-block runtime lock",
@@ -3360,6 +3422,77 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderStat
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(
summaryViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(),
) {
const summaryRows = Array.isArray(summaryViewModel?.rows) ? summaryViewModel.rows : [];
const rows = summaryRows
.filter(({ id }) => String(id).startsWith("evidence-expansion-family-"))
.filter(({ sourceFiles, gcodePaths }) => Array.isArray(sourceFiles) && Array.isArray(gcodePaths))
.map(({ id, label, value, sourceFiles, gcodePaths, candidateIds }) => {
const familySourceFiles = Array.isArray(sourceFiles) ? sourceFiles : [];
const familyGcodePaths = Array.isArray(gcodePaths) ? gcodePaths : [];
const familyCandidateIds = Array.isArray(candidateIds) ? candidateIds : [];
const sourceKindCounts = countPromotionFamilySourceKinds(familySourceFiles);
const sourceKindSummary = formatPromotionFamilySourceKindCounts(sourceKindCounts);
return {
id,
label,
value: value == null ? "" : String(value),
sourceFiles: familySourceFiles,
gcodePaths: familyGcodePaths,
candidateIds: familyCandidateIds,
sourceKindCounts,
sourceKindSummary,
};
});
const sourceRows = rows.flatMap((row) =>
row.sourceFiles.map((sourceFile, index) => ({
id: `${row.id}-source-${index + 1}`,
familyId: row.id,
label: `Source ${index + 1}`,
value: sourceFile,
sourceKind: classifyPromotionFamilySource(sourceFile),
manifestBacked: true,
status: "evidence-expansion-source",
}))
);
const candidateRows = rows.flatMap((row) =>
row.gcodePaths.map((gcodePath, index) => ({
id: `${row.id}-candidate-${index + 1}`,
familyId: row.id,
label: row.candidateIds[index] ?? `Candidate ${index + 1}`,
value: gcodePath,
candidateStatus: "evidence-expansion-ready",
promotionAllowed: false,
baselineChanging: false,
sourceKind: "gcode",
manifestBacked: true,
}))
);
const ready = rows.length > 0 && rows.every(({ value }) => String(value).includes("diagnostics=ready"));
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-rows-render-state",
renderStateVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
title: "Evidence expansion family diagnostics",
statusText: ready ? "Ready" : "Blocked",
detailText: ready ? `${rows.length} evidence expansion families ready` : "evidence expansion family rows missing",
statusLine: `${ready ? "Ready" : "Blocked"}: ${ready ? `${rows.length} evidence expansion families ready` : "evidence expansion family rows missing"}`,
rows,
sourceRows,
candidateRows,
sourceFileCount: sourceRows.length,
candidateCount: candidateRows.length,
dataset: {
handoffPhase: ready ? "ready" : "blocked",
handoffReady: ready ? "true" : "false",
handoffScope: "workflow-overview-evidence-expansion-family-rows",
},
};
}
export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(
renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(),
{ sourceKind = "all", familyId = "all" } = {},
@@ -3454,6 +3587,88 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterVi
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
{ sourceKind = "all", familyId = "all" } = {},
) {
const viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(
renderState,
{ sourceKind, familyId },
);
return {
...viewModel,
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-view-model",
detailText: viewModel.ready
? `${viewModel.filteredSourceFileCount}/${viewModel.totalSourceFileCount} source files selected`
: "evidence expansion source rows missing",
statusLine: `${viewModel.ready ? "Ready" : "Blocked"}: ${viewModel.ready ? `${viewModel.filteredSourceFileCount}/${viewModel.totalSourceFileCount} source files selected` : "evidence expansion source rows missing"}`,
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(),
) {
const familyRows = Array.isArray(viewModel?.familyRows) ? viewModel.familyRows : [];
const sourceRows = Array.isArray(viewModel?.sourceRows) ? viewModel.sourceRows : [];
const candidateRows = Array.isArray(viewModel?.candidateRows) ? viewModel.candidateRows : [];
const selectedFamilyId = viewModel?.selectedFamilyId ?? "all";
const selectedSourceKind = viewModel?.selectedSourceKind ?? "all";
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-summary",
summaryVersion: 1,
phase: viewModel?.ready === true ? "ready" : "blocked",
ready: viewModel?.ready === true,
selectedFamilyId,
selectedSourceKind,
filteredSourceFileCount: viewModel?.filteredSourceFileCount ?? sourceRows.length,
scopedSourceFileCount: viewModel?.scopedSourceFileCount ?? sourceRows.length,
totalSourceFileCount: viewModel?.totalSourceFileCount ?? sourceRows.length,
filteredCandidateCount: viewModel?.filteredCandidateCount ?? candidateRows.length,
totalCandidateCount: viewModel?.totalCandidateCount ?? candidateRows.length,
familyCount: familyRows.length,
sourceKinds: [...new Set(sourceRows.map((row) => row.sourceKind).filter(Boolean))],
familyIds: familyRows.map((row) => row.id),
candidateIds: candidateRows.map((row) => row.label ?? row.id),
gcodePaths: candidateRows.map((row) => row.value).filter(Boolean),
sourceFiles: sourceRows.map((row) => row.value).filter(Boolean),
statusLine: viewModel?.ready === true
? `Ready: ${selectedFamilyId} / ${selectedSourceKind} selects ${viewModel?.filteredSourceFileCount ?? sourceRows.length}/${viewModel?.totalSourceFileCount ?? sourceRows.length} source files`
: "Blocked: evidence expansion source filter summary missing",
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(
summary = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(),
) {
const ready = summary?.ready === true;
const selectedFamilyId = summary?.selectedFamilyId ?? "all";
const selectedSourceKind = summary?.selectedSourceKind ?? "all";
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-action-plan",
actionPlanVersion: 1,
phase: ready ? "ready" : "blocked",
ready,
selectedFamilyId,
selectedSourceKind,
filteredSourceFileCount: summary?.filteredSourceFileCount ?? 0,
filteredCandidateCount: summary?.filteredCandidateCount ?? 0,
promotionAllowed: false,
baselineChanging: false,
nextCommand: ready ? null : "mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState",
nextSteps: ready
? []
: [
"Load a release readiness artifact URL workflow summary.",
"Create evidence expansion family rows render state.",
"Mount the evidence expansion family/source filter DOM.",
],
statusLine: ready
? `Ready: evidence expansion filter ${selectedFamilyId} / ${selectedSourceKind} is externally readable`
: "Blocked: evidence expansion filter summary is not ready",
summary,
};
}
export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({
rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter",
selectors = {},
@@ -3496,6 +3711,21 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDo
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
selectors = {},
} = {}) {
return createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({
rowDatasetPrefix,
selectors: {
mount: selectors.mount ?? "[data-workflow-overview-evidence-expansion-family-source-filter]",
status: selectors.status ?? "[data-workflow-overview-evidence-expansion-family-source-filter-status]",
controls: selectors.controls ?? "[data-workflow-overview-evidence-expansion-family-source-filter-controls]",
rows: selectors.rows ?? "[data-workflow-overview-evidence-expansion-family-source-filter-rows]",
},
});
}
export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomReadiness({
rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract({ rowDatasetPrefix }),
@@ -3528,6 +3758,30 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDo
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const readiness = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomReadiness({
rowDatasetPrefix,
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
return {
...readiness,
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-readiness",
};
}
function readPromotionFamilySourceFilterControlValue(
controlsNode,
rowDatasetPrefix,
@@ -3572,6 +3826,39 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSe
};
}
export function createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
{
familyId = "all",
sourceKind = "all",
previousViewModel = null,
} = {},
) {
const nextViewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
renderState,
{ familyId, sourceKind },
);
const changed = previousViewModel === null ||
previousViewModel.selectedFamilyId !== nextViewModel.selectedFamilyId ||
previousViewModel.selectedSourceKind !== nextViewModel.selectedSourceKind;
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-action-plan",
actionPlanVersion: 1,
phase: nextViewModel.ready ? "ready" : "blocked",
ready: nextViewModel.ready,
changed,
selectedFamilyId: nextViewModel.selectedFamilyId,
selectedSourceKind: nextViewModel.selectedSourceKind,
filteredSourceFileCount: nextViewModel.filteredSourceFileCount,
scopedSourceFileCount: nextViewModel.scopedSourceFileCount,
totalSourceFileCount: nextViewModel.totalSourceFileCount,
statusLine: changed
? `Ready: evidence expansion source filter changed to ${nextViewModel.selectedFamilyId} / ${nextViewModel.selectedSourceKind}`
: "Ready: evidence expansion source filter unchanged",
nextViewModel,
};
}
export function handleIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSelectionChange({
renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState),
@@ -3628,6 +3915,62 @@ export function handleIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSe
};
}
export function handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange({
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(renderState),
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
render = false,
} = {}) {
const selectedFamilyId = readPromotionFamilySourceFilterControlValue(
controlsNode,
contract.rowDatasetPrefix,
"family",
viewModel?.selectedFamilyId ?? "all",
);
const selectedSourceKind = readPromotionFamilySourceFilterControlValue(
controlsNode,
contract.rowDatasetPrefix,
"source-kind",
viewModel?.selectedSourceKind ?? "all",
);
const actionPlan = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(
renderState,
{
familyId: selectedFamilyId,
sourceKind: selectedSourceKind,
previousViewModel: viewModel,
},
);
const renderResult = render
? renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(actionPlan.nextViewModel, {
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
})
: null;
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-change",
workflowVersion: 1,
phase: actionPlan.phase,
ready: actionPlan.ready,
statusLine: actionPlan.statusLine,
selectedFamilyId: actionPlan.selectedFamilyId,
selectedSourceKind: actionPlan.selectedSourceKind,
actionPlan,
viewModel: actionPlan.nextViewModel,
renderResult,
};
}
export function bindIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSelectionControls({
renderState = createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState),
@@ -3720,6 +4063,98 @@ export function bindIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSele
return binding;
}
export function bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls({
renderState = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(),
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(renderState),
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
render = true,
onChange = null,
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
const selectNodes = Array.from(controlsNode?.children ?? [])
.filter((node) => typeof node?.dataset?.[`${contract.rowDatasetPrefix}Select`] === "string");
if (!domReadiness.ready || selectNodes.length === 0) {
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-controls-binding",
bindingVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.ready ? "selector controls missing" : domReadiness.missing.join(", ")}`,
boundControlCount: 0,
controlIds: [],
domReadiness,
lastChange: null,
triggerChange: () => null,
unbind: () => ({ unbound: 0 }),
};
}
const binding = {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-selection-controls-binding",
bindingVersion: 1,
phase: "ready",
ready: true,
statusLine: `Ready: ${selectNodes.length} selector controls bound`,
boundControlCount: selectNodes.length,
controlIds: selectNodes.map((node) => node.dataset[`${contract.rowDatasetPrefix}Select`]),
domReadiness,
lastChange: null,
triggerChange: null,
unbind: null,
};
const handleChange = () => {
const changeResult = handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange({
renderState,
viewModel,
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
render,
});
binding.lastChange = changeResult;
if (typeof onChange === "function") {
onChange(changeResult);
}
return changeResult;
};
const unbinders = selectNodes.map((node) => {
if (typeof node.addEventListener === "function") {
node.addEventListener("change", handleChange);
return () => node.removeEventListener?.("change", handleChange);
}
node.onchange = handleChange;
return () => {
if (node.onchange === handleChange) {
node.onchange = null;
}
};
});
binding.triggerChange = handleChange;
binding.unbind = () => {
for (const unbind of unbinders) {
unbind();
}
return { unbound: unbinders.length };
};
return binding;
}
export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState(
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(),
{
@@ -3892,6 +4327,32 @@ export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSt
};
}
export function renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(),
{
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {},
) {
const renderResult = renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState(viewModel, {
rowDatasetPrefix,
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
mountNode.dataset.handoffScope = "workflow-overview-evidence-expansion-family-source-filter";
renderResult.dataset.handoffScope = mountNode.dataset.handoffScope;
return renderResult;
}
export function mountIniPanelShellWorkflowOverviewPromotionFamilySourceFilterState({
viewModel = createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(),
rowDatasetPrefix = "workflowOverviewPromotionFamilySourceFilter",
@@ -3962,6 +4423,76 @@ export function mountIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSta
}
}
export function mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState({
viewModel = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(),
rowDatasetPrefix = "workflowOverviewEvidenceExpansionFamilySourceFilter",
contract = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract({ rowDatasetPrefix }),
documentRef = globalThis.document,
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
statusNode = documentRef?.querySelector?.(contract.selectors.status),
controlsNode = documentRef?.querySelector?.(contract.selectors.controls),
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
} = {}) {
const domReadiness = createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness({
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
if (!domReadiness.ready) {
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
contract,
domReadiness,
viewModel,
renderResult: null,
error: null,
};
}
try {
const renderResult = renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(viewModel, {
contract,
documentRef,
mountNode,
statusNode,
controlsNode,
rowsNode,
});
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-mount",
workflowVersion: 1,
phase: viewModel?.phase === "ready" ? "ready" : "blocked",
ready: viewModel?.ready === true,
statusLine: renderResult.statusLine,
contract,
domReadiness,
viewModel,
renderResult,
error: null,
};
} catch (error) {
return {
apiName: "ini-panel-shell-workflow-overview-evidence-expansion-family-source-filter-dom-mount",
workflowVersion: 1,
phase: "blocked",
ready: false,
statusLine: `Blocked: ${error?.message ?? "evidence expansion source filter DOM mount error"}`,
contract,
domReadiness,
viewModel,
renderResult: null,
error: error?.message ?? String(error),
};
}
}
export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsDomContract({
rowDatasetPrefix = "workflowOverviewPromotionFamily",
selectors = {},
@@ -6852,6 +7383,28 @@ export function createIniPanelShellViewModel(entries = getVisibleIniPanelEntries
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
createWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState:
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
createWorkflowOverviewEvidenceExpansionFamilyRowsRenderState:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan:
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange:
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls:
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState:
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState:
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createWorkflowOverviewPromotionFamilyRowsRenderState:
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState,
createWorkflowOverviewPromotionFamilySourceFilterViewModel:

View File

@@ -162,6 +162,11 @@
<div class="source-filter-controls" data-workflow-overview-promotion-family-source-filter-controls></div>
<dl data-workflow-overview-promotion-family-source-filter-rows></dl>
</section>
<section class="overview-status" aria-label="Evidence expansion family source filter" data-workflow-overview-evidence-expansion-family-source-filter>
<p data-workflow-overview-evidence-expansion-family-source-filter-status>Waiting for evidence expansion family source evidence.</p>
<div class="source-filter-controls" data-workflow-overview-evidence-expansion-family-source-filter-controls></div>
<dl data-workflow-overview-evidence-expansion-family-source-filter-rows></dl>
</section>
</section>
</main>
<script type="module">
@@ -205,6 +210,17 @@
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan,
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan,
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange,
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls,
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState,
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel,
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterDomContract,
@@ -256,6 +272,20 @@
const browserDiagnosticsUrlInput = document.querySelector("[data-browser-diagnostics-url-input]");
const releaseArtifactUrlWorkflowForm = document.querySelector("[data-release-artifact-url-workflow-form]");
function getWorkflowOverviewEvidenceExpansionFilterPreset(locationRef = window.location) {
const searchParams = new URLSearchParams(locationRef?.search ?? "");
const hashText = String(locationRef?.hash ?? "").replace(/^#/, "");
const hashParams = new URLSearchParams(hashText);
return {
familyId: searchParams.get("evidenceExpansionFamily") ??
hashParams.get("evidenceExpansionFamily") ??
"all",
sourceKind: searchParams.get("evidenceExpansionSourceKind") ??
hashParams.get("evidenceExpansionSourceKind") ??
"all",
};
}
async function runWorkflowOverviewReleaseReadinessArtifactUrlForm(options = {}) {
const artifactUrl = String(options.artifactUrl ?? releaseArtifactUrlInput?.value ?? "").trim();
const diagnosticsUrl = String(options.diagnosticsUrl ?? browserDiagnosticsUrlInput?.value ?? "").trim();
@@ -326,7 +356,45 @@
document.body.dataset.promotionFamilySourceFilterSourceKind =
changeResult.selectedSourceKind;
document.body.dataset.promotionFamilySourceFilterCount =
String(changeResult.actionPlan.filteredSourceFileCount);
},
});
const evidenceExpansionFamilyRowsRenderState =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(summary);
const evidenceExpansionFamilySourceFilter =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(
evidenceExpansionFamilyRowsRenderState,
options.evidenceExpansionFilterPreset ??
getWorkflowOverviewEvidenceExpansionFilterPreset(window.location),
);
const evidenceExpansionFamilySourceFilterSummary =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(
evidenceExpansionFamilySourceFilter,
);
const evidenceExpansionFamilySourceFilterActionPlan =
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(
evidenceExpansionFamilySourceFilterSummary,
);
const evidenceExpansionFamilySourceFilterMountResult =
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState({
viewModel: evidenceExpansionFamilySourceFilter,
documentRef: document,
});
const evidenceExpansionFamilySourceFilterBinding =
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls({
renderState: evidenceExpansionFamilyRowsRenderState,
viewModel: evidenceExpansionFamilySourceFilter,
documentRef: document,
render: true,
onChange: (changeResult) => {
document.body.dataset.evidenceExpansionFamilySourceFilterFamily =
changeResult.selectedFamilyId;
document.body.dataset.evidenceExpansionFamilySourceFilterSourceKind =
changeResult.selectedSourceKind;
document.body.dataset.evidenceExpansionFamilySourceFilterCount =
String(changeResult.actionPlan.filteredSourceFileCount);
document.body.dataset.evidenceExpansionFamilySourceFilterSummary =
changeResult.actionPlan.statusLine;
},
});
document.body.dataset.releaseArtifactUrlWorkflowPhase = workflow.phase;
@@ -337,6 +405,16 @@
promotionFamilySourceFilter.ready ? "true" : "false";
document.body.dataset.promotionFamilySourceFilterCount =
String(promotionFamilySourceFilter.filteredSourceFileCount);
document.body.dataset.evidenceExpansionFamilySourceFilterReady =
evidenceExpansionFamilySourceFilter.ready ? "true" : "false";
document.body.dataset.evidenceExpansionFamilySourceFilterFamily =
evidenceExpansionFamilySourceFilter.selectedFamilyId;
document.body.dataset.evidenceExpansionFamilySourceFilterSourceKind =
evidenceExpansionFamilySourceFilter.selectedSourceKind;
document.body.dataset.evidenceExpansionFamilySourceFilterCount =
String(evidenceExpansionFamilySourceFilter.filteredSourceFileCount);
document.body.dataset.evidenceExpansionFamilySourceFilterSummary =
evidenceExpansionFamilySourceFilterActionPlan.statusLine;
return {
workflow,
summary,
@@ -355,6 +433,12 @@
promotionFamilySourceFilter,
promotionFamilySourceFilterMountResult,
promotionFamilySourceFilterBinding,
evidenceExpansionFamilyRowsRenderState,
evidenceExpansionFamilySourceFilter,
evidenceExpansionFamilySourceFilterSummary,
evidenceExpansionFamilySourceFilterActionPlan,
evidenceExpansionFamilySourceFilterMountResult,
evidenceExpansionFamilySourceFilterBinding,
};
}
@@ -459,6 +543,50 @@
getWorkflowOverviewPromotionFamilyRowsRenderState: (summaryViewModel) => (
createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderState(summaryViewModel)
),
getWorkflowOverviewEvidenceExpansionFamilyRowsRenderState: (summaryViewModel) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilyRowsRenderState(summaryViewModel)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel: (renderState, options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterViewModel(renderState, options)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract: (options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomContract(options)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness: (options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterDomReadiness(
options ?? { documentRef: document },
)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary: (viewModel) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSummary(viewModel)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan: (summary) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterActionPlan(summary)
),
getWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan: (renderState, options) => (
createIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionActionPlan(renderState, options)
),
handleWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange: (options) => (
handleIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionChange(
options ?? { documentRef: document },
)
),
bindWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls: (options) => (
bindIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterSelectionControls(
options ?? { documentRef: document },
)
),
renderWorkflowOverviewEvidenceExpansionFamilySourceFilterState: (viewModel, options) => (
renderIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
viewModel,
options ?? { documentRef: document },
)
),
mountWorkflowOverviewEvidenceExpansionFamilySourceFilterState: (options) => (
mountIniPanelShellWorkflowOverviewEvidenceExpansionFamilySourceFilterState(
options ?? { documentRef: document },
)
),
getWorkflowOverviewPromotionFamilySourceFilterViewModel: (renderState, options) => (
createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterViewModel(renderState, options)
),