流程包详情整页 UI 梳理:一套图纸语言,贴边清零

量了一遍页面,问题四处,全修:

① **属性卡是混进来的第二种风格**(治理台圆角卡),同格栅其它三块都是图纸风。
   改为图纸卡:外壳同纸同影同角,题头入族 ——
   「流程包 · 版本」「流程图 · 顺序」「异常 · 看板」「节点 · 属性」四张两字·两字对仗;
   题头右侧 = 状态字 + 保存芯片(与「新建」「编辑」同款);
   内部小卡与节点条也入图纸语言(方角细线、mono 小字距题头),等高 250、超高内滚。

② **属性卡内部三处贴死**(题头↕0节点条↕0属性格↕0按钮):
   内容区统一 12px 呼吸;保存从底部挪进题头,不用滚到底找按钮。

③ **异常板被 stretch 拉到 916px**,三条异常配一片空白:改为高度随内容
   (实测 916 → 150),行顶仍与属性卡对齐。

④ 2px 的 margin hack 删了,row2 两卡顶严格同线(840 = 840)。

typecheck ✓ lint ✓ depcruise ✓ api:check ✓ 498 测试 ✓

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
2026-07-28 16:10:57 +08:00
co-authored by Claude Opus 5
parent ba5f65e685
commit 894769e2ca
2 changed files with 38 additions and 33 deletions
+15 -4
View File
@@ -564,8 +564,19 @@
.g-ex .msg { flex: 1; min-width: 0; font-size: 10.5px; line-height: 1.55; letter-spacing: 0; text-transform: none; color: #3a4452; } .g-ex .msg { flex: 1; min-width: 0; font-size: 10.5px; line-height: 1.55; letter-spacing: 0; text-transform: none; color: #3a4452; }
.g-exboard-empty { padding: 16px 18px; font-family: var(--sh-mono); font-size: 10px; line-height: 1.9; color: var(--sh-muted); } .g-exboard-empty { padding: 16px 18px; font-family: var(--sh-mono); font-size: 10px; line-height: 1.9; color: var(--sh-muted); }
/* 节点属性卡:与流程图同宽(格栅右列);内部小卡等高,超高的内容自己滚 */ /* 异常板高度随内容走,不被右侧属性卡拉高 —— 三条异常配 900px 空板才是脏 */
.g-nodecard { min-height: 0; margin-top: 2px; } .g-exboard { align-self: start; }
.g-nodecard .g-props { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); align-items: stretch; }
.g-nodecard .g-prop { height: 250px; display: flex; flex-direction: column; overflow: hidden; } /* 节点属性卡:图纸卡(外壳复用 g-vercard),与流程图同宽;题头右侧是状态字 + 保存芯片 */
.g-nodecard { min-height: 0; }
.g-nodecard .g-vercard-h { height: auto; padding: 13px 18px 10px; }
.g-nodecard .g-vercard-h .n { margin-left: auto; }
.g-nodecard .g-vercard-h .g-ver-new { margin-left: 10px; }
/* 内部三段(提示/节点条/属性格)统一 12px 呼吸 —— 从前是裸兄弟,三处贴死 */
.g-nodecard-b { display: flex; flex-direction: column; gap: 12px; padding: 14px 18px 16px; }
/* 小卡与节点条也入图纸语言:方角细线;等高 250,超高的内容自己滚 */
.g-nodecard .g-pick { border-radius: 0; border-color: var(--sh-line); }
.g-nodecard .g-props { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); align-items: stretch; gap: 12px; }
.g-nodecard .g-prop { height: 250px; display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--sh-line); border-radius: 0; box-shadow: none; }
.g-nodecard .g-prop-h { font-family: var(--sh-mono); font-size: 9.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--sh-steel); border-bottom: 1px solid var(--sh-line); }
.g-nodecard .g-prop-b { flex: 1; min-height: 0; overflow-y: auto; } .g-nodecard .g-prop-b { flex: 1; min-height: 0; overflow-y: auto; }
@@ -761,13 +761,28 @@ function FlowLab({
<div className="g-vercard-f">点一条异常,定位到它的节点属性;清零后才可激活。</div> <div className="g-vercard-f">点一条异常,定位到它的节点属性;清零后才可激活。</div>
</aside> </aside>
{/* 右下:节点属性卡 —— 与流程图同宽;闭环(岗位/判据/映射)在这里决定 */} {/* 右下:节点属性(图纸卡,与流程图同宽)—— 闭环(岗位/判据/映射)在这里决定 */}
<div className="g-nodecard"> <div className="g-vercard g-nodecard">
<Card <div className="g-vercard-h">
ico="sliders-horizontal" 节点 · 属性
title="节点属性" <span className="n">{dirty ? '有改动待保存' : '点节点就地填写'}</span>
extra={dirty ? '有改动待保存' : '点节点就地填写 —— 闭环(岗位/判据/映射)在这里决定'} <button
> className="g-ver-new"
disabled={!dirty || save.isPending}
onClick={() => {
if (graph !== null) save.mutate({ graph, idMap: {} });
}}
>
<Ico name="send" s={11} /> {save.isPending ? '保存中…' : `保存为 v${nextVersion}`}
</button>
</div>
<div className="g-nodecard-b">
{saveErr !== undefined && (
<Note tone="warn">
<b>保存失败:</b>
{saveErr}
</Note>
)}
<div className="g-picker"> <div className="g-picker">
{nodes {nodes
.filter((n) => n.kind !== 'start' && n.kind !== 'end' && n.kind !== 'end-bad') .filter((n) => n.kind !== 'start' && n.kind !== 'end' && n.kind !== 'end-bad')
@@ -968,30 +983,9 @@ function FlowLab({
</Prop> </Prop>
)} )}
</div> </div>
<Acts
align="end"
items={[
{
label: save.isPending ? '保存中…' : dirty ? `保存为 v${nextVersion}` : '编排无改动',
ico: 'send',
primary: dirty,
disabled: !dirty || save.isPending,
// 保存不设闸也不设确认:存下来的是未生效的新版,谁也伤不着;异常看板会说还缺什么
onClick: () => {
if (graph !== null) save.mutate({ graph, idMap: {} });
},
},
]}
/>
{saveErr !== undefined && (
<Note tone="warn">
<b>保存失败:</b>
{saveErr}
</Note>
)}
</> </>
)} )}
</Card> </div>
</div> </div>
</div> </div>
</Sec> </Sec>