# Broker Operations UI Improvements — Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Clean up operations table badges, add "+" for positive amounts, smooth pagination with styled buttons. **Architecture:** All changes are frontend-only (React components, TanStack Query hook, display helpers, tests). No backend changes. **Tech Stack:** React 18, TanStack Query v5, Vitest + Testing Library --- ### Task 1: Remove `getBrokerOperationImpactLabel` from brokerDisplay **Files:** - Modify: `apps/frontend/src/pages/broker/brokerDisplay.ts:165-176` - Modify: `apps/frontend/src/pages/broker/brokerDisplay.test.ts:195-201` - [ ] **Step 1: Remove the test for impact labels** In `brokerDisplay.test.ts`, delete the test block "provides Russian impact labels" (lines 195-201) and remove `getBrokerOperationImpactLabel` from the import. ```tsx // Import line changes from: import { getBrokerInstrumentPath, getBrokerOperationImpact, getBrokerOperationImpactLabel, getBrokerOperationTypeLabel, getBrokerPositionGroup, } from './brokerDisplay'; // to: import { getBrokerInstrumentPath, getBrokerOperationImpact, getBrokerOperationTypeLabel, getBrokerPositionGroup, } from './brokerDisplay'; ``` Delete the entire `it('provides Russian impact labels', ...)` block (lines 195-201). - [ ] **Step 2: Run tests to verify the test removal succeeds** Run: `npx vitest run apps/frontend/src/pages/broker/brokerDisplay.test.ts` Expected: PASS (1 less test) - [ ] **Step 3: Remove `getBrokerOperationImpactLabel` from source** In `brokerDisplay.ts`, delete the `getBrokerOperationImpactLabel` function (lines 165-176) and remove its export. - [ ] **Step 4: Run tests to verify** Run: `npx vitest run apps/frontend/src/pages/broker/brokerDisplay.test.ts` Expected: PASS - [ ] **Step 5: Commit** ```bash git add apps/frontend/src/pages/broker/brokerDisplay.ts apps/frontend/src/pages/broker/brokerDisplay.test.ts git commit -m "refactor: remove unused getBrokerOperationImpactLabel helper" ``` --- ### Task 2: Update BrokerPages.test.tsx for new expectations **Files:** - Modify: `apps/frontend/src/pages/broker/BrokerPages.test.tsx` - [ ] **Step 1: Update test to expect no badges and "+" prefix** Remove lines 314-315 (badge checks): ```tsx expect(screen.getByText('Пополняет')).toBeInTheDocument(); expect(screen.getByText('Списывает')).toBeInTheDocument(); ``` Update test name at line 225 from: ``` it('renders broker operations with Russian labels, linked instruments and impact badges', () => { ``` to: ``` it('renders broker operations with Russian labels, linked instruments and colored amounts', () => { ``` Add a check for the "+" prefix on positive amounts after the existing check at line 312-313: ```tsx expect(screen.getByText('Выплата купона')).toBeInTheDocument(); expect(screen.getByText('Налог')).toBeInTheDocument(); // Add: expect(screen.getByText(/\+120,00\s*₽/)).toBeInTheDocument(); ``` Remove the old checks for "Страница 1" and "Страница 2" text (lines 424-437) and instead verify the pagination buttons exist. Update the pagination test block at line 322: ```tsx it('requests broker operations by cursor with a page size of 10', async () => { // ...setup stays the same... // Replace these: // expect(screen.getByText('Страница 1')).toBeInTheDocument(); // with check that page buttons exist: const nextButton = screen.getByRole('button', { name: '→' }); const prevButton = screen.getByRole('button', { name: '←' }); expect(prevButton).toBeDisabled(); expect(nextButton).not.toBeDisabled(); await user.click(nextButton); expect(operationsSpy).toHaveBeenLastCalledWith('acc-1', { limit: 10, cursor: 'cursor-page-2', }); // expect(screen.getByText('Страница 2')).toBeInTheDocument(); // remove expect(screen.getByText('2')).toBeInTheDocument(); // page number shown without label await user.click(screen.getByRole('button', { name: '←' })); expect(operationsSpy).toHaveBeenLastCalledWith('acc-1', { limit: 10, cursor: undefined }); expect(screen.getByText('1')).toBeInTheDocument(); }); ``` - [ ] **Step 2: Run tests to verify they fail** Run: `npx vitest run apps/frontend/src/pages/broker/BrokerPages.test.tsx` Expected: FAIL (buttons named '→' / '←' not found yet, "+" text not found) - [ ] **Step 3: Commit** ```bash git add apps/frontend/src/pages/broker/BrokerPages.test.tsx git commit -m "test: update broker page tests for new UI expectations" ``` --- ### Task 3: Remove badges and add "+" prefix, style pagination buttons **Files:** - Modify: `apps/frontend/src/pages/broker/BrokerOperationsTable.tsx` - [ ] **Step 1: Remove badge-related code** In `BrokerOperationsTable.tsx`: Delete the `impactStyles` object (lines 30-47). Delete the `OperationType` component (lines 87-108). Update imports — remove `getBrokerOperationImpactLabel` and `BrokerOperationImpact`: ```tsx import { getBrokerInstrumentPath, getBrokerOperationImpact, getBrokerOperationTypeLabel, } from './brokerDisplay'; ``` Update the "Тип" column cell — replace `` with just: ```tsx {getBrokerOperationTypeLabel(operation)} ``` - [ ] **Step 2: Add "+" prefix to positive amounts** Modify `formatMoney` function: ```tsx function formatMoney(value: BrokerMoney | null | undefined) { if (!value) return '-'; const formatted = new Intl.NumberFormat('ru-RU', { style: 'currency', currency: value.currency || 'RUB', maximumFractionDigits: 2, }).format(value.value); return value.value > 0 ? `+${formatted}` : formatted; } ``` - [ ] **Step 3: Style pagination buttons** Add button style constants before the component: ```tsx const pagButtonStyle: React.CSSProperties = { padding: '6px 14px', borderRadius: 6, border: '1px solid #e0e0e0', background: 'var(--color-surface)', color: 'var(--color-text)', fontSize: 14, fontWeight: 600, cursor: 'pointer', lineHeight: 1.4, }; const pagButtonDisabledStyle: React.CSSProperties = { ...pagButtonStyle, opacity: 0.35, cursor: 'not-allowed', }; ``` Update pagination controls — replace existing "Назад" / "Вперед" buttons and "Страница N" text: ```tsx
{pageNumber}
``` - [ ] **Step 4: Run tests** Run: `npx vitest run apps/frontend/src/pages/broker/BrokerPages.test.tsx` Expected: PASS - [ ] **Step 5: Run full test suite** Run: `npm run test:frontend` Expected: PASS - [ ] **Step 6: Commit** ```bash git add apps/frontend/src/pages/broker/BrokerOperationsTable.tsx git commit -m "feat: remove impact badges, add + prefix, style pagination buttons" ``` --- ### Task 4: Add keepPreviousData to operations query **Files:** - Modify: `apps/frontend/src/hooks/useBrokerOperations.ts` - [ ] **Step 1: Add keepPreviousData** Update `useBrokerOperations.ts`: ```tsx import { keepPreviousData, useQuery } from '@tanstack/react-query'; export function useBrokerOperations( accountId: string | undefined, query: BrokerOperationQuery = {}, ) { return useQuery({ queryKey: ['broker', 'operations', accountId, query], enabled: Boolean(accountId), queryFn: async () => (await getBrokerOperations(accountId!, query)).data, placeholderData: keepPreviousData, staleTime: 300_000, retry: 2, refetchOnWindowFocus: false, }); } ``` - [ ] **Step 2: Run full test suite** Run: `npm run test:frontend` Expected: PASS - [ ] **Step 3: Commit** ```bash git add apps/frontend/src/hooks/useBrokerOperations.ts git commit -m "feat: add keepPreviousData for smooth pagination" ``` --- ### Task 5: Run lint and verify - [ ] **Step 1: Run lint** Run: `npm run lint` Expected: PASS (no lint errors) - [ ] **Step 2: Run full test suite** Run: `npm run test:frontend` Expected: PASS - [ ] **Step 3: Verify build** Run: `npm run build:frontend` Expected: PASS - [ ] **Step 4: Final commit if any fixes** ```bash git commit -m "chore: fix lint issues" ```