From e7655262acefab2c0f05545f0b8ecc9cd9e664d0 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Sat, 22 Aug 2026 17:25:12 +0800 Subject: [PATCH] fix: scope page insights to visible periods --- src/lib/api/schema.d.ts | 4 ++-- src/lib/components/AIInsightPanel.test.ts | 27 +++++++++++++++------- src/lib/components/AnalyticsPage.svelte | 9 ++++++-- src/lib/components/TransactionsPage.svelte | 11 +++++++-- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/lib/api/schema.d.ts b/src/lib/api/schema.d.ts index 34926df..822e5f4 100644 --- a/src/lib/api/schema.d.ts +++ b/src/lib/api/schema.d.ts @@ -1076,7 +1076,7 @@ export interface components { }; AIInsightRefreshRequest: { terminalId?: string; - /** @description Used only by the transactions module. */ + /** @description Server-offered reporting period used to match the visible analytics run. */ periodId?: string; }; AIInsightJob: { @@ -2469,7 +2469,7 @@ export interface operations { parameters: { query?: { terminalId?: string; - /** @description Used only by the transactions module to match the selected reporting period. */ + /** @description Server-offered reporting period used to match the visible analytics run. */ periodId?: string; }; header?: { diff --git a/src/lib/components/AIInsightPanel.test.ts b/src/lib/components/AIInsightPanel.test.ts index 8bb7522..583401e 100644 --- a/src/lib/components/AIInsightPanel.test.ts +++ b/src/lib/components/AIInsightPanel.test.ts @@ -1,6 +1,6 @@ -import { render, screen, waitFor } from '@testing-library/svelte'; +import { cleanup, render, screen, waitFor } from '@testing-library/svelte'; import { tick } from 'svelte'; -import { describe, expect, it, vi } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import type { AIInsight } from '$lib/api/client'; import AIInsightPanel from './AIInsightPanel.svelte'; @@ -57,6 +57,8 @@ const insight: AIInsight = { generatedAt: '2026-08-22T00:00:00Z', }; +afterEach(cleanup); + describe('AIInsightPanel', () => { it('leaves the skeleton after loading an insight and does not fetch it again', async () => { latestAIInsight.mockReset(); @@ -64,24 +66,33 @@ describe('AIInsightPanel', () => { render(AIInsightPanel, { module: 'overview' }); - await screen.findByText('فروش در این بازه رشد کرده است.'); + await screen.findByText('آخرین روز ثبت‌شده باثبات بوده است.'); await tick(); await waitFor(() => expect(screen.queryByLabelText('در حال دریافت تحلیل هوشمند')).toBeNull()); expect(latestAIInsight).toHaveBeenCalledTimes(1); + expect(screen.getByText('فروش در این بازه رشد کرده است.')).not.toBeNull(); + expect(screen.queryByText('روند کوتاه‌مدت باثبات پیش‌بینی می‌شود.')).toBeNull(); + expect(screen.queryByText('یافته‌ها')).toBeNull(); }); - it('loads a transaction insight with the resolved period scope', async () => { + it('loads every page insight with the resolved period scope', async () => { latestAIInsight.mockReset(); latestAIInsight.mockResolvedValueOnce({ ...insight, - module: 'transactions', + module: 'overview', scope: { terminalId: 'T83', periodId: 'period-7' }, }); - render(AIInsightPanel, { module: 'transactions', terminalId: 'T83', periodId: 'period-7' }); + render(AIInsightPanel, { + module: 'overview', + terminalId: 'T83', + periodId: 'period-7', + periodLabel: 'مرداد ۱۴۰۵', + }); - await screen.findByText('فروش در این بازه رشد کرده است.'); - expect(latestAIInsight).toHaveBeenCalledWith('transactions', 'T83', 'period-7'); + await screen.findByText('آخرین روز ثبت‌شده باثبات بوده است.'); + expect(screen.getByText('مرداد ۱۴۰۵')).not.toBeNull(); + expect(latestAIInsight).toHaveBeenCalledWith('overview', 'T83', 'period-7'); }); }); diff --git a/src/lib/components/AnalyticsPage.svelte b/src/lib/components/AnalyticsPage.svelte index d291c04..d775d53 100644 --- a/src/lib/components/AnalyticsPage.svelte +++ b/src/lib/components/AnalyticsPage.svelte @@ -120,8 +120,6 @@ - - {#if loading}
{#each Array(4) as _}{/each} @@ -140,6 +138,13 @@ {@const fees = run.sections.fees} {@const peers = run.sections.peerComparison} + + {#if kind === 'overview' && overview.state === 'READY'}
{:else if run} {@const transactions = run.sections.transactions} + {#if transactions.state === 'READY'}
روند ترکیب وضعیت‌ها

- هر خط، تغییر تعداد یک وضعیت را در طول زمان نشان می‌دهد؛ جزئیات تعداد و سهم هر نقطه با - تمرکز صفحه‌کلید یا اشاره‌گر در دسترس است. + هر خط، تغییر تعداد یک وضعیت را در طول زمان نشان می‌دهد؛ جزئیات تعداد و سهم هر نقطه با تمرکز + صفحه‌کلید یا اشاره‌گر در دسترس است.

{run.period.jalaliLabelFa}