This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { beforeEach, expect, test, vi } from 'vitest';
|
||||
|
||||
import type { BigFishSessionSnapshotResponse } from '../../../packages/shared/src/contracts/bigFish';
|
||||
import { BigFishAgentWorkspace } from './BigFishAgentWorkspace';
|
||||
|
||||
const baseSession: BigFishSessionSnapshotResponse = {
|
||||
sessionId: 'big-fish-session-1',
|
||||
currentTurn: 3,
|
||||
progressPercent: 64,
|
||||
stage: 'collecting_anchors',
|
||||
anchorPack: {
|
||||
gameplayPromise: {
|
||||
key: 'gameplayPromise',
|
||||
label: '玩法承诺',
|
||||
value: '从微光小鱼一路吞噬成长为深海巨兽',
|
||||
status: 'confirmed',
|
||||
},
|
||||
ecologyVisualTheme: {
|
||||
key: 'ecologyVisualTheme',
|
||||
label: '生态视觉主题',
|
||||
value: '幽蓝珊瑚海沟',
|
||||
status: 'confirmed',
|
||||
},
|
||||
growthLadder: {
|
||||
key: 'growthLadder',
|
||||
label: '成长阶梯',
|
||||
value: '',
|
||||
status: 'missing',
|
||||
},
|
||||
riskTempo: {
|
||||
key: 'riskTempo',
|
||||
label: '风险节奏',
|
||||
value: '',
|
||||
status: 'missing',
|
||||
},
|
||||
},
|
||||
draft: null,
|
||||
assetSlots: [],
|
||||
assetCoverage: {
|
||||
levelMainImageReadyCount: 0,
|
||||
levelMotionReadyCount: 0,
|
||||
backgroundReady: false,
|
||||
requiredLevelCount: 8,
|
||||
publishReady: false,
|
||||
blockers: [],
|
||||
},
|
||||
messages: [
|
||||
{
|
||||
id: 'message-1',
|
||||
role: 'assistant',
|
||||
kind: 'chat',
|
||||
text: '爽点和生态已经清楚,继续补剩余关键词。',
|
||||
createdAt: '2026-04-24T10:00:00.000Z',
|
||||
},
|
||||
],
|
||||
lastAssistantReply: '爽点和生态已经清楚,继续补剩余关键词。',
|
||||
publishReady: false,
|
||||
updatedAt: '2026-04-24T10:00:00.000Z',
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
if (!Element.prototype.scrollIntoView) {
|
||||
Element.prototype.scrollIntoView = () => {};
|
||||
}
|
||||
});
|
||||
|
||||
test('big fish workspace submits quick keyword fill request after two turns', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onSubmitMessage = vi.fn();
|
||||
|
||||
render(
|
||||
<BigFishAgentWorkspace
|
||||
session={baseSession}
|
||||
onBack={() => {}}
|
||||
onSubmitMessage={onSubmitMessage}
|
||||
onExecuteAction={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: '补充剩余设定' }));
|
||||
|
||||
expect(onSubmitMessage).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
text: '请补充剩余设定。',
|
||||
quickFillRequested: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
test('big fish workspace hides keyword fill before two turns', () => {
|
||||
render(
|
||||
<BigFishAgentWorkspace
|
||||
session={{ ...baseSession, currentTurn: 1 }}
|
||||
onBack={() => {}}
|
||||
onSubmitMessage={() => {}}
|
||||
onExecuteAction={() => {}}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.queryByRole('button', { name: '补充剩余设定' })).toBeNull();
|
||||
});
|
||||
123
src/components/big-fish-creation/BigFishAgentWorkspace.tsx
Normal file
123
src/components/big-fish-creation/BigFishAgentWorkspace.tsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import type {
|
||||
BigFishAnchorItemResponse,
|
||||
BigFishSessionSnapshotResponse,
|
||||
ExecuteBigFishActionRequest,
|
||||
SendBigFishMessageRequest,
|
||||
} from '../../../packages/shared/src/contracts/bigFish';
|
||||
import {
|
||||
buildCreationAgentChatMessage,
|
||||
createCreationAgentChatQuickActions,
|
||||
createCreationAgentClientMessageId,
|
||||
resolveCreationAgentQuickActionMessage,
|
||||
} from '../../services/creation-agent';
|
||||
import {
|
||||
type CreationAgentAnchorView,
|
||||
type CreationAgentSessionView,
|
||||
type CreationAgentTheme,
|
||||
CreationAgentWorkspace,
|
||||
} from '../creation-agent';
|
||||
|
||||
type BigFishAgentWorkspaceProps = {
|
||||
session: BigFishSessionSnapshotResponse | null;
|
||||
streamingReplyText?: string;
|
||||
isStreamingReply?: boolean;
|
||||
isBusy?: boolean;
|
||||
error?: string | null;
|
||||
onBack: () => void;
|
||||
onSubmitMessage: (payload: SendBigFishMessageRequest) => void;
|
||||
onExecuteAction: (payload: ExecuteBigFishActionRequest) => void;
|
||||
};
|
||||
|
||||
const BIG_FISH_AGENT_THEME: CreationAgentTheme = {
|
||||
accentTextClass: 'text-cyan-100/85',
|
||||
accentBgClass: 'bg-cyan-200',
|
||||
accentButtonClass: 'bg-cyan-200 shadow-cyan-950/20',
|
||||
userBubbleClass: 'bg-cyan-600 text-white',
|
||||
heroClass:
|
||||
'border border-cyan-100/16 bg-[radial-gradient(circle_at_top_left,rgba(45,212,191,0.22),transparent_32%),linear-gradient(135deg,rgba(8,47,73,0.96),rgba(13,24,38,0.96))]',
|
||||
anchorGridClass: 'grid gap-2 sm:grid-cols-4',
|
||||
};
|
||||
|
||||
function mapBigFishAnchor(
|
||||
anchor: BigFishAnchorItemResponse,
|
||||
): CreationAgentAnchorView {
|
||||
return {
|
||||
key: anchor.key,
|
||||
label: anchor.label,
|
||||
value: anchor.value,
|
||||
status: anchor.status,
|
||||
};
|
||||
}
|
||||
|
||||
function mapBigFishSession(
|
||||
session: BigFishSessionSnapshotResponse,
|
||||
): CreationAgentSessionView {
|
||||
return {
|
||||
sessionId: session.sessionId,
|
||||
// 所有玩法的 Agent 聊天页顶部模块只保留操作与进度,不展示标题和引导副文案。
|
||||
title: null,
|
||||
assistantSummary: null,
|
||||
currentTurn: session.currentTurn,
|
||||
progressPercent: session.progressPercent,
|
||||
anchors: [
|
||||
session.anchorPack.gameplayPromise,
|
||||
session.anchorPack.ecologyVisualTheme,
|
||||
session.anchorPack.growthLadder,
|
||||
session.anchorPack.riskTempo,
|
||||
].map(mapBigFishAnchor),
|
||||
messages: session.messages,
|
||||
recommendedReplies: [],
|
||||
};
|
||||
}
|
||||
|
||||
export function BigFishAgentWorkspace({
|
||||
session,
|
||||
streamingReplyText = '',
|
||||
isStreamingReply = false,
|
||||
isBusy = false,
|
||||
error = null,
|
||||
onBack,
|
||||
onSubmitMessage,
|
||||
onExecuteAction,
|
||||
}: BigFishAgentWorkspaceProps) {
|
||||
return (
|
||||
<CreationAgentWorkspace
|
||||
session={session ? mapBigFishSession(session) : null}
|
||||
theme={BIG_FISH_AGENT_THEME}
|
||||
loadingText="正在准备大鱼吃小鱼共创工作区..."
|
||||
composerPlaceholder="说说这局的生态、成长或爽点..."
|
||||
primaryActionLabel="生成结果页"
|
||||
streamingReplyText={streamingReplyText}
|
||||
isStreamingReply={isStreamingReply}
|
||||
isBusy={isBusy}
|
||||
error={error}
|
||||
quickActions={createCreationAgentChatQuickActions()}
|
||||
onBack={onBack}
|
||||
onSubmitText={(text) => {
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('big-fish'),
|
||||
text,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
onPrimaryAction={() => {
|
||||
onExecuteAction({ action: 'big_fish_compile_draft' });
|
||||
}}
|
||||
onQuickAction={(action) => {
|
||||
const quickActionMessage = resolveCreationAgentQuickActionMessage(
|
||||
action.key,
|
||||
'请总结一下当前已经成形的大鱼吃小鱼设定。',
|
||||
);
|
||||
onSubmitMessage(
|
||||
buildCreationAgentChatMessage({
|
||||
clientMessageId: createCreationAgentClientMessageId('big-fish'),
|
||||
...quickActionMessage,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default BigFishAgentWorkspace;
|
||||
Reference in New Issue
Block a user