Загрузка данных
import React from 'react';
import { Icon } from '@uikit/Icon';
import { BUTTON_MORE_ROW_KEY } from '@widgets/TradingResult/components/Repo/constants';
import { LoadMoreButton } from '@widgets/TradingResult/components/Repo/repo-table/component/loadMoreButton';
import { DataInfoByGroup } from '@widgets/TradingResult/components/Repo/repo-table/logic/table/useLoadGroupSubRowsData';
import { GroupFiltersStruct } from '@widgets/TradingResult/components/Repo/types/group';
import { Group } from 'types/MonitorRepo';
import repoTableStyles from '../styles/repoTable.module.scss';
interface InitialGroupFilterRecord {
key: string;
rowData: Record<string, unknown>;
}
interface GroupFilterValue {
value: string;
}
interface ExpandIconProps {
onExpand: (
record: Record<string, unknown>,
event: React.MouseEvent<HTMLElement>,
) => void;
record: Record<string, unknown>;
}
const VALUES_TO_REFRESH = [
'aggPrice',
'aggQuantity',
'aggAccint',
'aggValue',
'aggRepoRate',
'aggRepoValue',
] as const satisfies readonly (keyof Group)[];
const isGroupFilterValue = (
value: unknown,
): value is GroupFilterValue => {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
return false;
}
return 'value' in value && typeof value.value === 'string';
};
export const createInitialGroupFilters = (
record: InitialGroupFilterRecord,
): GroupFiltersStruct =>
Object.entries(record.rowData).reduce<GroupFiltersStruct>(
(acc, [filterName, dataValue]) => {
if (!isGroupFilterValue(dataValue)) {
return acc;
}
const groupValue = record.key;
return {
...acc,
[groupValue]: {
...acc[groupValue],
[filterName]: dataValue.value,
},
};
},
{},
);
export const ExpandIcon = ({
onExpand,
record,
}: ExpandIconProps) =>
record.children ? (
<div
className={repoTableStyles.expandIconWrapper}
onClick={(event: React.MouseEvent<HTMLElement>) =>
onExpand(record, event)
}
>
<Icon variant="chevron-down" />
</div>
) : null;
export const unifyGroupAndChildrenRows = <
T extends Record<string, unknown>,
>(
groupSubRowsData: Record<string, DataInfoByGroup>,
groupsData: T[],
buttonMargin: number,
loadMore: (groupValue: string) => Promise<void>,
): T[] => {
// ищем значения групп по которым существуют данные подстрок
const groupValues = Object.keys(groupSubRowsData);
if (groupValues.length === 0) {
return groupsData;
}
groupValues.forEach((groupValue) => {
const groupData = groupSubRowsData[groupValue];
if (!groupData) {
return;
}
const searchedGroup = groupsData.find(
(item) => item.key === groupValue,
);
if (!searchedGroup) {
return;
}
const data = groupData.data ?? [];
const page = groupData.page ?? 0;
const size = groupData.size ?? 0;
const totalValues = groupData.total ?? 0;
const itemsCount = data.length;
const isEmptyChildrenRows = itemsCount === 0;
const loadedRowsNumber = (page + 1) * size;
// подгруженные данные репо по группировке заносим в общую структуру групп как children
searchedGroup.children = [
...data,
{
key: `${BUTTON_MORE_ROW_KEY}${groupValue}`,
forceToSort: true,
secId: (
<LoadMoreButton
styles={{ marginLeft: buttonMargin }}
onClick={() => loadMore(groupValue)}
loaded={
!isEmptyChildrenRows
? Math.min(
loadedRowsNumber,
totalValues,
itemsCount,
)
: 0
}
shouldDisplayButton={
itemsCount === loadedRowsNumber
}
total={
!isEmptyChildrenRows
? totalValues || loadedRowsNumber
: 0
}
/>
),
},
];
});
return [...groupsData];
};
/** Обновляем только пересчитываемые значения */
export const refreshRowAggValues = (
oldGroup: Group,
newGroup: Group,
): Group =>
VALUES_TO_REFRESH.reduce(
(group, key) => ({
...group,
[key]: newGroup[key],
}),
oldGroup,
);