diff --git a/MosaicIQ/src/components/Panels/FilingsPanel.test.tsx b/MosaicIQ/src/components/Panels/FilingsPanel.test.tsx index 630879a..8681f9e 100644 --- a/MosaicIQ/src/components/Panels/FilingsPanel.test.tsx +++ b/MosaicIQ/src/components/Panels/FilingsPanel.test.tsx @@ -2,6 +2,7 @@ import { describe, expect, it } from 'bun:test'; import { renderToStaticMarkup } from 'react-dom/server'; import { buildFilingsCommand, + buildFilingsFormTypeCommand, buildFilingsPageSizeCommand, buildFilingsPaginationCommand, buildFilingsSearchCommand, @@ -94,4 +95,56 @@ describe('FilingsPanel', () => { '/filings AAPL', ); }); + + it('builds form type filter commands', () => { + expect(buildFilingsFormTypeCommand(samplePanel, '10-K')).toBe( + '/filings AAPL --page-size 50 --query 10-K', + ); + expect(buildFilingsFormTypeCommand(samplePanel, null)).toBe( + '/filings AAPL --page-size 50', + ); + }); + + it('renders form type filter chips', () => { + const html = renderToStaticMarkup(); + expect(html).toContain('10-K'); + expect(html).toContain('10-Q'); + expect(html).toContain('8-K'); + }); + + it('renders form type filter chips for panel without query', () => { + const noQueryPanel: FilingsPanelData = { + ...samplePanel, + query: undefined, + page: 1, + pageSize: 25, + }; + const html = renderToStaticMarkup(); + expect(html).toContain('10-K'); + expect(html).toContain('10-Q'); + expect(html).toContain('8-K'); + }); + + it('handles form type override in buildFilingsCommand', () => { + expect( + buildFilingsCommand({ + symbol: 'AAPL', + page: 1, + pageSize: 25, + formType: '8-K', + }), + ).toBe('/filings AAPL --query 8-K'); + }); + + it('prefers formType over query when both are present', () => { + expect( + buildFilingsCommand({ + symbol: 'AAPL', + page: 1, + pageSize: 25, + query: 'annual', + formType: '10-Q', + }), + ).toBe('/filings AAPL --query 10-Q'); + }); }); diff --git a/MosaicIQ/src/components/Panels/FilingsPanel.tsx b/MosaicIQ/src/components/Panels/FilingsPanel.tsx index e516560..421285c 100644 --- a/MosaicIQ/src/components/Panels/FilingsPanel.tsx +++ b/MosaicIQ/src/components/Panels/FilingsPanel.tsx @@ -1,6 +1,12 @@ import React from 'react'; import { openUrl } from '@tauri-apps/plugin-opener'; import type { FilingsPanelData } from '../../types/financial'; +import { + COMMON_FORM_TYPE_OPTIONS, + type CommonFormType, + isCommonFormType, + toggleFilingTypeFilter, +} from '../../lib/searchQuery'; const DEFAULT_PAGE = 1; const DEFAULT_PAGE_SIZE = 25; @@ -11,6 +17,7 @@ export interface FilingsCommandState { page: number; pageSize: number; query?: string; + formType?: CommonFormType; } interface FilingsPanelProps { @@ -32,9 +39,10 @@ export const buildFilingsCommand = ({ page, pageSize, query, + formType, }: FilingsCommandState) => { const normalizedSymbol = symbol.trim().toUpperCase(); - const normalizedQuery = query?.trim(); + const normalizedQuery = formType ?? query?.trim(); const tokens = ['/filings', normalizedSymbol]; if (page > DEFAULT_PAGE) { @@ -85,15 +93,28 @@ export const buildFilingsSearchCommand = ( query, }); +export const buildFilingsFormTypeCommand = ( + data: FilingsPanelData, + formType: CommonFormType | null, +) => + buildFilingsCommand({ + symbol: data.symbol, + page: DEFAULT_PAGE, + pageSize: data.pageSize, + formType: formType ?? undefined, + }); + export const FilingsPanel: React.FC = ({ data, onRunCommand, }) => { const [queryDraft, setQueryDraft] = React.useState(data.query ?? ''); - const normalizedCurrentQuery = data.query?.trim() ?? ''; + const activeFormType = isCommonFormType(data.query ?? '') ? (data.query as CommonFormType) : null; + const normalizedCurrentQuery = activeFormType ? '' : (data.query?.trim() ?? ''); React.useEffect(() => { - setQueryDraft(data.query ?? ''); + const next = data.query ?? ''; + setQueryDraft(isCommonFormType(next) ? '' : next); }, [data.query, data.symbol]); const runCommand = React.useCallback( @@ -141,6 +162,14 @@ export const FilingsPanel: React.FC = ({ runCommand(buildFilingsSearchCommand(data, undefined)); }, [data, normalizedCurrentQuery, queryDraft, runCommand]); + const toggleFormType = React.useCallback( + (formType: CommonFormType) => { + const next = toggleFilingTypeFilter(activeFormType, formType); + runCommand(buildFilingsFormTypeCommand(data, next)); + }, + [activeFormType, data, runCommand], + ); + return (
@@ -167,6 +196,23 @@ export const FilingsPanel: React.FC = ({
+
+ {COMMON_FORM_TYPE_OPTIONS.map((formType) => ( + + ))} +
+