Форматирование под ESLint + Prettier, зелёный make check (#31)
npm run format: порядок импортов (biome) в CompanyGroupsList.tsx, Prettier в пяти файлах; правки только оформления. make check: eslint 0 ошибок (19 предупреждений), vitest 324/324, build ок. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
681697f728
commit
5b13b74a7a
@ -40,8 +40,8 @@ export const TAG_PRESETS = {
|
||||
color: 'rgb(146, 64, 14)',
|
||||
},
|
||||
gray: {
|
||||
color: 'rgb(71, 84, 103)',
|
||||
bgColor: 'rgb(248, 250, 252)',
|
||||
borderColor: 'rgba(15, 23, 42, 0.08)',
|
||||
color: 'rgb(71, 84, 103)',
|
||||
bgColor: 'rgb(248, 250, 252)',
|
||||
borderColor: 'rgba(15, 23, 42, 0.08)',
|
||||
},
|
||||
} as const;
|
||||
|
||||
@ -1,51 +1,46 @@
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||
|
||||
type Options = {
|
||||
/** высота одного элемента в px (фиксированная) */
|
||||
itemHeight: number;
|
||||
/** высота контейнера в px (видимая область) */
|
||||
containerHeight: number;
|
||||
/** сколько элементов рендерить дополнительно сверху/снизу */
|
||||
overscan?: number;
|
||||
/** высота одного элемента в px (фиксированная) */
|
||||
itemHeight: number;
|
||||
/** высота контейнера в px (видимая область) */
|
||||
containerHeight: number;
|
||||
/** сколько элементов рендерить дополнительно сверху/снизу */
|
||||
overscan?: number;
|
||||
};
|
||||
|
||||
export function useVirtualList<T>(items: T[], options: Options) {
|
||||
const { itemHeight, containerHeight, overscan = 5 } = options;
|
||||
const { itemHeight, containerHeight, overscan = 5 } = options;
|
||||
|
||||
const [scrollTop, setScrollTop] = useState(0);
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const [scrollTop, setScrollTop] = useState(0);
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const totalHeight = items.length * itemHeight;
|
||||
const totalHeight = items.length * itemHeight;
|
||||
|
||||
const startIndex = Math.max(
|
||||
0,
|
||||
Math.floor(scrollTop / itemHeight) - overscan,
|
||||
);
|
||||
const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
|
||||
|
||||
const endIndex = Math.min(
|
||||
items.length,
|
||||
Math.ceil((scrollTop + containerHeight) / itemHeight) + overscan,
|
||||
);
|
||||
const endIndex = Math.min(items.length, Math.ceil((scrollTop + containerHeight) / itemHeight) + overscan);
|
||||
|
||||
const visibleItems = useMemo(
|
||||
() => items.slice(startIndex, endIndex).map((item, i) => ({
|
||||
item,
|
||||
index: startIndex + i,
|
||||
})),
|
||||
[items, startIndex, endIndex],
|
||||
);
|
||||
const visibleItems = useMemo(
|
||||
() =>
|
||||
items.slice(startIndex, endIndex).map((item, i) => ({
|
||||
item,
|
||||
index: startIndex + i,
|
||||
})),
|
||||
[items, startIndex, endIndex],
|
||||
);
|
||||
|
||||
const offsetY = startIndex * itemHeight;
|
||||
const offsetY = startIndex * itemHeight;
|
||||
|
||||
const onScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
|
||||
setScrollTop(e.currentTarget.scrollTop);
|
||||
}, []);
|
||||
const onScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
|
||||
setScrollTop(e.currentTarget.scrollTop);
|
||||
}, []);
|
||||
|
||||
return {
|
||||
ref,
|
||||
onScroll,
|
||||
visibleItems,
|
||||
totalHeight,
|
||||
offsetY,
|
||||
};
|
||||
}
|
||||
return {
|
||||
ref,
|
||||
onScroll,
|
||||
visibleItems,
|
||||
totalHeight,
|
||||
offsetY,
|
||||
};
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import type {
|
||||
import { LE_PAGE } from './company_groups';
|
||||
|
||||
export async function fetchCatalogueJur(params: GetCatalogueJurPropsI) {
|
||||
const res = await api.get<Page<ICatalogueJur>>('/directories/legal-entities', {limit:LE_PAGE, offset:0, ...params});
|
||||
const res = await api.get<Page<ICatalogueJur>>('/directories/legal-entities', { limit: LE_PAGE, offset: 0, ...params });
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ export const CatalogueJurForm: React.FC<Props> = ({ open, onCancel, onOk, jurId
|
||||
} catch (e) {
|
||||
if (e instanceof ApiError) {
|
||||
notification.error({ description: e.message });
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
setInitialDataLoading(false);
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
||||
<ColumnSettings defs={catalogueJurConfig.columns} visibleKeys={visibleKeys} onChange={setVisibleKeys} />
|
||||
</Space>
|
||||
</Space>
|
||||
{(relatedGroupFilter?.id && !outside_group) && (
|
||||
{relatedGroupFilter?.id && !outside_group && (
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Input, List, Spin, Empty, Typography, Tag } from 'antd';
|
||||
import { FolderOpenOutlined, SearchOutlined } from '@ant-design/icons';
|
||||
import { useAppDispatch, useAppSelector } from '../../store/store';
|
||||
import { getCompanyGroupsThunk } from '../../store/slices/companyGroupsSlice/thunks';
|
||||
import { setActiveCompanyGroup } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
|
||||
import { Empty, Input, List, Spin, Tag, Typography } from 'antd';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { useVirtualList } from '../../hooks/useVirtualList';
|
||||
import { setActiveCompanyGroup } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
|
||||
import { getCompanyGroupsThunk } from '../../store/slices/companyGroupsSlice/thunks';
|
||||
import { useAppDispatch, useAppSelector } from '../../store/store';
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user