This commit is contained in:
2026-04-22 23:44:57 +08:00
parent 76ac9d22a5
commit 84dc92646a
484 changed files with 9598 additions and 9135 deletions

View File

@@ -3,7 +3,10 @@
import { render, screen } from '@testing-library/react';
import { afterEach, expect, test, vi } from 'vitest';
import { type CreationAgentTheme,CreationAgentWorkspace } from './CreationAgentWorkspace';
import {
type CreationAgentTheme,
CreationAgentWorkspace,
} from './CreationAgentWorkspace';
const testTheme: CreationAgentTheme = {
accentTextClass: 'text-emerald-100',
@@ -110,3 +113,95 @@ test('creation agent workspace renders streaming assistant text', () => {
expect(screen.getByText(//u)).toBeTruthy();
});
test('creation agent workspace hides anchors and primary action before completed progress', () => {
if (!Element.prototype.scrollIntoView) {
Element.prototype.scrollIntoView = () => {};
}
render(
<CreationAgentWorkspace
session={{
sessionId: 'creation-agent-session-1',
title: '统一共创',
currentTurn: 2,
progressPercent: 99,
anchors: [
{
key: 'worldPromise',
label: '世界承诺',
value: '一个被潮雾改写航线秩序的群岛世界。',
status: 'confirmed',
},
],
messages: [
{
id: 'message-1',
role: 'assistant',
kind: 'chat',
text: '我们继续把设定收住。',
},
],
}}
theme={testTheme}
loadingText="正在准备"
composerPlaceholder="输入消息"
primaryActionLabel="生成结果页"
onBack={() => {}}
onSubmitText={() => {}}
onPrimaryAction={() => {}}
/>,
);
expect(screen.queryByRole('button', { name: '生成结果页' })).toBeNull();
expect(screen.queryByText('世界承诺')).toBeNull();
expect(screen.queryByText('一个被潮雾改写航线秩序的群岛世界。')).toBeNull();
});
test('creation agent workspace shows primary and progress actions at completed progress', () => {
if (!Element.prototype.scrollIntoView) {
Element.prototype.scrollIntoView = () => {};
}
render(
<CreationAgentWorkspace
session={{
sessionId: 'creation-agent-session-1',
title: '统一共创',
currentTurn: 2,
progressPercent: 100,
anchors: [],
messages: [
{
id: 'message-1',
role: 'assistant',
kind: 'chat',
text: '设定已经可以进入生成。',
},
],
}}
theme={testTheme}
loadingText="正在准备"
composerPlaceholder="输入消息"
primaryActionLabel="生成结果页"
quickActions={[
{
key: 'summarize',
label: '总结当前设定',
},
{
key: 'quickFill',
label: '补全剩余设定',
minTurn: 2,
},
]}
onBack={() => {}}
onSubmitText={() => {}}
onPrimaryAction={() => {}}
/>,
);
expect(screen.getByRole('button', { name: '生成结果页' })).toBeTruthy();
expect(screen.getByRole('button', { name: '总结当前设定' })).toBeTruthy();
expect(screen.getByRole('button', { name: '补全剩余设定' })).toBeTruthy();
});

View File

@@ -5,7 +5,6 @@ import {
type CreationAgentProgressCopy,
normalizeCreationAgentProgress,
resolveCreationAgentProgressHint,
resolveCreationAnchorStatusLabel,
} from '../../services/creation-agent';
export type CreationAgentAnchorView = {
@@ -209,32 +208,6 @@ function CreationAgentMessageBubble({
);
}
function CreationAgentAnchorChip({
anchor,
theme,
}: {
anchor: CreationAgentAnchorView;
theme: CreationAgentTheme;
}) {
return (
<div className="rounded-[1.25rem] border border-white/14 bg-white/8 px-3 py-3 text-left">
<div className="flex items-center justify-between gap-2">
<span
className={`text-xs font-semibold tracking-[0.18em] ${theme.accentTextClass}`}
>
{anchor.label}
</span>
<span className="rounded-full bg-white/12 px-2 py-1 text-[0.68rem] text-white/70">
{resolveCreationAnchorStatusLabel(anchor.status)}
</span>
</div>
<div className="mt-2 line-clamp-2 text-sm leading-5 text-white/86">
{anchor.value || '等待补齐'}
</div>
</div>
);
}
function shouldShowQuickAction(
action: CreationAgentQuickAction,
session: CreationAgentSessionView,
@@ -244,10 +217,6 @@ function shouldShowQuickAction(
return false;
}
if (!action.showWhenComplete && progress >= 100 && action.minProgress !== 100) {
return false;
}
if (typeof action.minTurn === 'number' && session.currentTurn < action.minTurn) {
return false;
}
@@ -298,6 +267,7 @@ export function CreationAgentWorkspace({
}
const progress = normalizeCreationAgentProgress(session.progressPercent);
const canShowPrimaryAction = progress >= 100;
const visibleQuickActions = quickActions.filter((action) =>
shouldShowQuickAction(action, session, progress),
);
@@ -330,15 +300,17 @@ export function CreationAgentWorkspace({
>
<ArrowLeft className="h-4 w-4" />
</button>
<button
type="button"
disabled={isBusy}
onClick={onPrimaryAction}
className={`inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-bold text-slate-950 shadow-lg disabled:cursor-not-allowed disabled:opacity-50 ${theme.accentButtonClass}`}
>
<Sparkles className="h-4 w-4" />
{primaryActionLabel}
</button>
{canShowPrimaryAction ? (
<button
type="button"
disabled={isBusy}
onClick={onPrimaryAction}
className={`inline-flex items-center gap-2 rounded-full px-4 py-2 text-sm font-bold text-slate-950 shadow-lg disabled:cursor-not-allowed disabled:opacity-50 ${theme.accentButtonClass}`}
>
<Sparkles className="h-4 w-4" />
{primaryActionLabel}
</button>
) : null}
</div>
<div className="mt-6">
@@ -389,18 +361,6 @@ export function CreationAgentWorkspace({
) : null}
</div>
{session.anchors.length > 0 ? (
<div className={theme.anchorGridClass || 'grid gap-2 sm:grid-cols-2 xl:grid-cols-4'}>
{session.anchors.map((anchor) => (
<CreationAgentAnchorChip
key={anchor.key}
anchor={anchor}
theme={theme}
/>
))}
</div>
) : null}
<CreationAgentOperationBanner operation={activeOperation} />
<div className="min-h-0 flex-1 overflow-hidden rounded-[1.6rem] border border-[var(--platform-subpanel-border)] bg-[var(--platform-subpanel-fill)]">