审批 / 消息 / 纪要 / 汇报补上助理栏 —— 那不是空态,是整栏没渲染
`.workspace` 是**三列**网格(侧栏 · 工作区 · 助理栏 440px)。这四个模块只渲染了 两栏,右边就空出一条 **234px 的白带** —— 里面什么都没有,不是「空态没写好」, 是这一栏根本没画。实测四面皆然。 那一栏该摆什么,按 OS 4.1 定:「对话流 / 视图区」是**工作台-任务**的交互结构、 是回环输入的唯一入口。这四个要素各有自己的形态 —— 审批是通过/驳回附依据、 消息是就地答(MessageDesk 自己那条 NoteBand 早写着「不开放任务对话流」)、 纪要靠人记、汇报是确认即提交 —— 都不经对话流。 所以**不摆能打字的输入框**:那是在许诺聊得起来。只如实说这一栏是什么、 这一面该怎么用、想说话该去哪儿。共用件 `AssistantAside`,色调 `muted` (通路不在这儿,灰着就不许诺),章也不打彩色渐变 —— 亮着像在待命。 四句文案各说各的事,不是同一句复制四遍: 审批 拍板不用先商量 —— 看依据就够了,想先问一句就去那一单的任务里说 消息 这儿不用聊 —— 就地答完即可,作答只及卡面,不用跑进别人的任务 纪要 会得你自己开 —— 你写下来最准,写完登记起单责任才落到人 汇报 不用你写一个字 —— 按任务日志自动聚合,要数字好看得回任务里干活 顺带治了题头被截:一行摆四件(章 · 任务助理 · Agent · 说明句),对话区压到 212px 时说明句只剩 29px,被省略号截成「汇…」,一个字都读不出来。改为按**本栏宽度** 容器查询,挤了就让说明句换到第二行拿整行说完。任务面的「盯着这单推进 · 有事随时说」 以前也是截的,这下一并读全了。容器上下文落在 `.jc-tch` 不是 `.session-chat` —— 后者带拖拽调宽的负偏移柄,不给它加 containment。 补 3 个缺失图标(gavel / pencil-line / chart-column)—— 不补就是空 SVG,这坑踩过。 typecheck ✓ lint ✓ depcruise 374 模块 ✓ api:check ✓ 490 测试 ✓ Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KeDBx2PHLavbURXB8LJJ7m
This commit is contained in:
@@ -2958,3 +2958,23 @@
|
|||||||
.proto-root .jc-empty.t-muted .r1 { background: radial-gradient(circle, var(--line-soft), transparent 72%); }
|
.proto-root .jc-empty.t-muted .r1 { background: radial-gradient(circle, var(--line-soft), transparent 72%); }
|
||||||
.proto-root .jc-empty.t-muted .r2 { background: var(--line-soft); }
|
.proto-root .jc-empty.t-muted .r2 { background: var(--line-soft); }
|
||||||
.proto-root .jc-empty.t-muted .jc-empty-ico { color: var(--ink-3); }
|
.proto-root .jc-empty.t-muted .jc-empty-ico { color: var(--ink-3); }
|
||||||
|
|
||||||
|
/* ── 助理栏的「不在岗」态(补充,非原型)──────────────────────────────
|
||||||
|
审批 / 消息 / 纪要 / 汇报四面的助理栏:对话流按 OS 4.1 只长在任务上,
|
||||||
|
这四面用不到它。章不打彩色渐变 —— 亮着像在待命,灰着才说得清「这儿不说话」。 */
|
||||||
|
.proto-root .jc-tch-mark.t-idle { background: var(--line-soft); color: var(--ink-3); box-shadow: none; }
|
||||||
|
|
||||||
|
/* ── 助理栏题头的抗压(补充,非原型)────────────────────────────────
|
||||||
|
题头一行摆四件:章 · 任务助理 · Agent · 说明句。对话区被压到 ~210px 时,
|
||||||
|
说明句只剩 29px 宽,被省略号截成「汇…」—— 一个字都读不出来,等于白占地方。
|
||||||
|
让它在挤的时候**换到第二行**,拿整行说完;右对齐也一并取消(自己一行就不用靠边)。
|
||||||
|
|
||||||
|
按**自己这一栏的宽度**判断,不按视口 —— 对话区宽度还受收起状态影响,
|
||||||
|
视口断点管不住它。容器上下文落在 `.jc-tch`(内层壳)而不是 `.session-chat`:
|
||||||
|
后者带着拖拽调宽的柄(负偏移),不给它加 containment。 */
|
||||||
|
.proto-root .jc-tch { container-type: inline-size; }
|
||||||
|
|
||||||
|
@container (max-width: 300px) {
|
||||||
|
.proto-root .jc-tch-head { flex-wrap: wrap; row-gap: 2px; }
|
||||||
|
.proto-root .jc-tch-desc { flex: 1 0 100%; text-align: left; white-space: normal; }
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { decideApprovalRoute, listApprovalsForMeRoute } from '@contracts';
|
|||||||
import { Ico } from '@web-shared/Ico.tsx';
|
import { Ico } from '@web-shared/Ico.tsx';
|
||||||
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
||||||
import { call } from '@web-shared/typed-fetch.ts';
|
import { call } from '@web-shared/typed-fetch.ts';
|
||||||
import { Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
import { AssistantAside, Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
||||||
|
|
||||||
const STATE_CHIP = {
|
const STATE_CHIP = {
|
||||||
pending: { tone: 'todo' as const, label: '待审批', pulse: true },
|
pending: { tone: 'todo' as const, label: '待审批', pulse: true },
|
||||||
@@ -188,6 +188,13 @@ export function ApprovalDesk() {
|
|||||||
)}
|
)}
|
||||||
</DocPanel>
|
</DocPanel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<AssistantAside
|
||||||
|
ico="gavel"
|
||||||
|
note="审批不经对话"
|
||||||
|
title="拍板不用先商量"
|
||||||
|
desc="通过还是驳回,看依据就够了 —— 驳回时把原因写进意见,发起人就知道该改哪儿。想先问一句再拍,去那一单的任务里说。"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { answerMessageRoute, listMessagesRoute, markMessageReadRoute } from '@co
|
|||||||
import { Ico } from '@web-shared/Ico.tsx';
|
import { Ico } from '@web-shared/Ico.tsx';
|
||||||
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
||||||
import { call } from '@web-shared/typed-fetch.ts';
|
import { call } from '@web-shared/typed-fetch.ts';
|
||||||
import { Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
import { AssistantAside, Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
||||||
|
|
||||||
const KIND_META: Readonly<Record<string, { icon: string; grad: readonly [string, string]; kicker: string }>> = {
|
const KIND_META: Readonly<Record<string, { icon: string; grad: readonly [string, string]; kicker: string }>> = {
|
||||||
notice: { icon: 'bell', grad: ['#7f3bf5', '#5b21cf'], kicker: '系统 · 通知' },
|
notice: { icon: 'bell', grad: ['#7f3bf5', '#5b21cf'], kicker: '系统 · 通知' },
|
||||||
@@ -151,6 +151,13 @@ export function MessageDesk() {
|
|||||||
)}
|
)}
|
||||||
</DocPanel>
|
</DocPanel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<AssistantAside
|
||||||
|
ico="at-sign"
|
||||||
|
note="消息就地答"
|
||||||
|
title="这儿不用聊"
|
||||||
|
desc="别人请你补的信息,在左边那条消息上直接答完就行 —— 作答只及卡面,不用跑进别人的任务。助理只在你自己的任务里说话。"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { appendResolutionRoute, createMinuteRoute, listMinutesRoute, registerRes
|
|||||||
import { Ico } from '@web-shared/Ico.tsx';
|
import { Ico } from '@web-shared/Ico.tsx';
|
||||||
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
||||||
import { call } from '@web-shared/typed-fetch.ts';
|
import { call } from '@web-shared/typed-fetch.ts';
|
||||||
import { Avatar, AvatarStack, Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
import { AssistantAside, Avatar, AvatarStack, Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
||||||
|
|
||||||
export function MinuteDesk() {
|
export function MinuteDesk() {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
@@ -269,6 +269,13 @@ export function MinuteDesk() {
|
|||||||
</Section>
|
</Section>
|
||||||
</DocPanel>
|
</DocPanel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<AssistantAside
|
||||||
|
ico="pencil-line"
|
||||||
|
note="纪要靠你记"
|
||||||
|
title="会得你自己开"
|
||||||
|
desc="会上定了什么,你写下来最准 —— 写完把该办的事登记起单,责任才落到人。助理在任务里帮你把事推下去,不代你开会。"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { REPORT_PERIOD_LABEL, draftReportRoute, submitReportRoute } from '@contr
|
|||||||
import { Ico } from '@web-shared/Ico.tsx';
|
import { Ico } from '@web-shared/Ico.tsx';
|
||||||
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
import ScrollArea from '@web-shared/ScrollArea.tsx';
|
||||||
import { call } from '@web-shared/typed-fetch.ts';
|
import { call } from '@web-shared/typed-fetch.ts';
|
||||||
import { Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
import { AssistantAside, Chip, DocPanel, Hero, EmptyState, ListEmpty, NoteBand, Section, SidebarHead } from '@web-shared/desk/module-kit.tsx';
|
||||||
|
|
||||||
const PERIODS: ReadonlyArray<{ k: ReportPeriodName; ico: string }> = [
|
const PERIODS: ReadonlyArray<{ k: ReportPeriodName; ico: string }> = [
|
||||||
{ k: 'day', ico: 'calendar-days' },
|
{ k: 'day', ico: 'calendar-days' },
|
||||||
@@ -191,6 +191,13 @@ export function ReportDesk() {
|
|||||||
</div>
|
</div>
|
||||||
</DocPanel>
|
</DocPanel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<AssistantAside
|
||||||
|
ico="chart-column"
|
||||||
|
note="汇报自动聚"
|
||||||
|
title="不用你写一个字"
|
||||||
|
desc="日报周报按你的任务日志自动聚合,你看一眼、确认即提交。要让数字变好看,得回任务里把活干完 —— 助理在那边等你。"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,3 +229,47 @@ export function EmptyState({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 助理栏 —— 审批 / 消息 / 纪要 / 汇报四面右侧那一栏。
|
||||||
|
*
|
||||||
|
* `.workspace` 是**三列**网格(侧栏 · 工作区 · 助理栏)。这四个模块原来只渲染两栏,
|
||||||
|
* 右边就空出一条 234px 的白带 —— 不是空态,是**什么都没有**,看着像坏了。
|
||||||
|
*
|
||||||
|
* 那一栏摆什么?按 OS 4.1,「对话流」是**工作台-任务**的交互结构、是回环输入的唯一入口;
|
||||||
|
* 这四个要素各有自己的形态:审批是通过/驳回附依据、消息是就地答、纪要靠人记、
|
||||||
|
* 汇报是确认即提交 —— 都不经对话流。所以这里不摆一个能打字的输入框(那是许诺聊得起来),
|
||||||
|
* 只如实说明这一栏是什么、这一面该怎么用、想说话该去哪儿。
|
||||||
|
*
|
||||||
|
* 色调用 `muted`:通路不在这儿,灰着就不许诺。
|
||||||
|
*/
|
||||||
|
export function AssistantAside({
|
||||||
|
ico,
|
||||||
|
title,
|
||||||
|
desc,
|
||||||
|
note,
|
||||||
|
}: {
|
||||||
|
ico: string;
|
||||||
|
title: string;
|
||||||
|
desc: string;
|
||||||
|
/** 题头右侧那半句 —— 一句话说清这一栏在本面的角色 */
|
||||||
|
note: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<section className="session-chat">
|
||||||
|
<div className="jc-tch">
|
||||||
|
<header className="jc-tch-head">
|
||||||
|
<span className="jc-tch-mark t-idle">
|
||||||
|
<Ico name="bot" s={15} />
|
||||||
|
</span>
|
||||||
|
<b className="jc-tch-name">任务助理</b>
|
||||||
|
<em className="jc-tch-tag">Agent</em>
|
||||||
|
<span className="jc-tch-desc">{note}</span>
|
||||||
|
</header>
|
||||||
|
<div className="jc-tch-scroll">
|
||||||
|
<EmptyState ico={ico} tone="muted" title={title} desc={desc} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ export function Ico({ name, s = 18 }: { name: string; s?: number }) {
|
|||||||
"shield-check": (<><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" /><path d="m9 12 2 2 4-4" /></>),
|
"shield-check": (<><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z" /><path d="m9 12 2 2 4-4" /></>),
|
||||||
scan: (<><path d="M3 7V5a2 2 0 0 1 2-2h2" /><path d="M17 3h2a2 2 0 0 1 2 2v2" /><path d="M21 17v2a2 2 0 0 1-2 2h-2" /><path d="M7 21H5a2 2 0 0 1-2-2v-2" /><path d="M7 12h10" /></>),
|
scan: (<><path d="M3 7V5a2 2 0 0 1 2-2h2" /><path d="M17 3h2a2 2 0 0 1 2 2v2" /><path d="M21 17v2a2 2 0 0 1-2 2h-2" /><path d="M7 21H5a2 2 0 0 1-2-2v-2" /><path d="M7 12h10" /></>),
|
||||||
"file-check": (<><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" /><path d="M14 2v4a2 2 0 0 0 2 2h4" /><path d="m9 15 2 2 4-4" /></>),
|
"file-check": (<><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" /><path d="M14 2v4a2 2 0 0 0 2 2h4" /><path d="m9 15 2 2 4-4" /></>),
|
||||||
|
gavel: (<><path d="m14.5 12.5-8 8a2.119 2.119 0 1 1-3-3l8-8" /><path d="m16 16 6-6" /><path d="m8 8 6-6" /><path d="m9 7 8 8" /><path d="m21 11-8-8" /></>),
|
||||||
|
"pencil-line": (<><path d="M13 21h8" /><path d="m15 5 4 4" /><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" /></>),
|
||||||
|
"chart-column": (<><path d="M3 3v16a2 2 0 0 0 2 2h16" /><path d="M18 17V9" /><path d="M13 17V5" /><path d="M8 17v-3" /></>),
|
||||||
"trending-up": (<><path d="M16 7h6v6" /><path d="m22 7-8.5 8.5-5-5L2 17" /></>),
|
"trending-up": (<><path d="M16 7h6v6" /><path d="m22 7-8.5 8.5-5-5L2 17" /></>),
|
||||||
ban: (<><circle cx="12" cy="12" r="10" /><path d="m4.9 4.9 14.2 14.2" /></>),
|
ban: (<><circle cx="12" cy="12" r="10" /><path d="m4.9 4.9 14.2 14.2" /></>),
|
||||||
key: (<><path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4" /><path d="m21 2-9.6 9.6" /><circle cx="7.5" cy="15.5" r="5.5" /></>),
|
key: (<><path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4" /><path d="m21 2-9.6 9.6" /><circle cx="7.5" cy="15.5" r="5.5" /></>),
|
||||||
|
|||||||
Reference in New Issue
Block a user