refactor: move update pipeline into dialog
This commit is contained in:
@@ -273,6 +273,7 @@ export default function UpdatePage({
|
||||
const [actionBusy, setActionBusy] = useState(false);
|
||||
const [reloadReady, setReloadReady] = useState(false);
|
||||
const [showNotesDialog, setShowNotesDialog] = useState(false);
|
||||
const [showPipelineDialog, setShowPipelineDialog] = useState(false);
|
||||
const [now, setNow] = useState(() => Date.now());
|
||||
|
||||
const announced = useRef<string | null>(null);
|
||||
@@ -338,6 +339,10 @@ export default function UpdatePage({
|
||||
}, [isMock]);
|
||||
|
||||
const job = info?.job;
|
||||
useEffect(() => {
|
||||
if (job && activeStatuses.has(job.status)) setShowPipelineDialog(true);
|
||||
}, [job?.id, job?.status]);
|
||||
|
||||
const applyQueuedAt = timestamp(job?.applyQueuedAt);
|
||||
const restartAt =
|
||||
timestamp(job?.restartDeadline) ??
|
||||
@@ -468,6 +473,7 @@ export default function UpdatePage({
|
||||
mockTimer.current = null;
|
||||
setActionBusy(false);
|
||||
setConfirmVersion(null);
|
||||
setShowPipelineDialog(true);
|
||||
if (confirmAction === "download") {
|
||||
handleScenarioChange("downloading_30");
|
||||
notify?.("Mock:开始模拟下载,状态已流转至 [下载中]", "info");
|
||||
@@ -496,6 +502,7 @@ export default function UpdatePage({
|
||||
setConfirmVersion(null);
|
||||
setReloadReady(false);
|
||||
setLiveInfo((current) => (current ? { ...current, job: result.job } : current));
|
||||
setShowPipelineDialog(true);
|
||||
notify?.(
|
||||
confirmAction === "download" ? "更新包下载已开始" : "更新已开始,服务会短暂重启",
|
||||
"info"
|
||||
@@ -715,11 +722,18 @@ export default function UpdatePage({
|
||||
</Surface>
|
||||
</div>
|
||||
|
||||
{/* Stepper Process Card */}
|
||||
<Surface className="tn-stepper-surface">
|
||||
{/* Stepper Process Dialog */}
|
||||
<Dialog
|
||||
visible={showPipelineDialog}
|
||||
header="版本升级流水线"
|
||||
confirmBtn={{ content: "关闭", theme: "default" }}
|
||||
cancelBtn={null}
|
||||
onConfirm={() => setShowPipelineDialog(false)}
|
||||
onClose={() => setShowPipelineDialog(false)}
|
||||
>
|
||||
<div className="tn-stepper-surface">
|
||||
<div className="tn-stepper-head">
|
||||
<div>
|
||||
<h3 className="tn-section-heading">版本升级流水线</h3>
|
||||
<small className="tn-section-subheading">
|
||||
标准化发布流程:版本发现 → 校验签名与清单 → 安全暂存 → 原子切换并重启
|
||||
</small>
|
||||
@@ -834,7 +848,8 @@ export default function UpdatePage({
|
||||
<span>更新成功完成!新版本已通过内置端点健康检查,账本数据与附件完整无损。</span>
|
||||
</div>
|
||||
)}
|
||||
</Surface>
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
{/* Release Details Section */}
|
||||
{latest ? (
|
||||
@@ -856,32 +871,8 @@ export default function UpdatePage({
|
||||
</small>
|
||||
)}
|
||||
</div>
|
||||
<div className="tn-release-header-actions">
|
||||
{notes && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="medium"
|
||||
onClick={() => setShowNotesDialog(true)}
|
||||
icon={<FileCode size={15} />}
|
||||
>
|
||||
查看完整更新日志
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Release Notes Preview snippet */}
|
||||
{notes && (
|
||||
<div className="tn-release-notes-box">
|
||||
<div className="tn-release-notes-heading">
|
||||
<span>更新内容概览</span>
|
||||
</div>
|
||||
<div className="tn-release-notes-content">
|
||||
<MarkdownNotes value={notes} compact />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Integrity & compatibility facts grid */}
|
||||
<div className="tn-facts-grid">
|
||||
<div className="tn-fact-item">
|
||||
@@ -963,6 +954,30 @@ export default function UpdatePage({
|
||||
</Surface>
|
||||
)}
|
||||
|
||||
{latest && notes && (
|
||||
<Surface className="tn-release-notes-surface">
|
||||
<div className="tn-release-notes-header">
|
||||
<div>
|
||||
<span className="tn-eyebrow">更新日志</span>
|
||||
<h3 className="tn-section-heading">本次版本更新内容</h3>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="medium"
|
||||
onClick={() => setShowNotesDialog(true)}
|
||||
icon={<FileCode size={15} />}
|
||||
>
|
||||
查看完整日志
|
||||
</Button>
|
||||
</div>
|
||||
<div className="tn-release-notes-box">
|
||||
<div className="tn-release-notes-content">
|
||||
<MarkdownNotes value={notes} compact />
|
||||
</div>
|
||||
</div>
|
||||
</Surface>
|
||||
)}
|
||||
|
||||
{/* Manual source warning if not systemd */}
|
||||
{!info.configured && (
|
||||
<div className="tn-update-explainer">
|
||||
|
||||
@@ -847,6 +847,17 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
|
||||
margin-bottom: 16px;
|
||||
padding: 20px;
|
||||
}
|
||||
.tn-release-notes-surface {
|
||||
margin-bottom: 16px;
|
||||
padding: 20px;
|
||||
}
|
||||
.tn-release-notes-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.tn-release-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
@@ -870,7 +881,7 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
|
||||
color: var(--tn-text-secondary);
|
||||
}
|
||||
.tn-release-notes-box {
|
||||
margin: 16px 0;
|
||||
margin: 0;
|
||||
padding: 12px 16px;
|
||||
background: #f8fafc;
|
||||
border: 1px solid var(--tn-border);
|
||||
@@ -1064,6 +1075,13 @@ input:focus-visible, textarea:focus-visible, select:focus-visible {
|
||||
.tn-release-header {
|
||||
flex-direction: column;
|
||||
}
|
||||
.tn-release-notes-header {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
.tn-release-notes-header .t-button {
|
||||
width: 100%;
|
||||
}
|
||||
.tn-release-card-actions {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user