diff --git a/web/src/App.css b/web/src/App.css index 8dd8ac0..d703b0d 100644 --- a/web/src/App.css +++ b/web/src/App.css @@ -1,6 +1,6 @@ -.ant-select-selection-item{ - background-color: #ecfdf3 !important; - color: #1f5f35 !important; - box-shadow: inset 0 0 0 1px #2ea64b38 !important; - border-radius: 999px !important; -} \ No newline at end of file +.ant-select-selection-item { + background-color: #ecfdf3 !important; + color: #1f5f35 !important; + box-shadow: inset 0 0 0 1px #2ea64b38 !important; + border-radius: 999px !important; +} diff --git a/web/src/App.tsx b/web/src/App.tsx index 044ea1e..3d972ee 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -17,9 +17,9 @@ import { Main, Mono, } from './layouts/'; +import { ConsolidatioReportPage } from './layouts/ConsolidatioReportPage'; import { store } from './store/store'; import { Sidebar } from './widgets/Sidebar/Sidebar'; -import { ConsolidatioReportPage } from './layouts/ConsolidatioReportPage'; // Каркас: экраны по docs/context/10-user-journey.md добавляются срезами. function App() { @@ -37,7 +37,7 @@ function App() { } /> } /> - } /> + } /> } /> } /> diff --git a/web/src/api/client.ts b/web/src/api/client.ts index 5966bd4..b916f1f 100644 --- a/web/src/api/client.ts +++ b/web/src/api/client.ts @@ -129,13 +129,13 @@ export async function apiFetch(path: string, init: RequestInit = {}): Promise /** Бинарный ответ (скан, xlsx) с токеном и тем же разбором ошибок; имя — из Content-Disposition, если доступно. */ export async function apiFetchBlob( path: string, - init: RequestInit = {} // Добавили init + init: RequestInit = {}, // Добавили init ): Promise<{ blob: Blob; filename: string | null }> { - const response = await send(path, init); + const response = await send(path, init); const blob = await response.blob(); - return { - blob, - filename: filenameFromContentDisposition(response.headers.get('Content-Disposition')) + return { + blob, + filename: filenameFromContentDisposition(response.headers.get('Content-Disposition')), }; } diff --git a/web/src/components/TreeFilterDropdown/TreeFilterDropdown.css b/web/src/components/TreeFilterDropdown/TreeFilterDropdown.css index b71b9a1..8f0c3e4 100644 --- a/web/src/components/TreeFilterDropdown/TreeFilterDropdown.css +++ b/web/src/components/TreeFilterDropdown/TreeFilterDropdown.css @@ -1,3 +1,3 @@ -.ant-tree-switcher-noop{ - display: none !important; -} \ No newline at end of file +.ant-tree-switcher-noop { + display: none !important; +} diff --git a/web/src/components/TreeFilterDropdown/TreeFilterDropdown.tsx b/web/src/components/TreeFilterDropdown/TreeFilterDropdown.tsx index 7bdf118..b33a829 100644 --- a/web/src/components/TreeFilterDropdown/TreeFilterDropdown.tsx +++ b/web/src/components/TreeFilterDropdown/TreeFilterDropdown.tsx @@ -1,12 +1,12 @@ -import { useState, useMemo, useEffect } from 'react'; -import { Input, Button, Tree, Space } from 'antd'; import { SearchOutlined } from '@ant-design/icons'; +import { Button, Input, Space, Tree } from 'antd'; +import { useEffect, useMemo, useState } from 'react'; import './TreeFilterDropdown.css'; export type OptionType = { title: string; key: string; - code?:string; + code?: string; children?: OptionType[]; }; @@ -31,7 +31,7 @@ export const TreeFilterDropdown: React.FC = ({ const [checkedKeys, setCheckedKeys] = useState(selectedKeys); const [expandedKeys, setExpandedKeys] = useState([]); - + useEffect(() => { setCheckedKeys(selectedKeys); }, [selectedKeys]); @@ -94,7 +94,7 @@ export const TreeFilterDropdown: React.FC = ({ }; return ( -
+
{title}
Поиск
@@ -107,12 +107,8 @@ export const TreeFilterDropdown: React.FC = ({ /> - - + +
@@ -131,9 +127,7 @@ export const TreeFilterDropdown: React.FC = ({
- +
); -}; \ No newline at end of file +}; diff --git a/web/src/layouts/ConsolidatioReportPage.tsx b/web/src/layouts/ConsolidatioReportPage.tsx index f3bb56f..19693f6 100644 --- a/web/src/layouts/ConsolidatioReportPage.tsx +++ b/web/src/layouts/ConsolidatioReportPage.tsx @@ -1,5 +1,5 @@ import { Space, message } from 'antd'; -import { ReactNode, useEffect, useState } from 'react'; +import { type ReactNode, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { ApiError } from '../api/client'; import PageTitle from '../components/PageTitle'; @@ -10,9 +10,9 @@ import type { ConsRussianStatus } from '../types/consolidations/common_types'; import type { VersionCard } from '../types/consolidations/version_members'; import { quarterShortLabel } from '../utils/labels'; import { statusColorMapping, statusMapping } from '../widgets/ConsoleTable/consts'; +import { ChessContent } from '../widgets/ConsolidatedChessContent/ConsolidatedChessContent'; import { OsvTabs } from '../widgets/ConsolidatedOsv/OsvTabs'; import { OsvContent } from '../widgets/ConsolidatedOsvContent/ConsolidatedOsvContent'; -import { ChessContent } from '../widgets/ConsolidatedChessContent/ConsolidatedChessContent'; function ReportContent() { const [card, setCard] = useState(null); @@ -21,10 +21,10 @@ function ReportContent() { const TAB_COMPONENTS: Record = { osv: , - chess: , + chess: , }; - const ActiveTab = TAB_COMPONENTS[tab as string] ?? <>; + const ActiveTab = TAB_COMPONENTS[tab as string] ?? null; const russianStatus = card ? (statusMapping[card.status] ?? card.status) : ''; const preset = statusColorMapping[russianStatus as ConsRussianStatus] ?? TAG_PRESETS.default; diff --git a/web/src/services/consodilation/chess.ts b/web/src/services/consodilation/chess.ts index 6e5513d..5ecf609 100644 --- a/web/src/services/consodilation/chess.ts +++ b/web/src/services/consodilation/chess.ts @@ -1,5 +1,5 @@ import { api, apiFetchBlob } from '../../api/client'; -import { ChessManualRequest, IntercompanyMatrixResponse } from '../../types/chess/chess'; +import type { ChessManualRequest, IntercompanyMatrixResponse } from '../../types/chess/chess'; export const fetchChessConsolidations = (id: string) => api.get(`/consolidations/versions/${id}/intercompany-matrix/all`); diff --git a/web/src/types/chess/chess.ts b/web/src/types/chess/chess.ts index c7efcf5..67e4d15 100644 --- a/web/src/types/chess/chess.ts +++ b/web/src/types/chess/chess.ts @@ -1,23 +1,23 @@ export interface MatrixCompany { - id: string; - name: string; + id: string; + name: string; } export interface MatrixCell { - company_a_id: string; - company_b_id: string; - amount_a: string; - amount_b: string; - variance_amount: string; - exceeds_threshold:boolean - one_sided:boolean - variance_percent:string| null - skipped_osv_entry_count:number + company_a_id: string; + company_b_id: string; + amount_a: string; + amount_b: string; + variance_amount: string; + exceeds_threshold: boolean; + one_sided: boolean; + variance_percent: string | null; + skipped_osv_entry_count: number; } export interface IntercompanyMatrixResponse { - companies: MatrixCompany[]; - cells: MatrixCell[]; + companies: MatrixCompany[]; + cells: MatrixCell[]; } export type ChessManualRequest = { diff --git a/web/src/widgets/ConsolidatedChessContent/ConsolidatedChessContent.tsx b/web/src/widgets/ConsolidatedChessContent/ConsolidatedChessContent.tsx index 7058f11..fc076a4 100644 --- a/web/src/widgets/ConsolidatedChessContent/ConsolidatedChessContent.tsx +++ b/web/src/widgets/ConsolidatedChessContent/ConsolidatedChessContent.tsx @@ -1,7 +1,7 @@ -import { useEffect, useMemo, useState, useRef } from 'react'; -import { useParams } from 'react-router-dom'; +import { DownloadOutlined, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons'; import { Button } from 'antd'; -import { FullscreenOutlined, FullscreenExitOutlined, DownloadOutlined } from '@ant-design/icons'; +import { useEffect, useMemo, useRef, useState } from 'react'; +import { useParams } from 'react-router-dom'; import { ApiError } from '../../api/client'; import { exportChessTableAll, @@ -10,13 +10,10 @@ import { fetchChessConsolidationsManual, } from '../../services/consodilation/chess'; import type { IntercompanyMatrixResponse } from '../../types/chess/chess'; +import { saveBlob } from '../../utils/download'; import { useNotificationApi } from '../../utils/useNotification'; import { ConsolidationChessTable } from '../ConsolidationChessTable/ConsolidationChessTable'; import { ConsolidationChessTableFilter } from '../ConsolidationChessTable/ConsolidationChessTableFilter'; -import { saveBlob } from '../../utils/download'; - - - export const ChessContent = () => { const { version_id } = useParams<{ version_id: string }>(); @@ -50,7 +47,7 @@ export const ChessContent = () => { const loadData = async (vId: string, dIds: string[], cIds: string[]) => { setLoading(true); try { - let res; + let res: IntercompanyMatrixResponse; if (dIds?.length && cIds?.length) { res = await fetchChessConsolidationsManual(vId, { debit_account_ids: dIds, credit_account_ids: cIds }); } else { @@ -163,7 +160,6 @@ export const ChessContent = () => {
} - /> ); diff --git a/web/src/widgets/ConsolidatedOsv/OsvTabs.tsx b/web/src/widgets/ConsolidatedOsv/OsvTabs.tsx index 7e0e9f4..dc03aa3 100644 --- a/web/src/widgets/ConsolidatedOsv/OsvTabs.tsx +++ b/web/src/widgets/ConsolidatedOsv/OsvTabs.tsx @@ -53,6 +53,7 @@ export function OsvTabs() { const label = ( tr:hover > td.empty-cell { - background-color: #f2f4f7 !important; + background-color: #f2f4f7 !important; } -.ant-table-summary{ - border-end-end-radius: 8px !important; - border-end-start-radius: 8px !important; +.ant-table-summary { + border-end-end-radius: 8px !important; + border-end-start-radius: 8px !important; } - .ant-table-cell-fix { - background-color: #f8fafc !important; + background-color: #f8fafc !important; } -.resRow{ - background-color:#e6f4ea !important ; +.resRow { + background-color: #e6f4ea !important ; } diff --git a/web/src/widgets/ConsolidationChessTable/ConsolidationChessTable.tsx b/web/src/widgets/ConsolidationChessTable/ConsolidationChessTable.tsx index c41e4d2..d380f64 100644 --- a/web/src/widgets/ConsolidationChessTable/ConsolidationChessTable.tsx +++ b/web/src/widgets/ConsolidationChessTable/ConsolidationChessTable.tsx @@ -1,6 +1,7 @@ -import React, { useMemo } from 'react'; import { Table, Typography } from 'antd'; import type { ColumnsType } from 'antd/es/table'; +import type React from 'react'; +import { useMemo } from 'react'; import type { IntercompanyMatrixResponse, MatrixCell, MatrixCompany } from '../../types/chess/chess'; import './ConsolidatedChessTable.css'; @@ -37,8 +38,8 @@ export const ConsolidationChessTable: React.FC = ({ const formatValue = (val: string | number) => { if (val === undefined || val === null || val === '') return ''; - let num = typeof val === 'string' ? parseFloat(val) : val; - if (isNaN(num)) return String(val); + let num = typeof val === 'string' ? Number.parseFloat(val) : val; + if (Number.isNaN(num)) return String(val); if (units === 'thousand') { num /= 1000; @@ -57,9 +58,9 @@ export const ConsolidationChessTable: React.FC = ({ const isNegative: boolean = val.startsWith('(') && val.endsWith(')'); const cleanVal = isNegative ? val.slice(1, -1) : val; - const num = parseFloat(cleanVal); + const num = Number.parseFloat(cleanVal); - if (isNaN(num)) { + if (Number.isNaN(num)) { return 0; } @@ -146,7 +147,7 @@ export const ConsolidationChessTable: React.FC = ({ return ( - dataSource={data?.companies || []} + dataSource={data?.companies || []} columns={columns} rowKey='id' pagination={false} @@ -159,7 +160,7 @@ export const ConsolidationChessTable: React.FC = ({ if (!totalRowData) return null; return ( - +
@@ -180,4 +181,4 @@ export const ConsolidationChessTable: React.FC = ({ }} /> ); -}; \ No newline at end of file +}; diff --git a/web/src/widgets/ConsolidationChessTable/ConsolidationChessTableFilter.tsx b/web/src/widgets/ConsolidationChessTable/ConsolidationChessTableFilter.tsx index 1775e11..2a0f3af 100644 --- a/web/src/widgets/ConsolidationChessTable/ConsolidationChessTableFilter.tsx +++ b/web/src/widgets/ConsolidationChessTable/ConsolidationChessTableFilter.tsx @@ -1,8 +1,9 @@ -import React, { useEffect, useState } from 'react'; -import { Space, Select, Button } from 'antd'; +import { Button, Select, Space } from 'antd'; +import type React from 'react'; +import { useEffect, useState } from 'react'; +import { ApiError, api } from '../../api/client'; +import { type OptionType, TreeFilterDropdown } from '../../components/TreeFilterDropdown/TreeFilterDropdown'; import type { MatrixCompany } from '../../types/chess/chess'; -import { OptionType, TreeFilterDropdown } from '../../components/TreeFilterDropdown/TreeFilterDropdown'; -import { api, ApiError } from '../../api/client'; import { useNotificationApi } from '../../utils/useNotification'; interface Account {