Update full-width cell renderer

This commit is contained in:
jeffvli 2023-05-20 19:21:23 -07:00
parent 897af4661b
commit 35f9798bed
4 changed files with 87 additions and 22 deletions

View file

@ -0,0 +1,45 @@
import { useState } from 'react';
import { ICellRendererParams } from '@ag-grid-community/core';
import { Group } from '@mantine/core';
import { RiCheckboxBlankLine, RiCheckboxLine } from 'react-icons/ri';
import styled from 'styled-components';
import { Button } from '/@/renderer/components/button';
import { Paper } from '/@/renderer/components/paper';
import { getNodesByDiscNumber, setNodeSelection } from '../utils';
const Container = styled(Paper)`
padding: 0.5rem 1rem;
border: 1px solid transparent;
`;
export const FullWidthDiscCell = ({ node, data, api }: ICellRendererParams) => {
const [isSelected, setIsSelected] = useState(false);
const handleToggleDiscNodes = () => {
if (!data) return;
const discNumber = Number(node.data.id.split('-')[1]);
const nodes = getNodesByDiscNumber({ api, discNumber });
setNodeSelection({ isSelected: !isSelected, nodes });
setIsSelected((prev) => !prev);
};
return (
<Container>
<Group
position="apart"
w="100%"
>
<Button
compact
leftIcon={isSelected ? <RiCheckboxLine /> : <RiCheckboxBlankLine />}
size="md"
variant="subtle"
onClick={handleToggleDiscNodes}
>
{data.name}
</Button>
</Group>
</Container>
);
};

View file

@ -37,6 +37,7 @@ export * from './table-config-dropdown';
export * from './table-pagination'; export * from './table-pagination';
export * from './hooks/use-fixed-table-header'; export * from './hooks/use-fixed-table-header';
export * from './hooks/use-click-outside-deselect'; export * from './hooks/use-click-outside-deselect';
export * from './utils';
const TableWrapper = styled.div` const TableWrapper = styled.div`
display: flex; display: flex;

View file

@ -0,0 +1,36 @@
import { GridApi, RowNode } from '@ag-grid-community/core';
export const getNodesByDiscNumber = (args: { api: GridApi; discNumber: number }) => {
const { api, discNumber } = args;
const nodes: RowNode<any>[] = [];
api.forEachNode((node) => {
if (node.data.discNumber === discNumber) nodes.push(node);
});
return nodes;
};
export const setNodeSelection = (args: {
deselectAll?: boolean;
isSelected: boolean;
nodes: RowNode<any>[];
}) => {
const { nodes, isSelected } = args;
nodes.forEach((node) => {
node.setSelected(isSelected);
});
};
export const toggleNodeSelection = (args: { nodes: RowNode<any>[] }) => {
const { nodes } = args;
nodes.forEach((node) => {
if (node.isSelected()) {
node.setSelected(false);
} else {
node.setSelected(true);
}
});
};

View file

@ -4,7 +4,7 @@ import { ColDef, RowDoubleClickedEvent, RowHeightParams, RowNode } from '@ag-gri
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
import { Box, Group, Stack } from '@mantine/core'; import { Box, Group, Stack } from '@mantine/core';
import { useSetState } from '@mantine/hooks'; import { useSetState } from '@mantine/hooks';
import { RiDiscFill, RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri'; import { RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
import { generatePath, useParams } from 'react-router'; import { generatePath, useParams } from 'react-router';
import { useAlbumDetail } from '/@/renderer/features/albums/queries/album-detail-query'; import { useAlbumDetail } from '/@/renderer/features/albums/queries/album-detail-query';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -32,9 +32,10 @@ import {
VirtualTable, VirtualTable,
} from '/@/renderer/components/virtual-table'; } from '/@/renderer/components/virtual-table';
import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel'; import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel';
import { FullWidthDiscCell } from '/@/renderer/components/virtual-table/cells/full-width-disc-cell';
const isFullWidthRow = (node: RowNode) => { const isFullWidthRow = (node: RowNode) => {
return node.id?.includes('disc-'); return node.id?.startsWith('disc-');
}; };
const ContentContainer = styled.div` const ContentContainer = styled.div`
@ -125,16 +126,11 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
} }
const uniqueDiscNumbers = new Set(detailQuery.data?.songs.map((s) => s.discNumber)); const uniqueDiscNumbers = new Set(detailQuery.data?.songs.map((s) => s.discNumber));
if (uniqueDiscNumbers.size === 1) {
return detailQuery.data?.songs;
}
const rowData: (QueueSong | { id: string; name: string })[] = []; const rowData: (QueueSong | { id: string; name: string })[] = [];
for (const discNumber of uniqueDiscNumbers.values()) { for (const discNumber of uniqueDiscNumbers.values()) {
const songsByDiscNumber = detailQuery.data?.songs.filter((s) => s.discNumber === discNumber); const songsByDiscNumber = detailQuery.data?.songs.filter((s) => s.discNumber === discNumber);
rowData.push({ id: `disc-${discNumber}`, name: `DISC ${discNumber}` }); rowData.push({ id: `disc-${discNumber}`, name: `Disc ${discNumber}`.toLocaleUpperCase() });
rowData.push(...songsByDiscNumber); rowData.push(...songsByDiscNumber);
} }
@ -335,26 +331,13 @@ export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => {
ref={tableRef} ref={tableRef}
autoFitColumns autoFitColumns
autoHeight autoHeight
deselectOnClickOutside
suppressCellFocus suppressCellFocus
suppressHorizontalScroll suppressHorizontalScroll
suppressLoadingOverlay suppressLoadingOverlay
suppressRowDrag suppressRowDrag
columnDefs={columnDefs} columnDefs={columnDefs}
enableCellChangeFlash={false} enableCellChangeFlash={false}
fullWidthCellRenderer={(data: any) => { fullWidthCellRenderer={FullWidthDiscCell}
if (!data.data) return null;
return (
<Group
align="center"
h="100%"
spacing="sm"
>
<RiDiscFill />
<Text>{data.data.name}</Text>
</Group>
);
}}
getRowHeight={getRowHeight} getRowHeight={getRowHeight}
getRowId={(data) => data.data.id} getRowId={(data) => data.data.id}
isFullWidthRow={(data) => { isFullWidthRow={(data) => {