feat: make storing grid sizes opt in
This commit is contained in:
@@ -91,7 +91,7 @@ export const Portfolio = () => {
|
||||
<Tabs storageKey="console-portfolio-bottom">
|
||||
<Tab id="collateral" name={t('Collateral')}>
|
||||
<VegaWalletContainer>
|
||||
<AccountsContainer id="portfolioCollateral" />
|
||||
<AccountsContainer />
|
||||
</VegaWalletContainer>
|
||||
</Tab>
|
||||
<Tab id="deposits" name={t('Deposits')}>
|
||||
|
||||
@@ -13,12 +13,10 @@ export const AccountsContainer = ({
|
||||
pinnedAsset,
|
||||
hideButtons,
|
||||
noBottomPlaceholder,
|
||||
id,
|
||||
}: {
|
||||
pinnedAsset?: PinnedAsset;
|
||||
hideButtons?: boolean;
|
||||
noBottomPlaceholder?: boolean;
|
||||
id?: string;
|
||||
}) => {
|
||||
const { pubKey, isReadOnly } = useVegaWallet();
|
||||
const { open: openAssetDetailsDialog } = useAssetDetailsDialogStore();
|
||||
@@ -44,7 +42,6 @@ export const AccountsContainer = ({
|
||||
return (
|
||||
<div className="h-full relative">
|
||||
<AccountManager
|
||||
id={id}
|
||||
partyId={pubKey}
|
||||
onClickAsset={onClickAsset}
|
||||
onClickWithdraw={openWithdrawalDialog}
|
||||
|
||||
@@ -19,7 +19,6 @@ interface AccountManagerProps {
|
||||
isReadOnly: boolean;
|
||||
pinnedAsset?: PinnedAsset;
|
||||
noBottomPlaceholder?: boolean;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export const AccountManager = ({
|
||||
@@ -30,7 +29,6 @@ export const AccountManager = ({
|
||||
isReadOnly,
|
||||
pinnedAsset,
|
||||
noBottomPlaceholder,
|
||||
id,
|
||||
}: AccountManagerProps) => {
|
||||
const gridRef = useRef<AgGridReact | null>(null);
|
||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||
@@ -54,7 +52,6 @@ export const AccountManager = ({
|
||||
return (
|
||||
<div className="relative h-full">
|
||||
<AccountTable
|
||||
id={id}
|
||||
ref={gridRef}
|
||||
rowData={error ? [] : data}
|
||||
onClickAsset={onClickAsset}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { forwardRef, useCallback, useMemo, useState } from 'react';
|
||||
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
|
||||
import {
|
||||
addDecimalsFormatNumber,
|
||||
isNumeric,
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
VegaICellRendererParams,
|
||||
VegaValueFormatterParams,
|
||||
} from '@vegaprotocol/datagrid';
|
||||
import { useColumnSizes } from '@vegaprotocol/datagrid';
|
||||
import {
|
||||
Button,
|
||||
ButtonLink,
|
||||
@@ -105,6 +106,11 @@ export interface AccountTableProps extends AgGridReactProps {
|
||||
|
||||
export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
({ onClickAsset, onClickWithdraw, onClickDeposit, ...props }, ref) => {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const { onGridReady, onColumnResized } = useColumnSizes({
|
||||
id: 'accounts',
|
||||
container: containerRef,
|
||||
});
|
||||
const [openBreakdown, setOpenBreakdown] = useState(false);
|
||||
const [row, setRow] = useState<AccountFields>();
|
||||
const pinnedAssetId = props.pinnedAsset?.id;
|
||||
@@ -144,7 +150,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="w-full h-full" ref={containerRef}>
|
||||
<AgGrid
|
||||
{...props}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
@@ -155,6 +161,8 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
rowData={props.rowData?.filter(
|
||||
(data) => data.asset.id !== pinnedAssetId
|
||||
)}
|
||||
onGridReady={onGridReady}
|
||||
onColumnResized={onColumnResized}
|
||||
defaultColDef={{
|
||||
resizable: true,
|
||||
tooltipComponent: TooltipCellComponent,
|
||||
@@ -387,7 +395,7 @@ export const AccountTable = forwardRef<AgGridReact, AccountTableProps>(
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useRef } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||
import type { ColumnResizedEvent } from 'ag-grid-community';
|
||||
import type { ColumnResizedEvent, GridReadyEvent } from 'ag-grid-community';
|
||||
import { AgGridReact } from 'ag-grid-react';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { useColumnSizes } from './use-column-sizes';
|
||||
@@ -19,35 +19,19 @@ export const AgGridThemed = ({
|
||||
id?: string;
|
||||
children?: ReactNode[];
|
||||
}) => {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [setValues, reshapeChildren, reshapeProps] = useColumnSizes({
|
||||
id,
|
||||
container: containerRef,
|
||||
});
|
||||
const { theme } = useThemeSwitcher();
|
||||
const defaultProps = {
|
||||
rowHeight: 22,
|
||||
headerHeight: 22,
|
||||
enableCellTextSelection: true,
|
||||
onColumnResized: useCallback(
|
||||
(event: ColumnResizedEvent) => {
|
||||
if (event.source === 'uiColumnDragged' && event.columns) {
|
||||
setValues(event.columns);
|
||||
}
|
||||
},
|
||||
[setValues]
|
||||
),
|
||||
};
|
||||
|
||||
children = reshapeChildren(children);
|
||||
props = reshapeProps(props, children);
|
||||
|
||||
const wrapperClasses = classNames('vega-ag-grid', {
|
||||
'ag-theme-balham': theme === 'light',
|
||||
'ag-theme-balham-dark': theme === 'dark',
|
||||
});
|
||||
return (
|
||||
<div className={wrapperClasses} style={style} ref={containerRef}>
|
||||
<div className={wrapperClasses} style={style}>
|
||||
<AgGridReact {...defaultProps} {...props} ref={gridRef}>
|
||||
{children}
|
||||
</AgGridReact>
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import type { MutableRefObject, ReactElement } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import type { AgGridReactProps, AgReactUiProps } from 'ag-grid-react';
|
||||
import type { Column, ColDef } from 'ag-grid-community';
|
||||
import type {
|
||||
Column,
|
||||
ColDef,
|
||||
ColumnResizedEvent,
|
||||
GridReadyEvent,
|
||||
} from 'ag-grid-community';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
@@ -35,17 +40,7 @@ interface UseColumnSizesProps {
|
||||
id?: string;
|
||||
container?: MutableRefObject<HTMLDivElement | null>;
|
||||
}
|
||||
export const useColumnSizes = ({
|
||||
id = '',
|
||||
container,
|
||||
}: UseColumnSizesProps): [
|
||||
(columns: Column[]) => void,
|
||||
(children?: ReactElement[]) => ReactElement[] | undefined,
|
||||
(
|
||||
props: AgGridReactProps | AgReactUiProps,
|
||||
children?: ReactElement[]
|
||||
) => AgGridReactProps | AgReactUiProps
|
||||
] => {
|
||||
export const useColumnSizes = ({ id = '', container }: UseColumnSizesProps) => {
|
||||
const sizes = useColumnSizesStore((store) => store.sizes[id] || {});
|
||||
const valueSetter = useColumnSizesStore((store) => store.valueSetter);
|
||||
const getWidthOfAll = useCallback(
|
||||
@@ -54,85 +49,73 @@ export const useColumnSizes = ({
|
||||
0,
|
||||
[container]
|
||||
);
|
||||
const recalculateSizes = useCallback(
|
||||
(sizes: Record<string, number>) => {
|
||||
const width = getWidthOfAll();
|
||||
if (width && sizes['width'] && width !== sizes['width']) {
|
||||
const oldWidth = sizes['width'];
|
||||
const ratio = width / oldWidth;
|
||||
return {
|
||||
...Object.entries(sizes).reduce((agg, [key, value]) => {
|
||||
agg[key] = value * ratio;
|
||||
return agg;
|
||||
}, {} as Record<string, number>),
|
||||
width,
|
||||
} as Record<string, number>;
|
||||
}
|
||||
return sizes;
|
||||
},
|
||||
[getWidthOfAll]
|
||||
);
|
||||
const [calculatedSizes, setCalculatedSizes] = useState(
|
||||
recalculateSizes(sizes)
|
||||
);
|
||||
const onResize = useCallback(() => {
|
||||
const width = getWidthOfAll();
|
||||
if (width && sizes['width'] && width !== sizes['width']) {
|
||||
setCalculatedSizes(recalculateSizes(sizes));
|
||||
}
|
||||
}, [getWidthOfAll, recalculateSizes, sizes]);
|
||||
useResizeObserver(container?.current as Element, onResize);
|
||||
// const recalculateSizes = useCallback(
|
||||
// (sizes: Record<string, number>) => {
|
||||
// const width = getWidthOfAll();
|
||||
// if (width && sizes['width'] && width !== sizes['width']) {
|
||||
// const oldWidth = sizes['width'];
|
||||
// const ratio = width / oldWidth;
|
||||
// return {
|
||||
// ...Object.entries(sizes).reduce((agg, [key, value]) => {
|
||||
// agg[key] = value * ratio;
|
||||
// return agg;
|
||||
// }, {} as Record<string, number>),
|
||||
// width,
|
||||
// } as Record<string, number>;
|
||||
// }
|
||||
// return sizes;
|
||||
// },
|
||||
// [getWidthOfAll]
|
||||
// );
|
||||
// const [calculatedSizes, setCalculatedSizes] = useState(
|
||||
// recalculateSizes(sizes)
|
||||
// );
|
||||
// const onResize = useCallback(() => {
|
||||
// const width = getWidthOfAll();
|
||||
// if (width && sizes['width'] && width !== sizes['width']) {
|
||||
// setCalculatedSizes(recalculateSizes(sizes));
|
||||
// }
|
||||
// }, [getWidthOfAll, recalculateSizes, sizes]);
|
||||
// useResizeObserver(container?.current as Element, onResize);
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const handleOnChange = useCallback(
|
||||
debounce((columns: Column[]) => {
|
||||
if (id && columns.length) {
|
||||
const sizesObj = columns.reduce((aggr, column) => {
|
||||
aggr[column.getColId()] = column.getActualWidth();
|
||||
return aggr;
|
||||
}, {} as Record<string, number>);
|
||||
sizesObj['width'] = getWidthOfAll();
|
||||
valueSetter(id, sizesObj);
|
||||
const onColumnResized = useCallback(
|
||||
(event: ColumnResizedEvent) => {
|
||||
if (
|
||||
event.finished &&
|
||||
event.source === 'uiColumnDragged' &&
|
||||
event.columns
|
||||
) {
|
||||
const colState = event.columnApi.getColumnState();
|
||||
const store: { [colId: string]: number } = {};
|
||||
colState.forEach((c) => {
|
||||
if (c.width) {
|
||||
store[c.colId] = c.width;
|
||||
}
|
||||
});
|
||||
valueSetter(id, store);
|
||||
}
|
||||
}, COLUMNS_SET_DEBOUNCE_TIME),
|
||||
},
|
||||
[valueSetter, id]
|
||||
);
|
||||
const reshapeAgGridChildren = useCallback(
|
||||
(children?: ReactElement[]) =>
|
||||
id && children?.length && Object.keys(calculatedSizes).length
|
||||
? children.map((child: ReactElement) => ({
|
||||
...child,
|
||||
props: {
|
||||
...(child?.props ?? {}),
|
||||
width:
|
||||
(child?.props.colId && calculatedSizes[child?.props.colId]) ||
|
||||
(child?.props.field && calculatedSizes[child?.props.field]) ||
|
||||
undefined,
|
||||
},
|
||||
}))
|
||||
: children,
|
||||
[calculatedSizes, id]
|
||||
|
||||
const onGridReady = useCallback(
|
||||
(event: GridReadyEvent) => {
|
||||
console.log(event);
|
||||
if (!Object.keys(sizes).length) {
|
||||
event.columnApi.sizeColumnsToFit(getWidthOfAll());
|
||||
} else {
|
||||
const initialSizes = Object.entries(sizes).map(([key, newWidth]) => ({
|
||||
key,
|
||||
newWidth,
|
||||
}));
|
||||
event.columnApi.setColumnWidths(initialSizes);
|
||||
}
|
||||
},
|
||||
[sizes, getWidthOfAll]
|
||||
);
|
||||
const reshapeAgGridProps = useCallback(
|
||||
(props: AgGridReactProps | AgReactUiProps, children?: ReactElement[]) =>
|
||||
id && props?.columnDefs && Object.keys(calculatedSizes).length
|
||||
? ({
|
||||
...props,
|
||||
columnDefs: props.columnDefs.map((columnDef: ColDef) => ({
|
||||
...columnDef,
|
||||
width:
|
||||
(columnDef.colId && calculatedSizes[columnDef.colId]) ||
|
||||
(columnDef.field && calculatedSizes[columnDef.field]) ||
|
||||
undefined,
|
||||
})),
|
||||
} as AgGridReactProps | AgReactUiProps)
|
||||
: children?.length
|
||||
? props
|
||||
: ({
|
||||
...props,
|
||||
defaultColDef: { ...(props.defaultColDef || null), flex: 1 },
|
||||
} as AgGridReactProps | AgReactUiProps),
|
||||
[calculatedSizes, id]
|
||||
);
|
||||
return [handleOnChange, reshapeAgGridChildren, reshapeAgGridProps];
|
||||
|
||||
return {
|
||||
onColumnResized,
|
||||
onGridReady,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user