Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 47 additions & 43 deletions apps/dsa-web/src/pages/HomePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -479,48 +479,6 @@ const HomePage: React.FC = () => {
</div>
) : null}

{marketReviewNotice ? (
<div className="px-3 pb-2 md:px-4">
<InlineAlert
variant={marketReviewNotice.variant}
title={marketReviewNotice.title}
message={marketReviewNotice.message}
className="rounded-xl px-3 py-2 text-xs shadow-none"
/>
</div>
) : null}

{marketReviewError ? (
<div className="px-3 pb-2 md:px-4">
<ApiErrorAlert
error={marketReviewError}
className="mb-1"
onDismiss={() => setMarketReviewError(null)}
/>
</div>
) : null}

{marketReviewReport ? (
<div className="px-3 pb-2 md:px-4">
<div className="rounded-xl border border-subtle bg-surface/70 px-3 py-3 text-xs text-secondary-text shadow-sm">
<div className="mb-2 flex items-center justify-between gap-2">
<p className="font-semibold text-foreground">大盘复盘报告</p>
<button
type="button"
className="home-surface-button h-7 rounded-md px-3 py-1 text-xs text-foreground"
disabled={marketReviewReportCopied}
onClick={() => void handleCopyMarketReviewReport()}
>
{marketReviewReportCopied ? '已复制' : '复制'}
</button>
</div>
<pre className="max-h-64 overflow-x-auto overflow-y-auto whitespace-pre-wrap break-words rounded-lg bg-background px-3 py-2 leading-relaxed">
{marketReviewReport}
</pre>
</div>
</div>
) : null}

<div className="flex-1 flex min-h-0 overflow-hidden">
<div className="hidden min-h-0 w-64 shrink-0 flex-col overflow-hidden pl-4 pb-4 md:flex lg:w-72">
{sidebarContent}
Expand All @@ -538,7 +496,53 @@ const HomePage: React.FC = () => {
</div>
) : null}

<section className="flex-1 min-w-0 min-h-0 overflow-x-auto overflow-y-auto px-3 pb-4 md:px-6 touch-pan-y">
<section
data-testid="home-dashboard-scroll"
className="flex-1 min-w-0 min-h-0 overflow-x-auto overflow-y-auto px-3 pb-4 md:px-6 touch-pan-y"
>
{marketReviewNotice ? (
<div className="mb-3">
<InlineAlert
variant={marketReviewNotice.variant}
title={marketReviewNotice.title}
message={marketReviewNotice.message}
className="rounded-xl px-3 py-2 text-xs shadow-none"
/>
</div>
) : null}

{marketReviewError ? (
<div className="mb-3">
<ApiErrorAlert
error={marketReviewError}
className="mb-1"
onDismiss={() => setMarketReviewError(null)}
/>
</div>
) : null}

{marketReviewReport ? (
<div className="mb-3 rounded-xl border border-subtle bg-surface/70 px-3 py-3 text-xs text-secondary-text shadow-sm">
<div className="mb-2 flex items-center justify-between gap-2">
<p className="font-semibold text-foreground">大盘复盘报告</p>
<button
type="button"
className="home-surface-button h-7 rounded-md px-3 py-1 text-xs text-foreground"
disabled={marketReviewReportCopied}
onClick={() => void handleCopyMarketReviewReport()}
>
{marketReviewReportCopied ? '已复制' : '复制'}
</button>
</div>
<pre
data-testid="market-review-report"
className="overflow-x-auto whitespace-pre-wrap break-words rounded-lg bg-background px-3 py-2 leading-relaxed"
Comment on lines +548 to +563

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep market review feedback visible after toolbar clicks

When a user is scrolled down in the main dashboard (for example reading an existing stock report) and clicks the always-visible 大盘复盘 toolbar button, this block is inserted at the top of the same scroll container and no code resets scrollTop or scrolls the result into view. The browser will preserve the current scroll position, so the completion notice/report can appear above the viewport and the click appears to do nothing; before this change the market review feedback was outside the dashboard scroller and stayed visible below the header.

Useful? React with 👍 / 👎.

>
{marketReviewReport}
</pre>
</div>
) : null}

{error ? (
<ApiErrorAlert
error={error}
Expand Down
36 changes: 36 additions & 0 deletions apps/dsa-web/src/pages/__tests__/HomePage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ describe('HomePage', () => {
expect(dashboard.className).toContain('lg:h-[calc(100vh-2rem)]');
expect(dashboard.firstElementChild?.className).toContain('min-h-0');
expect(dashboard.querySelector('.flex-1.flex.min-h-0.overflow-hidden')).toBeTruthy();
expect(screen.getByTestId('home-dashboard-scroll')).toBeInTheDocument();
expect(screen.getByPlaceholderText('输入股票代码或名称,如 600519、贵州茅台、AAPL')).toBeInTheDocument();
expect(await screen.findByText('趋势维持强势')).toBeInTheDocument();
expect(
Expand Down Expand Up @@ -208,6 +209,41 @@ describe('HomePage', () => {
expect(analysisApi.getStatus).toHaveBeenCalledWith('task-1');
});

it('keeps market review results in the main dashboard scroll area', async () => {
vi.mocked(historyApi.getList).mockResolvedValue({
total: 0,
page: 1,
limit: 20,
items: [],
});
vi.mocked(analysisApi.triggerMarketReview).mockResolvedValue({
status: 'accepted',
sendNotification: true,
message: '大盘复盘任务已提交',
taskId: 'task-1',
});
vi.mocked(analysisApi.getStatus).mockResolvedValue({
taskId: 'task-1',
status: 'completed',
marketReviewReport: Array.from({ length: 30 }, (_, index) => `第 ${index + 1} 行复盘内容`).join('\n'),
});

render(
<MemoryRouter>
<HomePage />
</MemoryRouter>,
);

fireEvent.click(await screen.findByRole('button', { name: '大盘复盘' }));

const dashboardScroll = screen.getByTestId('home-dashboard-scroll');
const marketReviewReport = await screen.findByTestId('market-review-report');
expect(dashboardScroll).toContainElement(marketReviewReport);
expect(marketReviewReport.className).not.toContain('max-h-64');
expect(marketReviewReport.className).not.toContain('overflow-y-auto');
expect(await screen.findByText('开始分析')).toBeInTheDocument();
});

it('shows first-run setup gaps and links to settings', async () => {
vi.mocked(historyApi.getList).mockResolvedValue({
total: 0,
Expand Down
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
- [修复] Windows NSIS 自动更新在安装尝试未切换桌面端版本时跳过自动恢复,避免失败或取消安装后误回滚用户运行时数据。
- [修复] 同版本启动时清理未生效的自动更新备份目录,避免后续升级误将旧 `.dsa-desktop-update-backup/runtime-state.json` 的运行时文件再次恢复到新版本。
- [修复] 清理提交中的临时探测文件(`node_modules_exists.txt` 与 `node_modules_ls_check.txt`),避免污染桌面/前端改动范围。
- [修复] Web 首页大盘复盘结果改由主内容滚动区承载,避免 loading 切换到长结果后下方报告区域被截断或无法继续滚动。

- [新功能] Web 系统设置页开放 `.env` 配置备份导入/导出,复用键级覆盖、配置版本冲突保护和重载链路;Web 端在 `ADMIN_AUTH_ENABLED=false` 时该入口为禁用状态。
- [chore] 精简仓库根目录:将文档图片资源迁入 `docs/assets/`,将东方财富请求补丁迁入 `src/patches/`,并下移 CI 专用依赖文件与技能适配服务。
Expand Down
Loading