代码泰囧
This commit is contained in:
1 parent
21722b9f5a
commit
f32de510fe
7 files changed
+178
-25
No files matched your search
@@ -500,12 +500,12 @@ export function PositionBuiltinAgentChat({
|
||||
|
||||
return (
|
||||
<ThreadContext.Provider value={threadContextValue}>
|
||||
<div className="flex min-h-0 flex-1 flex-col">
|
||||
<header className="flex min-h-12 shrink-0 items-center gap-2 border-b border-slate-100 px-4 py-2 dark:border-[#2b8ffe]/20">
|
||||
<span className="flex size-7 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
||||
<div className="position-roundtable-agent-analysis-page position-roundtable-builtin-chat flex min-h-0 flex-1 flex-col">
|
||||
<header className="position-roundtable-agent-header flex min-h-12 shrink-0 items-center gap-2 border-b border-slate-100 px-4 py-2 dark:border-[#2b8ffe]/20">
|
||||
<span className="position-roundtable-agent-avatar flex size-7 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
||||
{canWrite ? <Icon className="size-4" /> : <LockKeyhole className="size-3.5" />}
|
||||
</span>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="position-roundtable-agent-title min-w-0 flex-1">
|
||||
<h2 className="truncate text-sm font-extrabold text-slate-900 dark:text-[#e8edf5]">
|
||||
{agentDisplayName}
|
||||
</h2>
|
||||
@@ -536,7 +536,7 @@ export function PositionBuiltinAgentChat({
|
||||
</header>
|
||||
|
||||
{persistedArtifacts.length > 0 && (
|
||||
<section className="shrink-0 border-b border-slate-100 bg-slate-50/70 px-4 py-2.5 dark:border-[#2b8ffe]/20 dark:bg-[#032650]/50">
|
||||
<section className="position-roundtable-agent-artifacts shrink-0 border-b border-slate-100 bg-slate-50/70 px-4 py-2.5 dark:border-[#2b8ffe]/20 dark:bg-[#032650]/50">
|
||||
<div className="mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold text-slate-600 dark:text-[#c5cfe0]">
|
||||
<FileText className="size-3.5 text-primary" />
|
||||
阶段产物
|
||||
@@ -572,7 +572,7 @@ export function PositionBuiltinAgentChat({
|
||||
|
||||
{boundThreadId ? (
|
||||
<MessageList
|
||||
className="min-h-0 flex-1"
|
||||
className="position-roundtable-agent-message-list min-h-0 flex-1"
|
||||
threadId={boundThreadId}
|
||||
thread={thread}
|
||||
paddingBottom={24}
|
||||
@@ -613,7 +613,7 @@ export function PositionBuiltinAgentChat({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="shrink-0 border-t border-slate-100 px-4 py-3 dark:border-[#2b8ffe]/20">
|
||||
<div className="position-roundtable-agent-composer-bar shrink-0 border-t border-slate-100 px-4 py-3 dark:border-[#2b8ffe]/20">
|
||||
<PositionAgentInput
|
||||
className="w-full"
|
||||
isNewThread={!boundThreadId}
|
||||
|
||||
@@ -71,10 +71,10 @@ export function PositionIntentInput({
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
return (
|
||||
<div className="position-roundtable-intent-input shrink-0 border-t border-slate-200 bg-[#f7faff] px-4 py-3 dark:border-[#2b8ffe]/35 dark:bg-[#071a38]">
|
||||
<div className="relative overflow-hidden rounded-[4px] border border-slate-300 bg-white shadow-[0_2px_10px_rgba(15,23,42,0.08)] transition-all focus-within:border-primary focus-within:ring-2 focus-within:ring-[var(--brand-200)]/45 dark:border-[#2b8ffe]/55 dark:bg-[#0d2855] dark:shadow-none dark:focus-within:border-[#56baff] dark:focus-within:ring-[#2b8ffe]/25">
|
||||
<div className="position-roundtable-intent-input position-roundtable-intent-composer shrink-0 border-t border-slate-200 bg-[#f7faff] px-4 py-3 dark:border-[#2b8ffe]/35 dark:bg-[#071a38]">
|
||||
<div className="position-roundtable-intent-composer-frame relative overflow-hidden rounded-[4px] border border-slate-300 bg-white shadow-[0_2px_10px_rgba(15,23,42,0.08)] transition-all focus-within:border-primary focus-within:ring-2 focus-within:ring-[var(--brand-200)]/45 dark:border-[#2b8ffe]/55 dark:bg-[#0d2855] dark:shadow-none dark:focus-within:border-[#56baff] dark:focus-within:ring-[#2b8ffe]/25">
|
||||
{attachedFiles.length > 0 && (
|
||||
<div className="mx-3 mb-2 flex flex-wrap gap-1.5 border-b border-slate-100 pb-2 pt-2.5 dark:border-[#2b8ffe]/25">
|
||||
<div className="position-roundtable-intent-attachments mx-3 mb-2 flex flex-wrap gap-1.5 border-b border-slate-100 pb-2 pt-2.5 dark:border-[#2b8ffe]/25">
|
||||
{attachedFiles.map((file, index) => (
|
||||
<span
|
||||
key={`${file.name}-${file.size}-${index}`}
|
||||
@@ -113,7 +113,7 @@ export function PositionIntentInput({
|
||||
? "也可在此输入自定义回答(Enter 发送 / Shift+Enter 换行)"
|
||||
: "请输入补充信息 / 回答问题 / 继续澄清(Enter 发送 / Shift+Enter 换行)"
|
||||
}
|
||||
className="min-h-[74px] w-full max-h-80 bg-transparent px-3 py-2.5 text-sm font-normal leading-relaxed text-slate-700 placeholder:text-slate-400 focus:outline-none dark:text-[#e7f0ff] dark:placeholder:text-[#7e9bc5]"
|
||||
className="position-roundtable-intent-textarea min-h-[74px] w-full max-h-80 bg-transparent px-3 py-2.5 text-sm font-normal leading-relaxed text-slate-700 placeholder:text-slate-400 focus:outline-none dark:text-[#e7f0ff] dark:placeholder:text-[#7e9bc5]"
|
||||
maxHeight={320}
|
||||
maxLength={500}
|
||||
/>
|
||||
@@ -154,7 +154,7 @@ export function PositionIntentInput({
|
||||
Parent pages can still hide optional actions by their stable ids
|
||||
without changing this component's layout or global input styles.
|
||||
*/}
|
||||
<div className="flex flex-wrap items-center gap-3 border-t border-slate-100 bg-white px-3 py-2.5 dark:border-[#2b8ffe]/25 dark:bg-[#0b234c]">
|
||||
<div className="position-roundtable-intent-toolbar flex flex-wrap items-center gap-3 border-t border-slate-100 bg-white px-3 py-2.5 dark:border-[#2b8ffe]/25 dark:bg-[#0b234c]">
|
||||
<div className="flex shrink-0 items-center">
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
@@ -171,15 +171,15 @@ export function PositionIntentInput({
|
||||
onClick={() => fileInputRef.current?.click()}
|
||||
title="上传参考文件"
|
||||
aria-label="上传参考文件"
|
||||
className="flex size-10 items-center justify-center rounded-[4px] border border-slate-200 bg-white text-slate-500 transition hover:border-primary/45 hover:text-primary dark:border-[#2b8ffe]/35 dark:bg-[#102f63] dark:text-[#b9d3f7] dark:hover:bg-[#1a417b] dark:hover:text-[#73c8ff]"
|
||||
className="position-roundtable-intent-upload-btn flex size-10 items-center justify-center rounded-[4px] border border-slate-200 bg-white text-slate-500 transition hover:border-primary/45 hover:text-primary dark:border-[#2b8ffe]/35 dark:bg-[#102f63] dark:text-[#b9d3f7] dark:hover:bg-[#1a417b] dark:hover:text-[#73c8ff]"
|
||||
>
|
||||
<Paperclip className="size-4" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="ml-auto flex min-w-0 flex-wrap items-center justify-end gap-1.5">
|
||||
<div className="position-roundtable-intent-actions ml-auto flex min-w-0 flex-wrap items-center justify-end gap-1.5">
|
||||
{modelOptions.length > 0 && (
|
||||
<div
|
||||
className="flex h-10 shrink-0 items-center gap-1.5 rounded-[4px] border border-slate-200 bg-white pl-2 text-xs font-bold text-slate-700 shadow-sm dark:border-[#2b8ffe]/35 dark:bg-[#102f63] dark:text-[#b9d3f7]"
|
||||
className="position-roundtable-intent-model-switch flex h-10 shrink-0 items-center gap-1.5 rounded-[4px] border border-slate-200 bg-white pl-2 text-xs font-bold text-slate-700 shadow-sm dark:border-[#2b8ffe]/35 dark:bg-[#102f63] dark:text-[#b9d3f7]"
|
||||
title="切换意图理解模型"
|
||||
>
|
||||
<Sparkles className="size-3.5 shrink-0 text-primary dark:text-[#73c8ff]" />
|
||||
@@ -200,7 +200,7 @@ export function PositionIntentInput({
|
||||
type="button"
|
||||
onClick={onSend}
|
||||
disabled={!canSend}
|
||||
className="flex h-10 shrink-0 items-center gap-1.5 rounded-[4px] bg-primary px-3 text-xs font-bold text-white shadow-[0_2px_8px_rgba(245,34,45,0.15)] transition-all active:scale-[0.98] hover:bg-[var(--brand-900)] disabled:cursor-not-allowed disabled:bg-slate-300 dark:bg-[#1478e8] dark:hover:bg-[#2995ff] dark:disabled:bg-[#28476f]"
|
||||
className="position-roundtable-intent-send-btn flex h-10 shrink-0 items-center gap-1.5 rounded-[4px] bg-primary px-3 text-xs font-bold text-white shadow-[0_2px_8px_rgba(245,34,45,0.15)] transition-all active:scale-[0.98] hover:bg-[var(--brand-900)] disabled:cursor-not-allowed disabled:bg-slate-300 dark:bg-[#1478e8] dark:hover:bg-[#2995ff] dark:disabled:bg-[#28476f]"
|
||||
>
|
||||
{isSending ? <Loader2 className="size-3 animate-spin" /> : <Send className="size-3" />}
|
||||
{isSending ? "发送中" : "发送"}
|
||||
|
||||
@@ -570,12 +570,12 @@ export function PositionNodeChat({
|
||||
|
||||
return (
|
||||
<ThreadContext.Provider value={threadContextValue}>
|
||||
<div className="flex min-h-0 flex-1 flex-col">
|
||||
<header className="flex min-h-12 shrink-0 items-center gap-2 border-b border-slate-100 px-4 py-2 dark:border-[#2b8ffe]/20">
|
||||
<span className="flex size-7 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
||||
<div className="position-roundtable-agent-analysis-page position-roundtable-node-chat flex min-h-0 flex-1 flex-col">
|
||||
<header className="position-roundtable-agent-header flex min-h-12 shrink-0 items-center gap-2 border-b border-slate-100 px-4 py-2 dark:border-[#2b8ffe]/20">
|
||||
<span className="position-roundtable-agent-avatar flex size-7 items-center justify-center rounded-lg bg-primary/10 text-primary">
|
||||
{node.status === "locked" ? <LockKeyhole className="size-3.5" /> : <Bot className="size-4" />}
|
||||
</span>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="position-roundtable-agent-title min-w-0 flex-1">
|
||||
<h2 className="truncate text-sm font-extrabold text-slate-900 dark:text-[#e8edf5]">
|
||||
{agentDisplayName}
|
||||
</h2>
|
||||
@@ -644,7 +644,7 @@ export function PositionNodeChat({
|
||||
</header>
|
||||
|
||||
{nodeArtifacts.length > 0 && (
|
||||
<section className="shrink-0 border-b border-slate-100 bg-slate-50/70 px-4 py-2.5 dark:border-[#2b8ffe]/20 dark:bg-[#032650]/50">
|
||||
<section className="position-roundtable-agent-artifacts shrink-0 border-b border-slate-100 bg-slate-50/70 px-4 py-2.5 dark:border-[#2b8ffe]/20 dark:bg-[#032650]/50">
|
||||
<div className="mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold text-slate-600 dark:text-[#c5cfe0]">
|
||||
<FileText className="size-3.5 text-primary" />
|
||||
节点产物
|
||||
@@ -680,7 +680,7 @@ export function PositionNodeChat({
|
||||
|
||||
{boundThreadId ? (
|
||||
<MessageList
|
||||
className="min-h-0 flex-1"
|
||||
className="position-roundtable-agent-message-list min-h-0 flex-1"
|
||||
threadId={boundThreadId}
|
||||
thread={thread}
|
||||
paddingBottom={24}
|
||||
@@ -713,7 +713,7 @@ export function PositionNodeChat({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="shrink-0 border-t border-slate-100 px-4 py-3 dark:border-[#2b8ffe]/20">
|
||||
<div className="position-roundtable-agent-composer-bar shrink-0 border-t border-slate-100 px-4 py-3 dark:border-[#2b8ffe]/20">
|
||||
<PositionAgentInput
|
||||
className="w-full"
|
||||
isNewThread={!boundThreadId}
|
||||
|
||||
@@ -75,6 +75,8 @@ import { listChains } from "@/roundtable-planning/api/chains";
|
||||
import { Step1Panel } from "@/roundtable-planning/components/Step1Panel";
|
||||
import { PositionIntentInput } from "@/position-roundtable/components/PositionIntentInput";
|
||||
import { PositionNodeChat } from "@/position-roundtable/components/PositionNodeChat";
|
||||
import "@/position-roundtable/styles/intent-understanding.css";
|
||||
import "@/position-roundtable/styles/agent-analysis.css";
|
||||
import { getAvatar } from "@/roundtable-planning/components/Avatars";
|
||||
import { useStep1Intent, type InteractiveMessage } from "@/roundtable-planning/hooks/useStep1Intent";
|
||||
import type { IntentSummary } from "@/roundtable-planning/api/intent";
|
||||
@@ -1520,7 +1522,7 @@ export default function PositionRoundtablePage({
|
||||
[closeSandbox, searchParamsString, setSearchParams],
|
||||
);
|
||||
const renderIntentChatPanel = (chainStarted: boolean) => (
|
||||
<div className="contents">
|
||||
<div className="position-roundtable-intent-page contents">
|
||||
{intent.intentInitError && (
|
||||
<div className="flex shrink-0 items-center justify-between gap-3 border-b border-amber-200 bg-amber-50 px-4 py-2 text-xs text-amber-800 dark:border-amber-900/60 dark:bg-amber-950/30 dark:text-amber-200">
|
||||
<span className="line-clamp-2">对话初始化失败:{intent.intentInitError}</span>
|
||||
@@ -1532,6 +1534,7 @@ export default function PositionRoundtablePage({
|
||||
{/* Step1Panel retains intent state; only the composer is replaced so this
|
||||
workspace can evolve its visual language without changing other Step 1 pages. */}
|
||||
<Step1Panel
|
||||
rootClassName="position-roundtable-intent-panel"
|
||||
headerLeftSlot={
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
<MessageSquareText className="size-4 text-primary" />
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 岗位会商 - 其他岗位智能体分析页面专属样式
|
||||
*
|
||||
* 覆盖范围:
|
||||
* - 普通业务链节点:PositionNodeChat
|
||||
* - 内置收口节点:PositionBuiltinAgentChat(方案总结 / 行动规划)
|
||||
*
|
||||
* 后续如果要调岗位智能体聊天页、产物条、输入区,优先改这个文件。
|
||||
*/
|
||||
|
||||
.position-roundtable-agent-analysis-page {
|
||||
--prt-agent-panel-bg: #ffffff;
|
||||
--prt-agent-header-bg: #ffffff;
|
||||
--prt-agent-header-border: rgb(241 245 249);
|
||||
--prt-agent-artifact-bg: rgba(248, 250, 252, 0.72);
|
||||
--prt-agent-composer-bg: #ffffff;
|
||||
--prt-agent-border: rgb(241 245 249);
|
||||
--prt-agent-title-color: rgb(15 23 42);
|
||||
--prt-agent-muted-color: rgb(100 116 139);
|
||||
--prt-agent-avatar-bg: rgba(245, 34, 45, 0.1);
|
||||
--prt-agent-avatar-color: var(--primary);
|
||||
}
|
||||
|
||||
.dark .position-roundtable-agent-analysis-page {
|
||||
--prt-agent-panel-bg: rgba(3, 38, 80, 0.62);
|
||||
--prt-agent-header-bg: rgba(3, 38, 80, 0.74);
|
||||
--prt-agent-header-border: rgba(43, 143, 254, 0.2);
|
||||
--prt-agent-artifact-bg: rgba(3, 38, 80, 0.5);
|
||||
--prt-agent-composer-bg: rgba(3, 38, 80, 0.64);
|
||||
--prt-agent-border: rgba(43, 143, 254, 0.2);
|
||||
--prt-agent-title-color: #e8edf5;
|
||||
--prt-agent-muted-color: #8aa0c4;
|
||||
--prt-agent-avatar-bg: rgba(43, 143, 254, 0.16);
|
||||
--prt-agent-avatar-color: #73c8ff;
|
||||
}
|
||||
|
||||
.position-roundtable-agent-analysis-page {
|
||||
background: var(--prt-agent-panel-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-header {
|
||||
border-color: var(--prt-agent-header-border);
|
||||
background: var(--prt-agent-header-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-avatar {
|
||||
background: var(--prt-agent-avatar-bg);
|
||||
color: var(--prt-agent-avatar-color);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-title h2 {
|
||||
color: var(--prt-agent-title-color);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-title p {
|
||||
color: var(--prt-agent-muted-color);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-artifacts {
|
||||
border-color: var(--prt-agent-border);
|
||||
background: var(--prt-agent-artifact-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-message-list {
|
||||
background: var(--prt-agent-panel-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-composer-bar {
|
||||
border-color: var(--prt-agent-border);
|
||||
background: var(--prt-agent-composer-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-agent-input {
|
||||
--prt-agent-input-radius: 14px;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 岗位会商 - 意图理解页面专属样式
|
||||
*
|
||||
* 这个文件只服务 `PositionRoundtablePage` 里的意图理解区域。
|
||||
* 后续手写样式优先改这里,尽量不要再往 globals.css 或组件 className 里堆。
|
||||
*/
|
||||
|
||||
.position-roundtable-intent-page {
|
||||
--prt-intent-panel-bg: #ffffff;
|
||||
--prt-intent-panel-border: rgb(226 232 240);
|
||||
--prt-intent-composer-bg: #f7faff;
|
||||
--prt-intent-composer-frame-bg: #ffffff;
|
||||
--prt-intent-composer-border: rgb(203 213 225);
|
||||
--prt-intent-toolbar-bg: #ffffff;
|
||||
--prt-intent-text-color: rgb(51 65 85);
|
||||
--prt-intent-muted-color: rgb(100 116 139);
|
||||
--prt-intent-radius: 4px;
|
||||
}
|
||||
|
||||
.dark .position-roundtable-intent-page {
|
||||
--prt-intent-panel-bg: rgba(3, 38, 80, 0.72);
|
||||
--prt-intent-panel-border: rgba(43, 143, 254, 0.28);
|
||||
--prt-intent-composer-bg: #071a38;
|
||||
--prt-intent-composer-frame-bg: #0d2855;
|
||||
--prt-intent-composer-border: rgba(43, 143, 254, 0.55);
|
||||
--prt-intent-toolbar-bg: #0b234c;
|
||||
--prt-intent-text-color: #e7f0ff;
|
||||
--prt-intent-muted-color: #8aa0c4;
|
||||
}
|
||||
|
||||
.position-roundtable-intent-panel {
|
||||
background: var(--prt-intent-panel-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-panel > div:first-child {
|
||||
border-color: var(--prt-intent-panel-border);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-panel > div:nth-child(2) > div:first-child {
|
||||
background: var(--prt-intent-panel-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-composer {
|
||||
background: var(--prt-intent-composer-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-composer-frame {
|
||||
border-color: var(--prt-intent-composer-border);
|
||||
border-radius: var(--prt-intent-radius);
|
||||
background: var(--prt-intent-composer-frame-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-textarea {
|
||||
color: var(--prt-intent-text-color);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-toolbar {
|
||||
background: var(--prt-intent-toolbar-bg);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-attachments {
|
||||
color: var(--prt-intent-muted-color);
|
||||
}
|
||||
|
||||
.position-roundtable-intent-actions {
|
||||
row-gap: 6px;
|
||||
}
|
||||
|
||||
.position-roundtable-intent-model-switch {
|
||||
border-radius: var(--prt-intent-radius);
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ export interface Step1InputAreaProps {
|
||||
}
|
||||
|
||||
export interface Step1PanelProps {
|
||||
rootClassName?: string;
|
||||
// ─── State ────────────────────────────────────────────────────
|
||||
/**
|
||||
* 头部左侧自定义内容(深链 taskId 模式:用「策划流程」小图取代默认标题)。
|
||||
@@ -141,6 +142,7 @@ export function Step1Panel(props: Step1PanelProps) {
|
||||
const {
|
||||
headerLeftSlot,
|
||||
headerRightSlot,
|
||||
rootClassName,
|
||||
interactiveMessages,
|
||||
intentThreadId,
|
||||
intentReady,
|
||||
@@ -210,7 +212,7 @@ export function Step1Panel(props: Step1PanelProps) {
|
||||
const headerDzRef = useDesensitizeSubtree<HTMLDivElement>();
|
||||
|
||||
return (
|
||||
<div className="flex-1 flex flex-col min-h-0">
|
||||
<div className={`flex-1 flex flex-col min-h-0 ${rootClassName ?? ""}`}>
|
||||
{/* Dialogue Header */}
|
||||
<div ref={headerDzRef} className="shrink-0 px-6 py-4.5 border-b border-slate-100 flex items-center justify-between gap-3 bg-slate-50/50">
|
||||
{headerLeftSlot ?? (
|
||||
|
||||
Reference in new issue
Block a user