fix: 平台构建
This commit is contained in:
@@ -49,7 +49,7 @@ export function AIConfigDiffReviewPanel() {
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="console-panel ai-diff-review-panel" aria-label="AI config diff review">
|
||||
<section className="console-panel console-module ai-diff-review-panel" aria-label="AI config diff review">
|
||||
<div className="panel-header">
|
||||
<h2><FileCheck2 size={16} /> AI 配置审查</h2>
|
||||
<button type="button" className="icon-command" disabled={loading || Boolean(busyId)} onClick={() => void refresh()}><RotateCw size={14} /><span>刷新</span></button>
|
||||
@@ -58,15 +58,15 @@ export function AIConfigDiffReviewPanel() {
|
||||
{loading && <LoadingState label="正在同步 AI 配置差异…" compact />}
|
||||
{!loading && error && <ErrorState title="AI 配置审查不可用" reason={error} diagnosticId="ai-config-diffs" onRetry={() => void refresh()} compact />}
|
||||
{!loading && !error && (
|
||||
<div className="operation-list">
|
||||
{items.length === 0 && <p className="operations-module-empty">当前没有 AI 配置差异。</p>}
|
||||
<div className="console-record-list">
|
||||
{items.length === 0 && <p className="console-empty-note">当前没有 AI 配置差异。</p>}
|
||||
{items.slice(0, 12).map((item) => (
|
||||
<div key={item.id} className="operation-item">
|
||||
<div className="operation-item-head"><strong>{item.serverInstanceId} · {item.key}</strong><span className={`status-pill status-${item.state === "approved" ? "succeeded" : item.state === "pending" ? "warning" : "disabled"}`}>{item.state}</span></div>
|
||||
<div className="operation-meta"><span>请求 {item.requestId}</span><span>版本 {item.configVersion}</span><span>{item.model || "Platform model"}</span><span>到期 {new Date(item.expiresAt).toLocaleString()}</span>{item.jobId && <span>任务 {item.jobId}</span>}</div>
|
||||
<div key={item.id} className="console-record">
|
||||
<div className="console-record-head"><strong>{item.serverInstanceId} · {item.key}</strong><span className={`status-pill status-${item.state === "approved" ? "succeeded" : item.state === "pending" ? "warning" : "disabled"}`}>{item.state}</span></div>
|
||||
<div className="console-record-meta"><span>请求 {item.requestId}</span><span>版本 {item.configVersion}</span><span>{item.model || "Platform model"}</span><span>到期 {new Date(item.expiresAt).toLocaleString()}</span>{item.jobId && <span>任务 {item.jobId}</span>}</div>
|
||||
<p>{item.diffSummary}</p>
|
||||
{item.proposedConfig && <pre className="log-view ai-config-proposal">{item.proposedConfig}</pre>}
|
||||
{item.state === "pending" && <div className="row-actions"><button type="button" disabled={Boolean(busyId)} onClick={() => setSelected(item)}><FileCheck2 size={14} /><span>审查并批准</span></button></div>}
|
||||
{item.state === "pending" && <div className="row-actions console-row-actions"><button type="button" disabled={Boolean(busyId)} onClick={() => setSelected(item)}><FileCheck2 size={14} /><span>审查并批准</span></button></div>}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -98,15 +98,15 @@ export function PluginLifecycleWorkbench({ pluginId, pluginName, operations = li
|
||||
<button type="button" className="primary-command" disabled={disabled || busy || !selectedServerId} onClick={() => setConfirming(true)}>{busy ? "提交中…" : "执行"}</button>
|
||||
</div>
|
||||
{installation ? (
|
||||
<div className="operation-item plugin-lifecycle-state">
|
||||
<div className="operation-item-head"><strong>{installation.currentState} → {installation.desiredState}</strong><span className="status-pill status-active">{installation.compatibility || "pending"}</span></div>
|
||||
<div className="operation-meta">
|
||||
<div className="console-record plugin-lifecycle-state">
|
||||
<div className="console-record-head"><strong>{installation.currentState} → {installation.desiredState}</strong><span className="status-pill status-active">{installation.compatibility || "pending"}</span></div>
|
||||
<div className="console-record-meta">
|
||||
<span>当前 {installation.currentVersion || "--"}</span><span>目标 {installation.targetVersion || "--"}</span><span>依赖 {installation.dependencyState || "unknown"}</span>
|
||||
{installation.jobId && <span>任务 {installation.jobId}</span>}{installation.auditEventId && <span>审计 {installation.auditEventId}</span>}{installation.alertId && <span>告警 {installation.alertId}</span>}
|
||||
</div>
|
||||
{installation.failureReason && <p className="operation-error">{installation.failureReason}</p>}
|
||||
</div>
|
||||
) : <p className="operations-module-empty">该服务器尚无插件生命周期记录。</p>}
|
||||
) : <p className="console-empty-note">该服务器尚无插件生命周期记录。</p>}
|
||||
</>
|
||||
)}
|
||||
<ConfirmDialog open={confirming} title={`确认${lifecycleOperationLabel(operation)}`} description={`插件 ${pluginName},服务器 ${selectedServerId || "--"}${targetVersion ? `,目标版本 ${targetVersion}` : ""}。`} confirmLabel={lifecycleOperationLabel(operation)} danger={disruptiveOperations.includes(operation)} busy={busy} onCancel={() => { if (!busy) setConfirming(false); }} onConfirm={() => void submit()} />
|
||||
|
||||
@@ -69,7 +69,7 @@ export function ProductionGovernancePanel({ compact = false, title = "容量与
|
||||
const visibleEndpoints = compact ? capacity?.endpoints.slice(0, 3) ?? [] : capacity?.endpoints ?? [];
|
||||
|
||||
return (
|
||||
<section className="console-panel production-governance-panel" aria-label="production capacity and alerts">
|
||||
<section className="console-panel console-module production-governance-panel" aria-label="production capacity and alerts">
|
||||
<div className="panel-header">
|
||||
<h2><AlertTriangle size={16} /> {title}</h2>
|
||||
<button type="button" className="icon-command" disabled={loading || Boolean(busyKey)} onClick={() => void refresh()} title="刷新容量与告警">
|
||||
@@ -82,39 +82,39 @@ export function ProductionGovernancePanel({ compact = false, title = "容量与
|
||||
{!loading && error && <ErrorState title="生产治理状态不可用" reason={error} diagnosticId="production-governance" onRetry={() => void refresh()} compact />}
|
||||
{!loading && !error && capacity && (
|
||||
<>
|
||||
<dl className="operations-pulse-strip production-capacity-strip">
|
||||
<dl className="console-stat-strip console-stat-strip-spaced">
|
||||
<div><dt>运行槽位</dt><dd>{capacity.totalRunningJobs}/{capacity.totalMaxJobs}</dd></div>
|
||||
<div><dt>排队</dt><dd>{capacity.totalQueuedJobs}</dd></div>
|
||||
<div><dt>未关闭告警</dt><dd>{capacity.activeAlerts}</dd></div>
|
||||
</dl>
|
||||
<div className="operations-endpoint-list" aria-label="capacity endpoints">
|
||||
<div className="console-row-list" aria-label="capacity endpoints">
|
||||
{visibleEndpoints.map((endpoint) => (
|
||||
<div key={endpoint.runEndpointId} className="operations-endpoint-row">
|
||||
<div key={endpoint.runEndpointId} className="console-row">
|
||||
<span><strong>{endpoint.displayName}</strong><small>{endpoint.pressureCodes?.join(", ") || "capacity.available"}</small></span>
|
||||
<span className={cx("status-pill", endpoint.pressureCodes?.length ? "status-warning" : `status-${endpoint.status}`)}>{endpoint.pressureCodes?.length ? "压力" : endpoint.status}</span>
|
||||
<span>{endpoint.runningJobs}/{endpoint.maxJobs} · 队列 {endpoint.queuedJobs}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="operation-list production-alert-list" aria-label="durable alerts">
|
||||
{visibleAlerts.length === 0 && <p className="operations-module-empty">当前没有持久告警。</p>}
|
||||
<div className="console-record-list console-record-list-spaced production-alert-list" aria-label="durable alerts">
|
||||
{visibleAlerts.length === 0 && <p className="console-empty-note">当前没有持久告警。</p>}
|
||||
{visibleAlerts.map((alert) => {
|
||||
const pending = busyKey.startsWith(`${alert.id}:`);
|
||||
return (
|
||||
<div key={alert.id} className="operation-item">
|
||||
<div className="operation-item-head">
|
||||
<div key={alert.id} className="console-record operation-item">
|
||||
<div className="console-record-head">
|
||||
<strong>{alert.title}</strong>
|
||||
<span className={cx("status-pill", alert.severity === "critical" ? "status-failed" : alert.state === "resolved" ? "status-succeeded" : "status-warning")}>{alert.state}</span>
|
||||
</div>
|
||||
<p>{alert.message}</p>
|
||||
<div className="operation-meta">
|
||||
<div className="console-record-meta">
|
||||
<span>{alert.sourceKind} · {alert.sourceId}</span>
|
||||
<span>发生 {alert.occurrenceCount} 次</span>
|
||||
{alert.lastJobId && <span>任务 {alert.lastJobId}</span>}
|
||||
{alert.lastAuditEventId && <span>审计 {alert.lastAuditEventId}</span>}
|
||||
</div>
|
||||
{alert.state !== "resolved" && (
|
||||
<div className="row-actions production-alert-actions">
|
||||
<div className="row-actions console-row-actions production-alert-actions">
|
||||
{alert.state === "active" && <button type="button" disabled={pending} onClick={() => setIntent({ alert, action: "acknowledge" })}><Check size={14} /><span>确认</span></button>}
|
||||
<button type="button" disabled={pending} onClick={() => setIntent({ alert, action: "resolve" })}><CheckCheck size={14} /><span>解决</span></button>
|
||||
{alert.retryable && <button type="button" disabled={pending} onClick={() => setIntent({ alert, action: "retry" })}><Activity size={14} /><span>重试源</span></button>}
|
||||
|
||||
Reference in New Issue
Block a user