Форматирование под 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
@ -1,51 +1,46 @@
|
|||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useMemo, useRef, useState } from 'react';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
/** высота одного элемента в px (фиксированная) */
|
/** высота одного элемента в px (фиксированная) */
|
||||||
itemHeight: number;
|
itemHeight: number;
|
||||||
/** высота контейнера в px (видимая область) */
|
/** высота контейнера в px (видимая область) */
|
||||||
containerHeight: number;
|
containerHeight: number;
|
||||||
/** сколько элементов рендерить дополнительно сверху/снизу */
|
/** сколько элементов рендерить дополнительно сверху/снизу */
|
||||||
overscan?: number;
|
overscan?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function useVirtualList<T>(items: T[], options: Options) {
|
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 [scrollTop, setScrollTop] = useState(0);
|
||||||
const ref = useRef<HTMLDivElement | null>(null);
|
const ref = useRef<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
const totalHeight = items.length * itemHeight;
|
const totalHeight = items.length * itemHeight;
|
||||||
|
|
||||||
const startIndex = Math.max(
|
const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
|
||||||
0,
|
|
||||||
Math.floor(scrollTop / itemHeight) - overscan,
|
|
||||||
);
|
|
||||||
|
|
||||||
const endIndex = Math.min(
|
const endIndex = Math.min(items.length, Math.ceil((scrollTop + containerHeight) / itemHeight) + overscan);
|
||||||
items.length,
|
|
||||||
Math.ceil((scrollTop + containerHeight) / itemHeight) + overscan,
|
|
||||||
);
|
|
||||||
|
|
||||||
const visibleItems = useMemo(
|
const visibleItems = useMemo(
|
||||||
() => items.slice(startIndex, endIndex).map((item, i) => ({
|
() =>
|
||||||
item,
|
items.slice(startIndex, endIndex).map((item, i) => ({
|
||||||
index: startIndex + i,
|
item,
|
||||||
})),
|
index: startIndex + i,
|
||||||
[items, startIndex, endIndex],
|
})),
|
||||||
);
|
[items, startIndex, endIndex],
|
||||||
|
);
|
||||||
|
|
||||||
const offsetY = startIndex * itemHeight;
|
const offsetY = startIndex * itemHeight;
|
||||||
|
|
||||||
const onScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
|
const onScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
|
||||||
setScrollTop(e.currentTarget.scrollTop);
|
setScrollTop(e.currentTarget.scrollTop);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ref,
|
ref,
|
||||||
onScroll,
|
onScroll,
|
||||||
visibleItems,
|
visibleItems,
|
||||||
totalHeight,
|
totalHeight,
|
||||||
offsetY,
|
offsetY,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@ import type {
|
|||||||
import { LE_PAGE } from './company_groups';
|
import { LE_PAGE } from './company_groups';
|
||||||
|
|
||||||
export async function fetchCatalogueJur(params: GetCatalogueJurPropsI) {
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -243,7 +243,7 @@ export function CatalogueJurTable({ outside_group, tabsComponent }: CatalogueJur
|
|||||||
<ColumnSettings defs={catalogueJurConfig.columns} visibleKeys={visibleKeys} onChange={setVisibleKeys} />
|
<ColumnSettings defs={catalogueJurConfig.columns} visibleKeys={visibleKeys} onChange={setVisibleKeys} />
|
||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
{(relatedGroupFilter?.id && !outside_group) && (
|
{relatedGroupFilter?.id && !outside_group && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
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 { FolderOpenOutlined, SearchOutlined } from '@ant-design/icons';
|
||||||
import { useAppDispatch, useAppSelector } from '../../store/store';
|
import { Empty, Input, List, Spin, Tag, Typography } from 'antd';
|
||||||
import { getCompanyGroupsThunk } from '../../store/slices/companyGroupsSlice/thunks';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { setActiveCompanyGroup } from '../../store/slices/companyGroupsSlice/companyGroupsSlice';
|
|
||||||
import { useVirtualList } from '../../hooks/useVirtualList';
|
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;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user