feat(ops): show deployment capability receipt
This commit is contained in:
@@ -17,6 +17,28 @@ export type OpsDeploymentProfile = {
|
||||
fit: string;
|
||||
};
|
||||
|
||||
export type OpsInfrastructureCapability = {
|
||||
id: string;
|
||||
label: string;
|
||||
state: "configured" | "available_unconfigured" | "externally_supplied" | "unavailable";
|
||||
source: string;
|
||||
detail: string;
|
||||
endpoint: Record<string, string | number | boolean | null>;
|
||||
secret_refs: string[];
|
||||
dependent_modules: string[];
|
||||
};
|
||||
|
||||
export type OpsPostInstallTask = {
|
||||
id: string;
|
||||
resume_key: string;
|
||||
capability_id: string;
|
||||
state: string;
|
||||
owner_module: string;
|
||||
summary: string;
|
||||
required_inputs: string[];
|
||||
secret_boundary: string;
|
||||
};
|
||||
|
||||
export type OpsSizingAssumption = {
|
||||
area: string;
|
||||
baseline: string;
|
||||
@@ -186,6 +208,8 @@ export type OpsStatus = {
|
||||
failed_operation_count?: number;
|
||||
outcome_unknown_count?: number;
|
||||
active_operation_count?: number;
|
||||
infrastructure_capability_count?: number;
|
||||
pending_post_install_task_count?: number;
|
||||
};
|
||||
readiness: {
|
||||
ready: boolean;
|
||||
@@ -220,6 +244,16 @@ export type OpsStatus = {
|
||||
deployment_profiles: OpsDeploymentProfile[];
|
||||
sizing: OpsSizingAssumption[];
|
||||
runtime_cluster: OpsRuntimeCluster;
|
||||
infrastructure: {
|
||||
configured: boolean;
|
||||
available: boolean;
|
||||
schema_version?: number | null;
|
||||
installation_id?: string | null;
|
||||
profile?: string | null;
|
||||
capabilities: OpsInfrastructureCapability[];
|
||||
post_install_tasks: OpsPostInstallTask[];
|
||||
error?: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
export function fetchOpsStatus(settings: ApiSettings): Promise<OpsStatus> {
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
type OpsCheck,
|
||||
type OpsDeploymentProfile,
|
||||
type OpsGovernanceModule,
|
||||
type OpsInfrastructureCapability,
|
||||
type OpsRecoveryOperation,
|
||||
type OpsRuntimeNode,
|
||||
type OpsSizingAssumption,
|
||||
@@ -168,6 +169,7 @@ export default function OpsPage({ settings, auth }: {settings: ApiSettings;auth:
|
||||
<MetricCard label="Database capacity" value={databaseCapacityValue(status)} tone={databaseCapacityTone(status)} detail="Peak pooled connections / available connections" />
|
||||
<MetricCard label="Recovery" value={status?.summary.recovery_required_count ?? 0} tone={status?.summary.recovery_required_count ? "danger" : "good"} detail="Operations requiring recovery attention" />
|
||||
<MetricCard label="Provider bindings" value={status?.governance.summary.configured_external_provider_count ?? 0} tone={status?.governance.summary.provider_attention_count ? "warning" : "good"} detail={`${status?.governance.summary.provider_attention_count ?? 0} requiring attention`} />
|
||||
<MetricCard label="i18n:govoplan-ops.infrastructure_capabilities" value={status?.summary.infrastructure_capability_count ?? 0} tone={status?.infrastructure.available ? "good" : "neutral"} detail={i18nMessage("i18n:govoplan-ops.pending_post_install_tasks", { value0: status?.summary.pending_post_install_task_count ?? 0 })} />
|
||||
</div>
|
||||
|
||||
<div className="dashboard-grid">
|
||||
@@ -197,6 +199,16 @@ export default function OpsPage({ settings, auth }: {settings: ApiSettings;auth:
|
||||
<ProfileList profiles={status?.deployment_profiles ?? []} />
|
||||
</Card>
|
||||
|
||||
<Card title="i18n:govoplan-ops.infrastructure_capabilities">
|
||||
<InfrastructureCapabilityTable items={status?.infrastructure.capabilities ?? []} />
|
||||
{(status?.infrastructure.post_install_tasks.length ?? 0) > 0 && <dl className="detail-list">
|
||||
{status?.infrastructure.post_install_tasks.map((task) => <div key={task.resume_key}>
|
||||
<dt><StatusBadge status="warning" label={task.state} /></dt>
|
||||
<dd><strong>{task.summary}</strong><span className="muted"> · {task.owner_module} · {task.required_inputs.join(", ")}</span></dd>
|
||||
</div>)}
|
||||
</dl>}
|
||||
</Card>
|
||||
|
||||
<Card title="i18n:govoplan-ops.sizing_assumptions.6ade9a90">
|
||||
<SizingTable items={status?.sizing ?? []} />
|
||||
</Card>
|
||||
@@ -507,6 +519,33 @@ function SizingTable({ items }: {items: OpsSizingAssumption[];}) {
|
||||
|
||||
}
|
||||
|
||||
function InfrastructureCapabilityTable({ items }: {items: OpsInfrastructureCapability[];}) {
|
||||
if (!items.length) return <p className="muted">i18n:govoplan-ops.no_infrastructure_capabilities</p>;
|
||||
const columns: DataGridColumn<OpsInfrastructureCapability>[] = [
|
||||
{ id: "capability", header: "i18n:govoplan-ops.capability", width: "minmax(220px, 1fr)", minWidth: 190, resizable: true, sortable: true, filterable: true, value: (item) => `${item.label} ${item.id}`, render: (item) => <div><strong>{item.label}</strong><span className="muted block">{item.id}</span></div> },
|
||||
{ id: "state", header: "i18n:govoplan-ops.status.bae7d5be", width: 190, sortable: true, filterable: true, value: (item) => item.state, render: (item) => <StatusBadge status={capabilityTone(item.state)} label={item.state.replaceAll("_", " ")} /> },
|
||||
{ id: "source", header: "i18n:govoplan-ops.source", width: "minmax(180px, .7fr)", minWidth: 160, resizable: true, filterable: true, value: (item) => item.source },
|
||||
{ id: "endpoint", header: "i18n:govoplan-ops.endpoint", width: "minmax(220px, 1fr)", minWidth: 180, resizable: true, filterable: true, value: (item) => endpointLabel(item.endpoint) },
|
||||
{ id: "consumers", header: "i18n:govoplan-ops.consumers", width: "minmax(220px, 1fr)", minWidth: 180, resizable: true, filterable: true, value: (item) => item.dependent_modules.join(" "), render: (item) => item.dependent_modules.join(", ") || "-" }
|
||||
];
|
||||
return <DataGrid id="ops-infrastructure-capabilities" rows={items} columns={columns} getRowKey={(item) => item.id} />;
|
||||
}
|
||||
|
||||
function endpointLabel(endpoint: OpsInfrastructureCapability["endpoint"]): string {
|
||||
if (typeof endpoint.host === "string") {
|
||||
const scheme = typeof endpoint.scheme === "string" ? `${endpoint.scheme}://` : "";
|
||||
const port = typeof endpoint.port === "number" ? `:${endpoint.port}` : "";
|
||||
return `${scheme}${endpoint.host}${port}`;
|
||||
}
|
||||
return typeof endpoint.reference === "string" ? endpoint.reference : "-";
|
||||
}
|
||||
|
||||
function capabilityTone(state: OpsInfrastructureCapability["state"]): string {
|
||||
if (state === "configured" || state === "externally_supplied") return "success";
|
||||
if (state === "available_unconfigured") return "warning";
|
||||
return "inactive";
|
||||
}
|
||||
|
||||
function stateTone(state: string): string {
|
||||
if (state === "ok") return "success";
|
||||
if (state === "warning") return "warning";
|
||||
|
||||
@@ -11,6 +11,13 @@ export const generatedTranslations: PlatformTranslations = {
|
||||
"i18n:govoplan-ops.surface.governance": "Governance inventory",
|
||||
"i18n:govoplan-ops.surface.deployment": "Deployment profiles",
|
||||
"i18n:govoplan-ops.surface.sizing": "Sizing assumptions",
|
||||
"i18n:govoplan-ops.infrastructure_capabilities": "Infrastructure capabilities",
|
||||
"i18n:govoplan-ops.pending_post_install_tasks": "{value0} pending post-install task(s)",
|
||||
"i18n:govoplan-ops.no_infrastructure_capabilities": "No deployment capability receipt is available.",
|
||||
"i18n:govoplan-ops.capability": "Capability",
|
||||
"i18n:govoplan-ops.source": "Source",
|
||||
"i18n:govoplan-ops.endpoint": "Endpoint",
|
||||
"i18n:govoplan-ops.consumers": "Consumers",
|
||||
"i18n:govoplan-ops.surface.run_probes": "Run operational probes",
|
||||
"i18n:govoplan-ops.surface.drain_node": "Drain runtime node",
|
||||
"i18n:govoplan-ops.reason.loading": "Operations status is loading.",
|
||||
@@ -80,6 +87,13 @@ export const generatedTranslations: PlatformTranslations = {
|
||||
"i18n:govoplan-ops.surface.governance": "Governance-Inventar",
|
||||
"i18n:govoplan-ops.surface.deployment": "Bereitstellungsprofile",
|
||||
"i18n:govoplan-ops.surface.sizing": "Dimensionierungsannahmen",
|
||||
"i18n:govoplan-ops.infrastructure_capabilities": "Infrastruktur-Fähigkeiten",
|
||||
"i18n:govoplan-ops.pending_post_install_tasks": "{value0} ausstehende Nachinstallationsaufgabe(n)",
|
||||
"i18n:govoplan-ops.no_infrastructure_capabilities": "Es ist kein Bereitstellungsnachweis für Infrastruktur-Fähigkeiten verfügbar.",
|
||||
"i18n:govoplan-ops.capability": "Fähigkeit",
|
||||
"i18n:govoplan-ops.source": "Quelle",
|
||||
"i18n:govoplan-ops.endpoint": "Endpunkt",
|
||||
"i18n:govoplan-ops.consumers": "Verwendende Module",
|
||||
"i18n:govoplan-ops.surface.run_probes": "Betriebsprüfungen ausführen",
|
||||
"i18n:govoplan-ops.surface.drain_node": "Laufzeitknoten leeren",
|
||||
"i18n:govoplan-ops.reason.loading": "Der Betriebsstatus wird geladen.",
|
||||
|
||||
Reference in New Issue
Block a user