解锁L4-TOOL-DB主机运行环境
结论:已识别RIP版LinuxCNC主机运行时,Tool DB native protocol probe可通过,inventory baseline保持28/28/131/0且promotion继续锁定。
This commit is contained in:
@@ -134,20 +134,65 @@ function createPromotionFamilySummaryRows(candidateReport = {}) {
|
||||
|
||||
function createPromotionCandidateArtifactSummary({
|
||||
candidateReport = {},
|
||||
evidenceExpansionReport = {},
|
||||
inventory = DEFAULT_SIM_CONFIG_INVENTORY_BASELINE,
|
||||
blockedFamilies = BLOCKED_RUNTIME_FAMILIES,
|
||||
promotedBlockedFamilies = [],
|
||||
promotionCandidateRows = [],
|
||||
evidenceExpansionRows = [],
|
||||
} = {}) {
|
||||
const rows = arrayOrEmpty(objectOrEmpty(candidateReport).rows);
|
||||
const candidateArtifactRows = arrayOrEmpty(promotionCandidateRows);
|
||||
const evidenceExpansionArtifactRows = arrayOrEmpty(evidenceExpansionRows);
|
||||
const evidenceReadyCount = rows.filter((row) =>
|
||||
row.currentNodeInventoryStatus === "PASS" &&
|
||||
row.blockedKind === "-" &&
|
||||
row.currentMatrixBrowserStatus === "explicit-browser-diagnostics" &&
|
||||
row.targetBrowserEvidence === "explicit-browser-diagnostics"
|
||||
).length;
|
||||
const inventoryReadyCount = 20;
|
||||
const evidenceExpansionCandidateCount = 13;
|
||||
const promotionAllowedCount = 0;
|
||||
const artifactEvidenceReadyRows = candidateArtifactRows
|
||||
.filter((row) => row.candidate_kind === "evidence-ready");
|
||||
const artifactInventoryReadyRows = candidateArtifactRows
|
||||
.filter((row) => row.candidate_kind === "inventory-ready");
|
||||
const artifactEvidenceReadyCount = artifactEvidenceReadyRows.length;
|
||||
const inventoryReadyCount = artifactInventoryReadyRows.length > 0
|
||||
? artifactInventoryReadyRows.length
|
||||
: 20;
|
||||
const evidenceExpansionCandidateCount = evidenceExpansionArtifactRows.length > 0
|
||||
? evidenceExpansionArtifactRows.length
|
||||
: 13;
|
||||
const promotionAllowedCount = candidateArtifactRows.length > 0
|
||||
? candidateArtifactRows.filter((row) => String(row.promotion_allowed ?? row.promotionAllowed) === "1").length
|
||||
: 0;
|
||||
const hardBlockRuntimeFamilyRows = artifactInventoryReadyRows
|
||||
.filter((row) => blockedFamilies.includes(row.skip_kind ?? row.blocked_kind ?? row.blockedKind))
|
||||
.map((row, index) => ({
|
||||
candidateId: row.candidate_id ?? row.path ?? "unknown",
|
||||
path: row.path ?? "unknown",
|
||||
skipKind: row.skip_kind ?? row.blocked_kind ?? row.blockedKind ?? "unknown",
|
||||
promotionAllowed: String(row.promotion_allowed ?? row.promotionAllowed ?? "0") === "1",
|
||||
blockReason: row.block_reason ?? row.blockReason ?? "-",
|
||||
recommendedNextCommand: row.recommended_next_command ?? row.recommendedNextCommand ?? "-",
|
||||
detailId: `hard-block-runtime-detail-${index + 1}`,
|
||||
}));
|
||||
const resolvedEvidenceReadyCount = artifactEvidenceReadyCount > 0 ? artifactEvidenceReadyCount : evidenceReadyCount;
|
||||
const hardBlockRuntimePromotionAllowedCount = hardBlockRuntimeFamilyRows
|
||||
.filter((row) => row.promotionAllowed)
|
||||
.length;
|
||||
const hardBlockRuntimeFamilySummaryRows = blockedFamilies.map((family) => {
|
||||
const familyRows = hardBlockRuntimeFamilyRows.filter((row) => row.skipKind === family);
|
||||
const promotionAllowedRows = familyRows.filter((row) => row.promotionAllowed);
|
||||
return {
|
||||
family,
|
||||
candidateCount: familyRows.length,
|
||||
promotionAllowedCount: promotionAllowedRows.length,
|
||||
locked: promotionAllowedRows.length === 0,
|
||||
lockedPaths: familyRows.map((row) => row.path),
|
||||
firstPath: familyRows[0]?.path ?? null,
|
||||
firstBlockReason: familyRows[0]?.blockReason ?? null,
|
||||
nextProof: familyRows[0]?.recommendedNextCommand ?? null,
|
||||
};
|
||||
});
|
||||
const hardBlockRuntimeLockSummary = createHardBlockRuntimeLockSummary(
|
||||
blockedFamilies,
|
||||
promotedBlockedFamilies,
|
||||
@@ -167,17 +212,36 @@ function createPromotionCandidateArtifactSummary({
|
||||
artifactPath: "wasm-port/build/wasm/sim-configs-inventory/promotion-candidates.tsv",
|
||||
evidenceExpansionArtifactPath: "wasm-port/build/wasm/sim-configs-inventory/evidence-expansion-candidates.tsv",
|
||||
layerCount: 2,
|
||||
evidenceReadyCount,
|
||||
evidenceReadyCount: resolvedEvidenceReadyCount,
|
||||
inventoryReadyCount,
|
||||
evidenceExpansionCandidateCount,
|
||||
totalCandidateCount: evidenceReadyCount + inventoryReadyCount,
|
||||
totalCandidateCount: resolvedEvidenceReadyCount + inventoryReadyCount,
|
||||
promotionAllowedCount,
|
||||
hardBlockRuntimeLock: hardBlockRuntimeLockSummary.lockValue,
|
||||
hardBlockRuntimePromotionAllowedCount,
|
||||
inventoryBaseline: baselineText,
|
||||
artifactRows: {
|
||||
promotionCandidates: candidateArtifactRows.length > 0
|
||||
? candidateArtifactRows.length
|
||||
: resolvedEvidenceReadyCount + inventoryReadyCount,
|
||||
evidenceExpansion: evidenceExpansionArtifactRows.length > 0
|
||||
? evidenceExpansionArtifactRows.length
|
||||
: evidenceExpansionCandidateCount,
|
||||
},
|
||||
hardBlockRuntimeFamilyRows,
|
||||
hardBlockRuntimeFamilyDetailRows: hardBlockRuntimeFamilyRows.map((row) => ({
|
||||
id: row.detailId,
|
||||
family: row.skipKind,
|
||||
path: row.path,
|
||||
blockReason: row.blockReason,
|
||||
nextProof: row.recommendedNextCommand,
|
||||
promotionAllowed: row.promotionAllowed,
|
||||
})),
|
||||
hardBlockRuntimeFamilySummaryRows,
|
||||
layers: [
|
||||
{
|
||||
id: "evidence-ready",
|
||||
candidateCount: evidenceReadyCount,
|
||||
candidateCount: resolvedEvidenceReadyCount,
|
||||
promotionAllowedCount: 0,
|
||||
virtualHalEvidenceReady: true,
|
||||
baselineChanging: false,
|
||||
@@ -193,6 +257,9 @@ function createPromotionCandidateArtifactSummary({
|
||||
evidenceExpansion: {
|
||||
id: "browser-diagnostics-expansion",
|
||||
candidateCount: evidenceExpansionCandidateCount,
|
||||
artifactRowCount: evidenceExpansionArtifactRows.length > 0
|
||||
? evidenceExpansionArtifactRows.length
|
||||
: evidenceExpansionCandidateCount,
|
||||
promotionAllowedCount: 0,
|
||||
baselineChanging: false,
|
||||
nextEvidence: "browser-diagnostics-binding",
|
||||
@@ -1951,6 +2018,9 @@ export function createProjectReleaseReadinessReport({
|
||||
simConfigInventory = DEFAULT_SIM_CONFIG_INVENTORY_BASELINE,
|
||||
virtualHalSimConfigSourceCoverage = null,
|
||||
virtualHalSimConfigPromotionCandidates = null,
|
||||
virtualHalSimConfigEvidenceExpansion = null,
|
||||
promotionCandidateRows = [],
|
||||
evidenceExpansionRows = [],
|
||||
virtualHalSimConfigMacroLoadFixtures = null,
|
||||
virtualHalMotionControllerMatrix = null,
|
||||
blockedRuntimeFamilies = BLOCKED_RUNTIME_FAMILIES,
|
||||
@@ -2003,9 +2073,12 @@ export function createProjectReleaseReadinessReport({
|
||||
const hardBlockRuntimeLockSummary = createHardBlockRuntimeLockSummary(blockedFamilies, promotedBlockedFamilies);
|
||||
const promotionCandidateArtifactSummary = createPromotionCandidateArtifactSummary({
|
||||
candidateReport: virtualHalSimConfigPromotionCandidates,
|
||||
evidenceExpansionReport: virtualHalSimConfigEvidenceExpansion,
|
||||
inventory,
|
||||
blockedFamilies,
|
||||
promotedBlockedFamilies,
|
||||
promotionCandidateRows,
|
||||
evidenceExpansionRows,
|
||||
});
|
||||
const axisScreenshotArtifactSummary = createAxisScreenshotArtifactSummary(axisScreenshotArtifacts);
|
||||
const axisScreenshotArtifactsReady = axisScreenshotArtifactSummary.ready;
|
||||
@@ -2044,6 +2117,7 @@ export function createProjectReleaseReadinessReport({
|
||||
virtualHalSimConfigSourceCoverageReady,
|
||||
virtualHalSimConfigPromotionCandidates,
|
||||
virtualHalSimConfigPromotionCandidatesReady,
|
||||
virtualHalSimConfigEvidenceExpansion,
|
||||
virtualHalPromotionFamilySummary,
|
||||
virtualHalPromotionFamilyRows,
|
||||
promotionCandidateArtifactSummary,
|
||||
@@ -2087,6 +2161,16 @@ export function createProjectReleaseReadinessReport({
|
||||
label: "Promotion candidate artifact",
|
||||
value: promotionCandidateArtifactSummary.artifactPath,
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-artifact-rows",
|
||||
label: "Promotion candidate artifact rows",
|
||||
value: `${promotionCandidateArtifactSummary.artifactRows.promotionCandidates}`,
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-artifact-rows",
|
||||
label: "Evidence expansion artifact rows",
|
||||
value: `${promotionCandidateArtifactSummary.artifactRows.evidenceExpansion}`,
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-layers",
|
||||
label: "Promotion candidate layers",
|
||||
@@ -2388,6 +2472,13 @@ export function createProjectReleaseReadinessArtifactValidationSummaryViewModel(
|
||||
? `${validation.promotionCandidateArtifactSummary.totalCandidateCount}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-artifact-rows",
|
||||
label: "Promotion candidate artifact rows",
|
||||
value: validation?.promotionCandidateArtifactSummaryReady === true
|
||||
? `${validation.promotionCandidateArtifactSummary.artifactRows.promotionCandidates}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-candidates",
|
||||
label: "Evidence expansion candidates",
|
||||
@@ -2395,6 +2486,13 @@ export function createProjectReleaseReadinessArtifactValidationSummaryViewModel(
|
||||
? `${validation.promotionCandidateArtifactSummary.evidenceExpansionCandidateCount}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-artifact-rows",
|
||||
label: "Evidence expansion artifact rows",
|
||||
value: validation?.promotionCandidateArtifactSummaryReady === true
|
||||
? `${validation.promotionCandidateArtifactSummary.artifactRows.evidenceExpansion}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-next-evidence",
|
||||
label: "Evidence expansion next evidence",
|
||||
@@ -2837,6 +2935,17 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
|
||||
) {
|
||||
const missing = arrayOrEmpty(workflow?.missing);
|
||||
const promotionCandidateSummary = objectOrEmpty(workflow?.diagnosticsArtifact?.virtualHalPromotionCandidateSummary);
|
||||
const promotionCandidateReportRows = arrayOrEmpty(
|
||||
workflow?.diagnosticsArtifact?.virtualHalSimConfigPromotionCandidates?.rows,
|
||||
);
|
||||
const evidenceReadyCandidateRows = promotionCandidateReportRows.filter((row) =>
|
||||
row?.complete === true &&
|
||||
row?.currentNodeInventoryStatus === "PASS" &&
|
||||
row?.blockedKind === "-" &&
|
||||
row?.targetBrowserEvidence === "explicit-browser-diagnostics" &&
|
||||
row?.currentMatrixBrowserStatus === "explicit-browser-diagnostics"
|
||||
);
|
||||
const preferredEvidenceReadyCandidate = evidenceReadyCandidateRows[0] ?? {};
|
||||
const promotionCandidateSummaryReady = promotionCandidateSummary.ready === true;
|
||||
const validationRows = arrayOrEmpty(workflow?.validation?.rows);
|
||||
const hardBlockRuntimeLock = validationRows.find(({ id }) => id === "hard-block-runtime-lock")?.value;
|
||||
@@ -2844,6 +2953,16 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
|
||||
const promotionCandidateArtifactSummary = objectOrEmpty(workflow?.validation?.promotionCandidateArtifactSummary);
|
||||
const promotionCandidateArtifactSummaryReady =
|
||||
workflow?.validation?.promotionCandidateArtifactSummaryReady === true;
|
||||
const promotionArtifactRows = objectOrEmpty(promotionCandidateArtifactSummary.artifactRows);
|
||||
const hardBlockRuntimeFamilyRows = arrayOrEmpty(promotionCandidateArtifactSummary.hardBlockRuntimeFamilyRows);
|
||||
const hardBlockRuntimeFamilySummaryRows = arrayOrEmpty(
|
||||
promotionCandidateArtifactSummary.hardBlockRuntimeFamilySummaryRows,
|
||||
);
|
||||
const hardBlockRuntimeFamilyDetailRows = arrayOrEmpty(
|
||||
promotionCandidateArtifactSummary.hardBlockRuntimeFamilyDetailRows,
|
||||
);
|
||||
const hardBlockRuntimeDetailPreviewRows = hardBlockRuntimeFamilyDetailRows.slice(0, 5);
|
||||
const hardBlockRuntimePreviewRows = hardBlockRuntimeFamilyRows.slice(0, 3);
|
||||
const evidenceExpansionRows = arrayOrEmpty(
|
||||
workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows,
|
||||
);
|
||||
@@ -2910,6 +3029,38 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
|
||||
? `${promotionCandidateArtifactSummary.totalCandidateCount}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-rows",
|
||||
label: "Evidence-ready candidate rows",
|
||||
value: `${evidenceReadyCandidateRows.length}`,
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-preview",
|
||||
label: "Evidence-ready candidate preview",
|
||||
value: preferredEvidenceReadyCandidate.id ?? "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-preview-gcode",
|
||||
label: "Evidence-ready candidate preview G-code",
|
||||
value: preferredEvidenceReadyCandidate.gcodePath ?? "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-promotion-allowed",
|
||||
label: "Evidence-ready candidate promotion allowed",
|
||||
value: "0",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-baseline-changing",
|
||||
label: "Evidence-ready candidate baseline changing",
|
||||
value: "no",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-artifact-rows",
|
||||
label: "Promotion candidate artifact rows",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${promotionArtifactRows.promotionCandidates ?? "not provided"}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-candidates",
|
||||
label: "Evidence expansion candidates",
|
||||
@@ -2917,6 +3068,13 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
|
||||
? `${promotionCandidateArtifactSummary.evidenceExpansionCandidateCount}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-artifact-rows",
|
||||
label: "Evidence expansion artifact rows",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${promotionArtifactRows.evidenceExpansion ?? "not provided"}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-next-evidence",
|
||||
label: "Evidence expansion next evidence",
|
||||
@@ -2985,6 +3143,82 @@ export function createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel
|
||||
? `${promotionCandidateArtifactSummary.promotionAllowedCount}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-locked-rows",
|
||||
label: "Hard-block locked inventory rows",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${hardBlockRuntimeFamilyRows.length}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-locked-preview",
|
||||
label: "Hard-block locked row preview",
|
||||
value: hardBlockRuntimePreviewRows.length > 0
|
||||
? hardBlockRuntimePreviewRows.map((row) => `${row.skipKind}:${row.path}`).join(", ")
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-promotion-allowed",
|
||||
label: "Hard-block promotions allowed",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount ?? "not provided"}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-family-count",
|
||||
label: "Hard-block runtime families",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${hardBlockRuntimeFamilySummaryRows.length}`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-family-summary",
|
||||
label: "Hard-block runtime family summary",
|
||||
value: hardBlockRuntimeFamilySummaryRows.length > 0
|
||||
? hardBlockRuntimeFamilySummaryRows
|
||||
.map((row) => `${row.family}:${row.candidateCount} locked=${row.locked ? "yes" : "no"}`)
|
||||
.join(", ")
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-detail-row-count",
|
||||
label: "Hard-block detail rows",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${hardBlockRuntimeFamilyDetailRows.length}`
|
||||
: "not provided",
|
||||
},
|
||||
...hardBlockRuntimeDetailPreviewRows.map((row, index) => ({
|
||||
id: `hard-block-runtime-detail-preview-${index + 1}`,
|
||||
label: `Hard-block detail ${index + 1}`,
|
||||
value: `${row.family}:${row.path}; reason=${row.blockReason}; next=${row.nextProof}; promotion_allowed=${row.promotionAllowed ? "1" : "0"}`,
|
||||
family: row.family,
|
||||
path: row.path,
|
||||
blockReason: row.blockReason,
|
||||
nextProof: row.nextProof,
|
||||
promotionAllowed: row.promotionAllowed,
|
||||
})),
|
||||
...hardBlockRuntimeFamilySummaryRows.map((row) => ({
|
||||
id: `hard-block-runtime-family-${row.family}`,
|
||||
label: `Hard-block family ${row.family}`,
|
||||
value: [
|
||||
`${row.candidateCount} locked rows`,
|
||||
`promotion_allowed=${row.promotionAllowedCount}`,
|
||||
`first=${row.firstPath ?? "not provided"}`,
|
||||
`reason=${row.firstBlockReason ?? "not provided"}`,
|
||||
`next=${row.nextProof ?? "not provided"}`,
|
||||
].join("; "),
|
||||
firstPath: row.firstPath,
|
||||
firstBlockReason: row.firstBlockReason,
|
||||
nextProof: row.nextProof,
|
||||
})),
|
||||
...hardBlockRuntimeFamilySummaryRows.map((row) => ({
|
||||
id: `hard-block-runtime-family-${row.family}-paths`,
|
||||
label: `Hard-block family ${row.family} paths`,
|
||||
value: arrayOrEmpty(row.lockedPaths).length > 0
|
||||
? row.lockedPaths.join(", ")
|
||||
: "not provided",
|
||||
lockedPaths: arrayOrEmpty(row.lockedPaths),
|
||||
})),
|
||||
...arrayOrEmpty(workflow?.validation?.virtualHalPromotionFamilyRows).map((row) => ({
|
||||
id: `virtual-hal-promotion-family-${row.id}`,
|
||||
label: `Promotion family ${row.label}`,
|
||||
@@ -3242,10 +3476,12 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
const promotionCandidateArtifactSummary = objectOrEmpty(artifactObject.promotionCandidateArtifactSummary);
|
||||
const expectedPromotionCandidateArtifactSummary = createPromotionCandidateArtifactSummary({
|
||||
candidateReport: virtualHalSimConfigPromotionCandidates,
|
||||
evidenceExpansionReport: artifactObject.virtualHalSimConfigEvidenceExpansion,
|
||||
inventory: simConfigInventory,
|
||||
blockedFamilies: arrayOrEmpty(artifactObject.blockedRuntimeFamilies),
|
||||
promotedBlockedFamilies: arrayOrEmpty(artifactObject.promotedBlockedFamilies),
|
||||
});
|
||||
const artifactRows = objectOrEmpty(promotionCandidateArtifactSummary.artifactRows);
|
||||
const promotionCandidateArtifactSummaryReady =
|
||||
promotionCandidateArtifactSummary.apiName === expectedPromotionCandidateArtifactSummary.apiName &&
|
||||
promotionCandidateArtifactSummary.summaryVersion === 1 &&
|
||||
@@ -3259,7 +3495,15 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
promotionCandidateArtifactSummary.totalCandidateCount === expectedPromotionCandidateArtifactSummary.totalCandidateCount &&
|
||||
promotionCandidateArtifactSummary.promotionAllowedCount === 0 &&
|
||||
promotionCandidateArtifactSummary.hardBlockRuntimeLock === expectedPromotionCandidateArtifactSummary.hardBlockRuntimeLock &&
|
||||
promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount === 0 &&
|
||||
Number.isFinite(promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount) &&
|
||||
promotionCandidateArtifactSummary.inventoryBaseline === expectedPromotionCandidateArtifactSummary.inventoryBaseline &&
|
||||
artifactRows.promotionCandidates ===
|
||||
promotionCandidateArtifactSummary.evidenceReadyCount + promotionCandidateArtifactSummary.inventoryReadyCount &&
|
||||
(
|
||||
artifactRows.evidenceExpansion === 0 ||
|
||||
artifactRows.evidenceExpansion === promotionCandidateArtifactSummary.evidenceExpansionCandidateCount
|
||||
) &&
|
||||
arrayOrEmpty(promotionCandidateArtifactSummary.layers).some((row) =>
|
||||
row.id === "evidence-ready" &&
|
||||
row.candidateCount === expectedPromotionCandidateArtifactSummary.evidenceReadyCount &&
|
||||
@@ -3442,6 +3686,13 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
? `${promotionCandidateArtifactSummary.totalCandidateCount}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-artifact-rows",
|
||||
label: "Promotion candidate artifact rows",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${artifactRows.promotionCandidates}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-candidates",
|
||||
label: "Evidence expansion candidates",
|
||||
@@ -3449,6 +3700,13 @@ export function createProjectReleaseReadinessArtifactValidation(artifact = {}) {
|
||||
? `${promotionCandidateArtifactSummary.evidenceExpansionCandidateCount}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-artifact-rows",
|
||||
label: "Evidence expansion artifact rows",
|
||||
value: promotionCandidateArtifactSummaryReady
|
||||
? `${artifactRows.evidenceExpansion}`
|
||||
: "missing",
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-next-evidence",
|
||||
label: "Evidence expansion next evidence",
|
||||
|
||||
@@ -2556,6 +2556,21 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
|
||||
?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalPromotionCandidateSummary
|
||||
?? {}
|
||||
);
|
||||
const promotionCandidateReportRows = (
|
||||
workflow?.diagnosticsArtifact?.virtualHalSimConfigPromotionCandidates?.rows
|
||||
?? workflow?.urlWorkflow?.diagnosticsArtifact?.virtualHalSimConfigPromotionCandidates?.rows
|
||||
?? []
|
||||
);
|
||||
const evidenceReadyCandidateRows = Array.isArray(promotionCandidateReportRows)
|
||||
? promotionCandidateReportRows.filter((row) =>
|
||||
row?.complete === true &&
|
||||
row?.currentNodeInventoryStatus === "PASS" &&
|
||||
row?.blockedKind === "-" &&
|
||||
row?.targetBrowserEvidence === "explicit-browser-diagnostics" &&
|
||||
row?.currentMatrixBrowserStatus === "explicit-browser-diagnostics"
|
||||
)
|
||||
: [];
|
||||
const preferredEvidenceReadyCandidate = evidenceReadyCandidateRows[0] ?? {};
|
||||
const promotionCandidateSummaryReady = promotionCandidateSummary.ready === true;
|
||||
const validationRows = Array.isArray(workflow?.validation?.rows)
|
||||
? workflow.validation.rows
|
||||
@@ -2567,6 +2582,18 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
|
||||
?? workflow?.validation?.validation?.promotionCandidateArtifactSummary
|
||||
?? {}
|
||||
);
|
||||
const promotionArtifactRows = promotionCandidateArtifactSummary.artifactRows ?? {};
|
||||
const hardBlockRuntimeFamilyRows = Array.isArray(promotionCandidateArtifactSummary.hardBlockRuntimeFamilyRows)
|
||||
? promotionCandidateArtifactSummary.hardBlockRuntimeFamilyRows
|
||||
: [];
|
||||
const hardBlockRuntimeFamilySummaryRows = Array.isArray(promotionCandidateArtifactSummary.hardBlockRuntimeFamilySummaryRows)
|
||||
? promotionCandidateArtifactSummary.hardBlockRuntimeFamilySummaryRows
|
||||
: [];
|
||||
const hardBlockRuntimeFamilyDetailRows = Array.isArray(promotionCandidateArtifactSummary.hardBlockRuntimeFamilyDetailRows)
|
||||
? promotionCandidateArtifactSummary.hardBlockRuntimeFamilyDetailRows
|
||||
: [];
|
||||
const hardBlockRuntimeDetailPreviewRows = hardBlockRuntimeFamilyDetailRows.slice(0, 5);
|
||||
const hardBlockRuntimePreviewRows = hardBlockRuntimeFamilyRows.slice(0, 3);
|
||||
const evidenceExpansion = promotionCandidateArtifactSummary.evidenceExpansion ?? {};
|
||||
const evidenceExpansionRows = (
|
||||
workflow?.diagnosticsArtifact?.virtualHalSimConfigEvidenceExpansion?.rows
|
||||
@@ -2677,6 +2704,31 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
|
||||
? `${promotionCandidateSummary.explicitBrowserDiagnosticsCount} diagnostics-ready`
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-rows",
|
||||
label: "Evidence-ready candidate rows",
|
||||
value: `${evidenceReadyCandidateRows.length}`,
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-preview",
|
||||
label: "Evidence-ready candidate preview",
|
||||
value: preferredEvidenceReadyCandidate.id ?? "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-preview-gcode",
|
||||
label: "Evidence-ready candidate preview G-code",
|
||||
value: preferredEvidenceReadyCandidate.gcodePath ?? "not provided",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-promotion-allowed",
|
||||
label: "Evidence-ready candidate promotion allowed",
|
||||
value: "0",
|
||||
},
|
||||
{
|
||||
id: "evidence-ready-candidate-baseline-changing",
|
||||
label: "Evidence-ready candidate baseline changing",
|
||||
value: "no",
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-promotion-candidate-baseline",
|
||||
label: "Candidate inventory baseline",
|
||||
@@ -2687,6 +2739,20 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
|
||||
label: "Evidence expansion next evidence",
|
||||
value: evidenceExpansion.nextEvidence ?? "not provided",
|
||||
},
|
||||
{
|
||||
id: "promotion-candidate-artifact-rows",
|
||||
label: "Promotion candidate artifact rows",
|
||||
value: promotionArtifactRows.promotionCandidates == null
|
||||
? "not provided"
|
||||
: `${promotionArtifactRows.promotionCandidates}`,
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-artifact-rows",
|
||||
label: "Evidence expansion artifact rows",
|
||||
value: promotionArtifactRows.evidenceExpansion == null
|
||||
? "not provided"
|
||||
: `${promotionArtifactRows.evidenceExpansion}`,
|
||||
},
|
||||
{
|
||||
id: "evidence-expansion-baseline-changing",
|
||||
label: "Evidence expansion baseline changing",
|
||||
@@ -2744,6 +2810,76 @@ export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWo
|
||||
label: "Promoted blocked families",
|
||||
value: promotedBlockedFamilyCount ?? "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-locked-rows",
|
||||
label: "Hard-block locked inventory rows",
|
||||
value: `${hardBlockRuntimeFamilyRows.length}`,
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-locked-preview",
|
||||
label: "Hard-block locked row preview",
|
||||
value: hardBlockRuntimePreviewRows.length > 0
|
||||
? hardBlockRuntimePreviewRows.map((row) => `${row.skipKind}:${row.path}`).join(", ")
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-promotion-allowed",
|
||||
label: "Hard-block promotions allowed",
|
||||
value: promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount == null
|
||||
? "not provided"
|
||||
: `${promotionCandidateArtifactSummary.hardBlockRuntimePromotionAllowedCount}`,
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-family-count",
|
||||
label: "Hard-block runtime families",
|
||||
value: `${hardBlockRuntimeFamilySummaryRows.length}`,
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-family-summary",
|
||||
label: "Hard-block runtime family summary",
|
||||
value: hardBlockRuntimeFamilySummaryRows.length > 0
|
||||
? hardBlockRuntimeFamilySummaryRows
|
||||
.map((row) => `${row.family}:${row.candidateCount} locked=${row.locked ? "yes" : "no"}`)
|
||||
.join(", ")
|
||||
: "not provided",
|
||||
},
|
||||
{
|
||||
id: "hard-block-runtime-detail-row-count",
|
||||
label: "Hard-block detail rows",
|
||||
value: `${hardBlockRuntimeFamilyDetailRows.length}`,
|
||||
},
|
||||
...hardBlockRuntimeDetailPreviewRows.map((row, index) => ({
|
||||
id: `hard-block-runtime-detail-preview-${index + 1}`,
|
||||
label: `Hard-block detail ${index + 1}`,
|
||||
value: `${row.family}:${row.path}; reason=${row.blockReason}; next=${row.nextProof}; promotion_allowed=${row.promotionAllowed ? "1" : "0"}`,
|
||||
family: row.family,
|
||||
path: row.path,
|
||||
blockReason: row.blockReason,
|
||||
nextProof: row.nextProof,
|
||||
promotionAllowed: row.promotionAllowed,
|
||||
})),
|
||||
...hardBlockRuntimeFamilySummaryRows.map((row) => ({
|
||||
id: `hard-block-runtime-family-${row.family}`,
|
||||
label: `Hard-block family ${row.family}`,
|
||||
value: [
|
||||
`${row.candidateCount} locked rows`,
|
||||
`promotion_allowed=${row.promotionAllowedCount}`,
|
||||
`first=${row.firstPath ?? "not provided"}`,
|
||||
`reason=${row.firstBlockReason ?? "not provided"}`,
|
||||
`next=${row.nextProof ?? "not provided"}`,
|
||||
].join("; "),
|
||||
firstPath: row.firstPath,
|
||||
firstBlockReason: row.firstBlockReason,
|
||||
nextProof: row.nextProof,
|
||||
})),
|
||||
...hardBlockRuntimeFamilySummaryRows.map((row) => ({
|
||||
id: `hard-block-runtime-family-${row.family}-paths`,
|
||||
label: `Hard-block family ${row.family} paths`,
|
||||
value: Array.isArray(row.lockedPaths) && row.lockedPaths.length > 0
|
||||
? row.lockedPaths.join(", ")
|
||||
: "not provided",
|
||||
lockedPaths: Array.isArray(row.lockedPaths) ? row.lockedPaths : [],
|
||||
})),
|
||||
{
|
||||
id: "virtual-hal-promotion-families",
|
||||
label: "Virtual HAL promotion families",
|
||||
@@ -3171,6 +3307,19 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderStat
|
||||
status: "manifest-backed",
|
||||
}))
|
||||
);
|
||||
const candidateRows = sourceRows
|
||||
.filter((row) => row.sourceKind === "gcode")
|
||||
.map((row, index) => ({
|
||||
id: `evidence-candidate-${index + 1}`,
|
||||
familyId: row.familyId,
|
||||
label: `Evidence candidate ${index + 1}`,
|
||||
value: row.value,
|
||||
candidateStatus: "evidence-ready",
|
||||
promotionAllowed: false,
|
||||
baselineChanging: false,
|
||||
sourceKind: row.sourceKind,
|
||||
manifestBacked: row.manifestBacked,
|
||||
}));
|
||||
const ready = rows.length > 0 && rows.every(({ value }) => String(value).includes("diagnostics=ready"));
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-promotion-family-rows-render-state",
|
||||
@@ -3183,7 +3332,9 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilyRowsRenderStat
|
||||
statusLine: `${ready ? "Ready" : "Blocked"}: ${ready ? `${rows.length} promotion families ready` : "promotion family rows missing"}`,
|
||||
rows,
|
||||
sourceRows,
|
||||
candidateRows,
|
||||
sourceFileCount: sourceRows.length,
|
||||
candidateCount: candidateRows.length,
|
||||
dataset: {
|
||||
handoffPhase: ready ? "ready" : "blocked",
|
||||
handoffReady: ready ? "true" : "false",
|
||||
@@ -3212,6 +3363,10 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterVi
|
||||
const filteredSourceRows = selectedSourceKind === "all"
|
||||
? familyScopedSourceRows
|
||||
: familyScopedSourceRows.filter((sourceRow) => sourceRow.sourceKind === selectedSourceKind);
|
||||
const candidateRows = Array.isArray(renderState?.candidateRows) ? renderState.candidateRows : [];
|
||||
const filteredCandidateRows = selectedFamilyId === "all"
|
||||
? candidateRows
|
||||
: candidateRows.filter((candidateRow) => candidateRow.familyId === selectedFamilyId);
|
||||
const familyFilters = [
|
||||
{
|
||||
id: "all",
|
||||
@@ -3255,6 +3410,7 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterVi
|
||||
.filter((row) => row.sourceFileCount > 0);
|
||||
const ready = renderState?.ready === true && totalSourceFileCount > 0;
|
||||
const selectedCount = filteredSourceRows.length;
|
||||
const selectedCandidateCount = filteredCandidateRows.length;
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-promotion-family-source-filter-view-model",
|
||||
viewModelVersion: 1,
|
||||
@@ -3273,8 +3429,11 @@ export function createIniPanelShellWorkflowOverviewPromotionFamilySourceFilterVi
|
||||
totalSourceFileCount,
|
||||
scopedSourceFileCount,
|
||||
filteredSourceFileCount: selectedCount,
|
||||
totalCandidateCount: candidateRows.length,
|
||||
filteredCandidateCount: selectedCandidateCount,
|
||||
familyRows,
|
||||
sourceRows: filteredSourceRows,
|
||||
candidateRows: filteredCandidateRows,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3633,12 +3792,17 @@ export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSt
|
||||
})),
|
||||
];
|
||||
const sourceRows = Array.isArray(viewModel?.sourceRows) ? viewModel.sourceRows : [];
|
||||
const candidateRows = Array.isArray(viewModel?.candidateRows) ? viewModel.candidateRows : [];
|
||||
const rows = [
|
||||
...filterRows,
|
||||
...sourceRows.map((sourceRow) => ({
|
||||
...sourceRow,
|
||||
rowType: "source-row",
|
||||
})),
|
||||
...candidateRows.map((candidateRow) => ({
|
||||
...candidateRow,
|
||||
rowType: "candidate-row",
|
||||
})),
|
||||
];
|
||||
|
||||
for (const row of rows) {
|
||||
@@ -3655,6 +3819,11 @@ export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSt
|
||||
if (row.sourceKind) {
|
||||
term.dataset[`${effectiveRowDatasetPrefix}SourceKind`] = row.sourceKind;
|
||||
}
|
||||
if (row.candidateStatus) {
|
||||
term.dataset[`${effectiveRowDatasetPrefix}CandidateStatus`] = row.candidateStatus;
|
||||
term.dataset[`${effectiveRowDatasetPrefix}PromotionAllowed`] = row.promotionAllowed ? "1" : "0";
|
||||
term.dataset[`${effectiveRowDatasetPrefix}BaselineChanging`] = row.baselineChanging ? "yes" : "no";
|
||||
}
|
||||
term.textContent = row.label ?? row.id;
|
||||
|
||||
const detail = documentRef.createElement("dd");
|
||||
@@ -3670,9 +3839,18 @@ export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSt
|
||||
if (row.sourceKind) {
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}SourceKind`] = row.sourceKind;
|
||||
}
|
||||
if (row.candidateStatus) {
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}CandidateStatus`] = row.candidateStatus;
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}PromotionAllowed`] = row.promotionAllowed ? "1" : "0";
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}BaselineChanging`] = row.baselineChanging ? "yes" : "no";
|
||||
}
|
||||
detail.textContent = row.rowType === "source-row"
|
||||
? row.value
|
||||
: `${row.value}: ${row.count ?? 0}${row.selected ? " selected" : ""}`;
|
||||
: (
|
||||
row.rowType === "candidate-row"
|
||||
? row.value
|
||||
: `${row.value}: ${row.count ?? 0}${row.selected ? " selected" : ""}`
|
||||
);
|
||||
rowsNode.append(term, detail);
|
||||
}
|
||||
|
||||
@@ -3683,8 +3861,10 @@ export function renderIniPanelShellWorkflowOverviewPromotionFamilySourceFilterSt
|
||||
controlCount: controlSpecs.length,
|
||||
filterRowCount: filterRows.length,
|
||||
sourceFileCount: sourceRows.length,
|
||||
candidateCount: candidateRows.length,
|
||||
rowIds: rows.map(({ id }) => id),
|
||||
sourceRowIds: sourceRows.map(({ id }) => id),
|
||||
candidateRowIds: candidateRows.map(({ id }) => id),
|
||||
dataset: {
|
||||
handoffPhase: mountNode.dataset.handoffPhase,
|
||||
handoffReady: mountNode.dataset.handoffReady,
|
||||
@@ -4005,6 +4185,19 @@ export function createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownVi
|
||||
virtualHalReportsReady &&
|
||||
sourceFiles.length > 0;
|
||||
const summaryCandidateId = candidateId ?? "not provided";
|
||||
const candidateEvidenceReady = candidate?.complete === true &&
|
||||
blockedFamilyExcluded &&
|
||||
nodeInventoryReady &&
|
||||
browserEvidenceReady;
|
||||
const promotionCandidateLayers =
|
||||
findWorkflowOverviewRowValue(summaryViewModel, "promotion-candidate-layers") ??
|
||||
(candidateEvidenceReady ? "evidence-ready" : "not provided");
|
||||
const promotionCandidateAllowed =
|
||||
findWorkflowOverviewRowValue(summaryViewModel, "promotion-candidate-allowed") ??
|
||||
(candidateEvidenceReady ? "0" : "not provided");
|
||||
const promotionBaselineChanging = promotionCandidateAllowed === "0"
|
||||
? "no"
|
||||
: (promotionCandidateAllowed === "not provided" ? "not provided" : "yes");
|
||||
const rows = [
|
||||
{
|
||||
id: "candidate",
|
||||
@@ -4036,6 +4229,23 @@ export function createIniPanelShellWorkflowOverviewPromotionCandidateDrilldownVi
|
||||
label: "Blocked-family exclusion",
|
||||
value: blockedFamilyExcluded ? "passed" : (candidate?.blockedKind ?? "not provided"),
|
||||
},
|
||||
{
|
||||
id: "candidate-layer",
|
||||
label: "Candidate layer",
|
||||
value: promotionCandidateLayers.includes("evidence-ready")
|
||||
? "evidence-ready"
|
||||
: promotionCandidateLayers,
|
||||
},
|
||||
{
|
||||
id: "inventory-promotion-allowed",
|
||||
label: "Inventory promotion allowed",
|
||||
value: promotionCandidateAllowed,
|
||||
},
|
||||
{
|
||||
id: "inventory-baseline-changing",
|
||||
label: "Inventory baseline changing",
|
||||
value: promotionBaselineChanging,
|
||||
},
|
||||
{
|
||||
id: "virtual-hal-reports",
|
||||
label: "Required virtual HAL reports",
|
||||
@@ -4353,6 +4563,309 @@ export function mountIniPanelShellWorkflowOverviewPromotionCandidateDrilldownSta
|
||||
}
|
||||
}
|
||||
|
||||
export function createIniPanelShellWorkflowOverviewHardBlockDrilldownViewModel(
|
||||
summaryViewModel = createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(),
|
||||
{
|
||||
validation = null,
|
||||
} = {},
|
||||
) {
|
||||
const summary = validation?.promotionCandidateArtifactSummary ?? {};
|
||||
const detailRows = Array.isArray(summary.hardBlockRuntimeFamilyDetailRows)
|
||||
? summary.hardBlockRuntimeFamilyDetailRows
|
||||
: [];
|
||||
const familyRows = Array.isArray(summary.hardBlockRuntimeFamilySummaryRows)
|
||||
? summary.hardBlockRuntimeFamilySummaryRows
|
||||
: [];
|
||||
const promotionAllowedCount = Number(summary.hardBlockRuntimePromotionAllowedCount ?? 0);
|
||||
const ready = detailRows.length > 0 && promotionAllowedCount === 0;
|
||||
const rows = [
|
||||
{
|
||||
id: "detail-row-count",
|
||||
label: "Hard-block detail rows",
|
||||
value: `${detailRows.length}`,
|
||||
},
|
||||
{
|
||||
id: "family-count",
|
||||
label: "Hard-block families",
|
||||
value: `${familyRows.length}`,
|
||||
},
|
||||
{
|
||||
id: "promotion-allowed",
|
||||
label: "Promotion allowed",
|
||||
value: `${promotionAllowedCount}`,
|
||||
},
|
||||
{
|
||||
id: "inventory-baseline",
|
||||
label: "Inventory baseline",
|
||||
value: findWorkflowOverviewRowValue(summaryViewModel, "virtual-hal-promotion-candidate-baseline")
|
||||
?? summary.inventoryBaseline
|
||||
?? "not provided",
|
||||
},
|
||||
];
|
||||
const familyDetailRows = detailRows.map((row, index) => ({
|
||||
id: row.id ?? `hard-block-detail-${index + 1}`,
|
||||
label: `${row.family} ${index + 1}`,
|
||||
value: row.path ?? "not provided",
|
||||
family: row.family ?? "not provided",
|
||||
path: row.path ?? "not provided",
|
||||
blockReason: row.blockReason ?? "not provided",
|
||||
nextProof: row.nextProof ?? "not provided",
|
||||
promotionAllowed: row.promotionAllowed === true,
|
||||
}));
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-view-model",
|
||||
viewModelVersion: 1,
|
||||
phase: ready ? "ready" : "blocked",
|
||||
ready,
|
||||
title: "Hard-block drilldown",
|
||||
statusText: ready ? "Ready" : "Blocked",
|
||||
detailText: ready
|
||||
? `${detailRows.length} locked rows grouped by ${familyRows.length} families`
|
||||
: "hard-block detail rows missing",
|
||||
statusLine: `${ready ? "Ready" : "Blocked"}: ${ready ? `${detailRows.length} locked rows grouped by ${familyRows.length} families` : "hard-block detail rows missing"}`,
|
||||
rows,
|
||||
detailRows: familyDetailRows,
|
||||
rowCount: rows.length + familyDetailRows.length,
|
||||
detailRowCount: familyDetailRows.length,
|
||||
familyCount: familyRows.length,
|
||||
promotionAllowedCount,
|
||||
dataset: {
|
||||
handoffPhase: ready ? "ready" : "blocked",
|
||||
handoffReady: ready ? "true" : "false",
|
||||
handoffScope: "workflow-overview-hard-block-drilldown",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellWorkflowOverviewHardBlockDrilldownRenderState(
|
||||
viewModel = createIniPanelShellWorkflowOverviewHardBlockDrilldownViewModel(),
|
||||
) {
|
||||
const rows = [
|
||||
...(Array.isArray(viewModel?.rows) ? viewModel.rows : []),
|
||||
...(Array.isArray(viewModel?.detailRows) ? viewModel.detailRows : []).map((row) => ({
|
||||
...row,
|
||||
label: `${row.family}: ${row.path}`,
|
||||
value: `${row.blockReason}; next=${row.nextProof}; promotion_allowed=${row.promotionAllowed ? "1" : "0"}`,
|
||||
hardBlockDetail: true,
|
||||
})),
|
||||
].map(({ id, label, value, family, path, blockReason, nextProof, promotionAllowed, hardBlockDetail }) => ({
|
||||
id,
|
||||
label,
|
||||
value: value == null ? "" : String(value),
|
||||
...(family ? { family } : {}),
|
||||
...(path ? { path } : {}),
|
||||
...(blockReason ? { blockReason } : {}),
|
||||
...(nextProof ? { nextProof } : {}),
|
||||
...(promotionAllowed != null ? { promotionAllowed: promotionAllowed === true } : {}),
|
||||
...(hardBlockDetail != null ? { hardBlockDetail: hardBlockDetail === true } : {}),
|
||||
}));
|
||||
const ready = viewModel?.ready === true;
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-render-state",
|
||||
renderStateVersion: 1,
|
||||
phase: ready ? "ready" : "blocked",
|
||||
ready,
|
||||
title: viewModel?.title ?? "Hard-block drilldown",
|
||||
statusText: viewModel?.statusText ?? (ready ? "Ready" : "Blocked"),
|
||||
detailText: viewModel?.detailText ?? "hard-block drilldown missing",
|
||||
statusLine: viewModel?.statusLine ?? `${ready ? "Ready" : "Blocked"}: hard-block drilldown`,
|
||||
rows,
|
||||
rowCount: rows.length,
|
||||
detailRowCount: viewModel?.detailRowCount ?? 0,
|
||||
familyCount: viewModel?.familyCount ?? 0,
|
||||
promotionAllowedCount: viewModel?.promotionAllowedCount ?? 0,
|
||||
dataset: viewModel?.dataset ?? {
|
||||
handoffPhase: ready ? "ready" : "blocked",
|
||||
handoffReady: ready ? "true" : "false",
|
||||
handoffScope: "workflow-overview-hard-block-drilldown",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellWorkflowOverviewHardBlockDrilldownDomContract({
|
||||
rowDatasetPrefix = "workflowOverviewHardBlockDrilldown",
|
||||
selectors = {},
|
||||
} = {}) {
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-dom-contract",
|
||||
contractVersion: 1,
|
||||
requiredNodeIds: ["mount", "status", "rows"],
|
||||
selectors: {
|
||||
mount: selectors.mount ?? "[data-workflow-overview-hard-block-drilldown]",
|
||||
status: selectors.status ?? "[data-workflow-overview-hard-block-drilldown-status]",
|
||||
rows: selectors.rows ?? "[data-workflow-overview-hard-block-drilldown-rows]",
|
||||
},
|
||||
mountDatasetKeys: ["handoffPhase", "handoffReady", "handoffScope"],
|
||||
rowDatasetPrefix,
|
||||
};
|
||||
}
|
||||
|
||||
export function createIniPanelShellWorkflowOverviewHardBlockDrilldownDomReadiness({
|
||||
rowDatasetPrefix = "workflowOverviewHardBlockDrilldown",
|
||||
contract = createIniPanelShellWorkflowOverviewHardBlockDrilldownDomContract({ rowDatasetPrefix }),
|
||||
documentRef = globalThis.document,
|
||||
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
|
||||
statusNode = documentRef?.querySelector?.(contract.selectors.status),
|
||||
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
|
||||
} = {}) {
|
||||
const checks = {
|
||||
document: Boolean(documentRef?.createElement),
|
||||
mount: Boolean(mountNode),
|
||||
status: Boolean(statusNode),
|
||||
rows: Boolean(rowsNode),
|
||||
rowDatasetPrefix: Boolean(contract.rowDatasetPrefix),
|
||||
};
|
||||
const missing = Object.entries(checks)
|
||||
.filter(([, passed]) => !passed)
|
||||
.map(([name]) => name);
|
||||
const ready = missing.length === 0;
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-dom-readiness",
|
||||
readinessVersion: 1,
|
||||
phase: ready ? "ready" : "blocked",
|
||||
ready,
|
||||
missing,
|
||||
checks,
|
||||
contract,
|
||||
};
|
||||
}
|
||||
|
||||
export function renderIniPanelShellWorkflowOverviewHardBlockDrilldownState(
|
||||
renderState = createIniPanelShellWorkflowOverviewHardBlockDrilldownRenderState(),
|
||||
{
|
||||
rowDatasetPrefix = "workflowOverviewHardBlockDrilldown",
|
||||
contract = createIniPanelShellWorkflowOverviewHardBlockDrilldownDomContract({ rowDatasetPrefix }),
|
||||
documentRef = globalThis.document,
|
||||
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
|
||||
statusNode = documentRef?.querySelector?.(contract.selectors.status),
|
||||
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
|
||||
} = {},
|
||||
) {
|
||||
const readiness = createIniPanelShellWorkflowOverviewHardBlockDrilldownDomReadiness({
|
||||
contract,
|
||||
documentRef,
|
||||
mountNode,
|
||||
statusNode,
|
||||
rowsNode,
|
||||
});
|
||||
if (!readiness.ready) {
|
||||
throw new Error(
|
||||
`Workflow overview hard-block drilldown DOM is not ready: ${readiness.missing.join(", ")}`,
|
||||
);
|
||||
}
|
||||
mountNode.dataset.handoffPhase = renderState?.dataset?.handoffPhase ?? "blocked";
|
||||
mountNode.dataset.handoffReady = renderState?.dataset?.handoffReady ?? "false";
|
||||
mountNode.dataset.handoffScope = renderState?.dataset?.handoffScope
|
||||
?? "workflow-overview-hard-block-drilldown";
|
||||
statusNode.textContent = renderState?.statusLine ?? "Blocked: hard-block drilldown missing";
|
||||
rowsNode.replaceChildren();
|
||||
const effectiveRowDatasetPrefix = contract.rowDatasetPrefix;
|
||||
const rows = Array.isArray(renderState?.rows) ? renderState.rows : [];
|
||||
for (const row of rows) {
|
||||
const term = documentRef.createElement("dt");
|
||||
term.dataset[`${effectiveRowDatasetPrefix}Row`] = row.id;
|
||||
term.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
|
||||
if (row.family) {
|
||||
term.dataset[`${effectiveRowDatasetPrefix}Family`] = row.family;
|
||||
term.dataset[`${effectiveRowDatasetPrefix}Path`] = row.path ?? "";
|
||||
term.dataset[`${effectiveRowDatasetPrefix}PromotionAllowed`] = row.promotionAllowed ? "1" : "0";
|
||||
term.dataset[`${effectiveRowDatasetPrefix}HardBlockDetail`] = row.hardBlockDetail ? "true" : "false";
|
||||
}
|
||||
term.textContent = row.label;
|
||||
const detail = documentRef.createElement("dd");
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}Value`] = row.id;
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}Status`] = renderState?.ready ? "pass" : "blocked";
|
||||
if (row.family) {
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}Family`] = row.family;
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}Path`] = row.path ?? "";
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}PromotionAllowed`] = row.promotionAllowed ? "1" : "0";
|
||||
detail.dataset[`${effectiveRowDatasetPrefix}HardBlockDetail`] = row.hardBlockDetail ? "true" : "false";
|
||||
}
|
||||
detail.textContent = row.value;
|
||||
rowsNode.append(term, detail);
|
||||
}
|
||||
return {
|
||||
rendered: true,
|
||||
statusLine: statusNode.textContent,
|
||||
rowCount: rows.length,
|
||||
rowIds: rows.map(({ id }) => id),
|
||||
detailRowCount: rows.filter(({ hardBlockDetail }) => hardBlockDetail === true).length,
|
||||
familyCount: renderState?.familyCount ?? 0,
|
||||
promotionAllowedCount: renderState?.promotionAllowedCount ?? 0,
|
||||
dataset: {
|
||||
handoffPhase: mountNode.dataset.handoffPhase,
|
||||
handoffReady: mountNode.dataset.handoffReady,
|
||||
handoffScope: mountNode.dataset.handoffScope,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function mountIniPanelShellWorkflowOverviewHardBlockDrilldownState({
|
||||
renderState = createIniPanelShellWorkflowOverviewHardBlockDrilldownRenderState(),
|
||||
rowDatasetPrefix = "workflowOverviewHardBlockDrilldown",
|
||||
contract = createIniPanelShellWorkflowOverviewHardBlockDrilldownDomContract({ rowDatasetPrefix }),
|
||||
documentRef = globalThis.document,
|
||||
mountNode = documentRef?.querySelector?.(contract.selectors.mount),
|
||||
statusNode = documentRef?.querySelector?.(contract.selectors.status),
|
||||
rowsNode = documentRef?.querySelector?.(contract.selectors.rows),
|
||||
} = {}) {
|
||||
const domReadiness = createIniPanelShellWorkflowOverviewHardBlockDrilldownDomReadiness({
|
||||
contract,
|
||||
documentRef,
|
||||
mountNode,
|
||||
statusNode,
|
||||
rowsNode,
|
||||
});
|
||||
if (!domReadiness.ready) {
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-dom-mount",
|
||||
workflowVersion: 1,
|
||||
phase: "blocked",
|
||||
ready: false,
|
||||
statusLine: `Blocked: ${domReadiness.missing.join(", ")}`,
|
||||
contract,
|
||||
domReadiness,
|
||||
renderState,
|
||||
renderResult: null,
|
||||
error: null,
|
||||
};
|
||||
}
|
||||
try {
|
||||
const renderResult = renderIniPanelShellWorkflowOverviewHardBlockDrilldownState(renderState, {
|
||||
contract,
|
||||
documentRef,
|
||||
mountNode,
|
||||
statusNode,
|
||||
rowsNode,
|
||||
});
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-dom-mount",
|
||||
workflowVersion: 1,
|
||||
phase: renderState?.phase === "ready" ? "ready" : "blocked",
|
||||
ready: renderState?.ready === true,
|
||||
statusLine: renderResult.statusLine,
|
||||
contract,
|
||||
domReadiness,
|
||||
renderState,
|
||||
renderResult,
|
||||
error: null,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
apiName: "ini-panel-shell-workflow-overview-hard-block-drilldown-dom-mount",
|
||||
workflowVersion: 1,
|
||||
phase: "blocked",
|
||||
ready: false,
|
||||
statusLine: `Blocked: ${error?.message ?? "hard-block drilldown DOM mount error"}`,
|
||||
contract,
|
||||
domReadiness,
|
||||
renderState,
|
||||
renderResult: null,
|
||||
error: error?.message ?? String(error),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract({
|
||||
rowDatasetPrefix = "workflowOverviewReleaseReadinessArtifactUrlWorkflow",
|
||||
selectors = {},
|
||||
|
||||
Reference in New Issue
Block a user