chore(web): format и biome для шахматки (ревью #158)
- npm run format (eslint --fix, biome check --write, prettier --write) по файлам шахматки; - biome: import type и сортировка импортов; явный тип IntercompanyMatrixResponse у `let res` (ConsolidatedChessContent); Number.isNaN вместо isNaN (ConsolidationChessTable); key у span в OsvTabs; `?? null` вместо пустого фрагмента (ConsolidatioReportPage). Поведение не менялось. Остаются предупреждения eslint в коде шахматки (any, deps хуков, console) — за автором. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
175343b843
commit
e19291c886
@ -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() {
|
||||
|
||||
@ -129,13 +129,13 @@ export async function apiFetch<T>(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 blob = await response.blob();
|
||||
return {
|
||||
blob,
|
||||
filename: filenameFromContentDisposition(response.headers.get('Content-Disposition'))
|
||||
filename: filenameFromContentDisposition(response.headers.get('Content-Disposition')),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
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 = {
|
||||
@ -107,12 +107,8 @@ export const TreeFilterDropdown: React.FC<TreeFilterDropdownProps> = ({
|
||||
/>
|
||||
|
||||
<Space style={{ marginBottom: 12, justifyContent: 'space-between', width: '100%' }}>
|
||||
<Button onClick={handleSelectAll}>
|
||||
Выбрать все
|
||||
</Button>
|
||||
<Button onClick={handleClear}>
|
||||
Очистить
|
||||
</Button>
|
||||
<Button onClick={handleSelectAll}>Выбрать все</Button>
|
||||
<Button onClick={handleClear}>Очистить</Button>
|
||||
</Space>
|
||||
|
||||
<div style={{ maxHeight: 280, overflowY: 'auto', border: '1px solid #f0f0f0', borderRadius: 8, padding: 8 }}>
|
||||
@ -131,9 +127,7 @@ export const TreeFilterDropdown: React.FC<TreeFilterDropdownProps> = ({
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 10 }}>
|
||||
<Button onClick={handleCancel}>
|
||||
Отмена
|
||||
</Button>
|
||||
<Button onClick={handleCancel}>Отмена</Button>
|
||||
<Button
|
||||
type='primary'
|
||||
style={{ background: '#2a8c3a' }}
|
||||
|
||||
@ -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<VersionCard | null>(null);
|
||||
@ -24,7 +24,7 @@ function ReportContent() {
|
||||
chess: <ChessContent />,
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@ -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<IntercompanyMatrixResponse>(`/consolidations/versions/${id}/intercompany-matrix/all`);
|
||||
|
||||
@ -9,10 +9,10 @@ export interface MatrixCell {
|
||||
amount_a: string;
|
||||
amount_b: string;
|
||||
variance_amount: string;
|
||||
exceeds_threshold:boolean
|
||||
one_sided:boolean
|
||||
variance_percent:string| null
|
||||
skipped_osv_entry_count:number
|
||||
exceeds_threshold: boolean;
|
||||
one_sided: boolean;
|
||||
variance_percent: string | null;
|
||||
skipped_osv_entry_count: number;
|
||||
}
|
||||
|
||||
export interface IntercompanyMatrixResponse {
|
||||
|
||||
@ -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 = () => {
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -53,6 +53,7 @@ export function OsvTabs() {
|
||||
|
||||
const label = (
|
||||
<span
|
||||
key={tabItem.key}
|
||||
style={{
|
||||
color: isActive ? '#2a8c3a' : undefined,
|
||||
fontWeight: isActive ? 600 : 400,
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
border-end-start-radius: 8px !important;
|
||||
}
|
||||
|
||||
|
||||
.ant-table-cell-fix {
|
||||
background-color: #f8fafc !important;
|
||||
}
|
||||
|
||||
@ -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<ConsolidationChessTableI> = ({
|
||||
|
||||
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<ConsolidationChessTableI> = ({
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user