mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 10:03:33 +00:00
Lint all files
This commit is contained in:
parent
22af76b4d6
commit
30e52ebb54
334 changed files with 76519 additions and 75932 deletions
|
|
@ -1,16 +1,16 @@
|
|||
/* eslint-disable import/no-cycle */
|
||||
import { Ref, forwardRef, useRef, useEffect, useCallback, useMemo } from 'react';
|
||||
import type {
|
||||
ICellRendererParams,
|
||||
ValueGetterParams,
|
||||
IHeaderParams,
|
||||
ValueFormatterParams,
|
||||
ColDef,
|
||||
ColumnMovedEvent,
|
||||
NewColumnsLoadedEvent,
|
||||
GridReadyEvent,
|
||||
GridSizeChangedEvent,
|
||||
ModelUpdatedEvent,
|
||||
ICellRendererParams,
|
||||
ValueGetterParams,
|
||||
IHeaderParams,
|
||||
ValueFormatterParams,
|
||||
ColDef,
|
||||
ColumnMovedEvent,
|
||||
NewColumnsLoadedEvent,
|
||||
GridReadyEvent,
|
||||
GridSizeChangedEvent,
|
||||
ModelUpdatedEvent,
|
||||
} from '@ag-grid-community/core';
|
||||
import type { AgGridReactProps } from '@ag-grid-community/react';
|
||||
import { AgGridReact } from '@ag-grid-community/react';
|
||||
|
|
@ -40,428 +40,453 @@ export * from './hooks/use-click-outside-deselect';
|
|||
export * from './utils';
|
||||
|
||||
const TableWrapper = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
const tableColumns: { [key: string]: ColDef } = {
|
||||
album: {
|
||||
cellRenderer: (params: ICellRendererParams) =>
|
||||
GenericCell(params, { isLink: true, position: 'left' }),
|
||||
colId: TableColumn.ALBUM,
|
||||
headerName: 'Album',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data
|
||||
? {
|
||||
link: generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||
albumId: params.data?.albumId || '',
|
||||
}),
|
||||
value: params.data?.album,
|
||||
}
|
||||
: undefined,
|
||||
width: 200,
|
||||
},
|
||||
albumArtist: {
|
||||
cellRenderer: AlbumArtistCell,
|
||||
colId: TableColumn.ALBUM_ARTIST,
|
||||
headerName: 'Album Artist',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.albumArtists : undefined,
|
||||
width: 150,
|
||||
},
|
||||
albumCount: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.ALBUM_COUNT,
|
||||
field: 'albumCount',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Albums',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.albumCount : undefined),
|
||||
width: 80,
|
||||
},
|
||||
artist: {
|
||||
cellRenderer: ArtistCell,
|
||||
colId: TableColumn.ARTIST,
|
||||
headerName: 'Artist',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.artists : undefined),
|
||||
width: 150,
|
||||
},
|
||||
biography: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'left' }),
|
||||
colId: TableColumn.BIOGRAPHY,
|
||||
field: 'biography',
|
||||
headerName: 'Biography',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.biography : ''),
|
||||
width: 200,
|
||||
},
|
||||
bitRate: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.BIT_RATE,
|
||||
field: 'bitRate',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) => `${params.value} kbps`,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bitRate : undefined),
|
||||
width: 90,
|
||||
},
|
||||
bpm: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.BPM,
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'BPM',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bpm : undefined),
|
||||
width: 60,
|
||||
},
|
||||
channels: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.CHANNELS,
|
||||
field: 'channels',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.channels : undefined),
|
||||
width: 100,
|
||||
},
|
||||
comment: {
|
||||
cellRenderer: GenericCell,
|
||||
colId: TableColumn.COMMENT,
|
||||
headerName: 'Note',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.comment : undefined),
|
||||
width: 150,
|
||||
},
|
||||
dateAdded: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.DATE_ADDED,
|
||||
field: 'createdAt',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Date Added',
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) =>
|
||||
params.value ? dayjs(params.value).format('MMM D, YYYY') : '',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.createdAt : undefined),
|
||||
width: 130,
|
||||
},
|
||||
discNumber: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.DISC_NUMBER,
|
||||
field: 'discNumber',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Disc',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.discNumber : undefined),
|
||||
width: 60,
|
||||
},
|
||||
duration: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.DURATION,
|
||||
field: 'duration',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center', preset: 'duration' }),
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) => formatDuration(params.value * 1000),
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.duration : undefined),
|
||||
width: 70,
|
||||
},
|
||||
genre: {
|
||||
cellRenderer: GenreCell,
|
||||
colId: TableColumn.GENRE,
|
||||
headerName: 'Genre',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.genres : undefined),
|
||||
width: 100,
|
||||
},
|
||||
lastPlayedAt: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.LAST_PLAYED,
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Last Played',
|
||||
valueFormatter: (params: ValueFormatterParams) =>
|
||||
params.value ? dayjs(params.value).fromNow() : '',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.lastPlayedAt : undefined,
|
||||
width: 130,
|
||||
},
|
||||
path: {
|
||||
cellRenderer: GenericCell,
|
||||
colId: TableColumn.PATH,
|
||||
headerName: 'Path',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.path : undefined),
|
||||
width: 200,
|
||||
},
|
||||
playCount: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.PLAY_COUNT,
|
||||
field: 'playCount',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Plays',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.playCount : undefined),
|
||||
width: 90,
|
||||
},
|
||||
releaseDate: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.RELEASE_DATE,
|
||||
field: 'releaseDate',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Release Date',
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) =>
|
||||
params.value ? dayjs(params.value).format('MMM D, YYYY') : '',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.releaseDate : undefined),
|
||||
width: 130,
|
||||
},
|
||||
releaseYear: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.YEAR,
|
||||
field: 'releaseYear',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Year',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.releaseYear : undefined),
|
||||
width: 80,
|
||||
},
|
||||
rowIndex: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'right' }),
|
||||
colId: TableColumn.ROW_INDEX,
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'right', preset: 'rowIndex' }),
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params) => {
|
||||
return (params.node?.rowIndex || 0) + 1;
|
||||
album: {
|
||||
cellRenderer: (params: ICellRendererParams) =>
|
||||
GenericCell(params, { isLink: true, position: 'left' }),
|
||||
colId: TableColumn.ALBUM,
|
||||
headerName: 'Album',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data
|
||||
? {
|
||||
link: generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||
albumId: params.data?.albumId || '',
|
||||
}),
|
||||
value: params.data?.album,
|
||||
}
|
||||
: undefined,
|
||||
width: 200,
|
||||
},
|
||||
albumArtist: {
|
||||
cellRenderer: AlbumArtistCell,
|
||||
colId: TableColumn.ALBUM_ARTIST,
|
||||
headerName: 'Album Artist',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.albumArtists : undefined,
|
||||
width: 150,
|
||||
},
|
||||
albumCount: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.ALBUM_COUNT,
|
||||
field: 'albumCount',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Albums',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.albumCount : undefined,
|
||||
width: 80,
|
||||
},
|
||||
artist: {
|
||||
cellRenderer: ArtistCell,
|
||||
colId: TableColumn.ARTIST,
|
||||
headerName: 'Artist',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.artists : undefined),
|
||||
width: 150,
|
||||
},
|
||||
biography: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'left' }),
|
||||
colId: TableColumn.BIOGRAPHY,
|
||||
field: 'biography',
|
||||
headerName: 'Biography',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.biography : ''),
|
||||
width: 200,
|
||||
},
|
||||
bitRate: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.BIT_RATE,
|
||||
field: 'bitRate',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) => `${params.value} kbps`,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bitRate : undefined),
|
||||
width: 90,
|
||||
},
|
||||
bpm: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.BPM,
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'BPM',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bpm : undefined),
|
||||
width: 60,
|
||||
},
|
||||
channels: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.CHANNELS,
|
||||
field: 'channels',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.channels : undefined,
|
||||
width: 100,
|
||||
},
|
||||
comment: {
|
||||
cellRenderer: GenericCell,
|
||||
colId: TableColumn.COMMENT,
|
||||
headerName: 'Note',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.comment : undefined),
|
||||
width: 150,
|
||||
},
|
||||
dateAdded: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.DATE_ADDED,
|
||||
field: 'createdAt',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Date Added',
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) =>
|
||||
params.value ? dayjs(params.value).format('MMM D, YYYY') : '',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.createdAt : undefined,
|
||||
width: 130,
|
||||
},
|
||||
discNumber: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.DISC_NUMBER,
|
||||
field: 'discNumber',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Disc',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.discNumber : undefined,
|
||||
width: 60,
|
||||
},
|
||||
duration: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.DURATION,
|
||||
field: 'duration',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center', preset: 'duration' }),
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) => formatDuration(params.value * 1000),
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.duration : undefined,
|
||||
width: 70,
|
||||
},
|
||||
genre: {
|
||||
cellRenderer: GenreCell,
|
||||
colId: TableColumn.GENRE,
|
||||
headerName: 'Genre',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.genres : undefined),
|
||||
width: 100,
|
||||
},
|
||||
lastPlayedAt: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.LAST_PLAYED,
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Last Played',
|
||||
valueFormatter: (params: ValueFormatterParams) =>
|
||||
params.value ? dayjs(params.value).fromNow() : '',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.lastPlayedAt : undefined,
|
||||
width: 130,
|
||||
},
|
||||
path: {
|
||||
cellRenderer: GenericCell,
|
||||
colId: TableColumn.PATH,
|
||||
headerName: 'Path',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.path : undefined),
|
||||
width: 200,
|
||||
},
|
||||
playCount: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.PLAY_COUNT,
|
||||
field: 'playCount',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Plays',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.playCount : undefined,
|
||||
width: 90,
|
||||
},
|
||||
releaseDate: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.RELEASE_DATE,
|
||||
field: 'releaseDate',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Release Date',
|
||||
suppressSizeToFit: true,
|
||||
valueFormatter: (params: ValueFormatterParams) =>
|
||||
params.value ? dayjs(params.value).format('MMM D, YYYY') : '',
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.releaseDate : undefined,
|
||||
width: 130,
|
||||
},
|
||||
releaseYear: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.YEAR,
|
||||
field: 'releaseYear',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Year',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.releaseYear : undefined,
|
||||
width: 80,
|
||||
},
|
||||
rowIndex: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'right' }),
|
||||
colId: TableColumn.ROW_INDEX,
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'right', preset: 'rowIndex' }),
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params) => {
|
||||
return (params.node?.rowIndex || 0) + 1;
|
||||
},
|
||||
width: 65,
|
||||
},
|
||||
songCount: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.SONG_COUNT,
|
||||
field: 'songCount',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Songs',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.songCount : undefined,
|
||||
width: 80,
|
||||
},
|
||||
title: {
|
||||
cellRenderer: (params: ICellRendererParams) =>
|
||||
GenericCell(params, { position: 'left', primary: true }),
|
||||
colId: TableColumn.TITLE,
|
||||
field: 'name',
|
||||
headerName: 'Title',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.name : undefined),
|
||||
width: 250,
|
||||
},
|
||||
titleCombined: {
|
||||
cellRenderer: CombinedTitleCell,
|
||||
colId: TableColumn.TITLE_COMBINED,
|
||||
headerName: 'Title',
|
||||
initialWidth: 500,
|
||||
minWidth: 150,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data
|
||||
? {
|
||||
albumArtists: params.data?.albumArtists,
|
||||
artists: params.data?.artists,
|
||||
imagePlaceholderUrl: params.data?.imagePlaceholderUrl,
|
||||
imageUrl: params.data?.imageUrl,
|
||||
name: params.data?.name,
|
||||
rowHeight: params.node?.rowHeight,
|
||||
type: params.data?.serverType,
|
||||
}
|
||||
: undefined,
|
||||
width: 250,
|
||||
},
|
||||
trackNumber: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.TRACK_NUMBER,
|
||||
field: 'trackNumber',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Track',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.trackNumber : undefined,
|
||||
width: 80,
|
||||
},
|
||||
userFavorite: {
|
||||
cellClass: (params) => (params.value ? 'visible ag-cell-favorite' : 'ag-cell-favorite'),
|
||||
cellRenderer: FavoriteCell,
|
||||
colId: TableColumn.USER_FAVORITE,
|
||||
field: 'userFavorite',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center', preset: 'userFavorite' }),
|
||||
headerName: 'Favorite',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.userFavorite : undefined,
|
||||
width: 50,
|
||||
},
|
||||
userRating: {
|
||||
cellClass: (params) =>
|
||||
params.value?.userRating ? 'visible ag-cell-rating' : 'ag-cell-rating',
|
||||
cellRenderer: RatingCell,
|
||||
colId: TableColumn.USER_RATING,
|
||||
field: 'userRating',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center', preset: 'userRating' }),
|
||||
headerName: 'Rating',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data : undefined),
|
||||
width: 95,
|
||||
},
|
||||
width: 65,
|
||||
},
|
||||
songCount: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.SONG_COUNT,
|
||||
field: 'songCount',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Songs',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.songCount : undefined),
|
||||
width: 80,
|
||||
},
|
||||
title: {
|
||||
cellRenderer: (params: ICellRendererParams) =>
|
||||
GenericCell(params, { position: 'left', primary: true }),
|
||||
colId: TableColumn.TITLE,
|
||||
field: 'name',
|
||||
headerName: 'Title',
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.name : undefined),
|
||||
width: 250,
|
||||
},
|
||||
titleCombined: {
|
||||
cellRenderer: CombinedTitleCell,
|
||||
colId: TableColumn.TITLE_COMBINED,
|
||||
headerName: 'Title',
|
||||
initialWidth: 500,
|
||||
minWidth: 150,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data
|
||||
? {
|
||||
albumArtists: params.data?.albumArtists,
|
||||
artists: params.data?.artists,
|
||||
imagePlaceholderUrl: params.data?.imagePlaceholderUrl,
|
||||
imageUrl: params.data?.imageUrl,
|
||||
name: params.data?.name,
|
||||
rowHeight: params.node?.rowHeight,
|
||||
type: params.data?.serverType,
|
||||
}
|
||||
: undefined,
|
||||
width: 250,
|
||||
},
|
||||
trackNumber: {
|
||||
cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }),
|
||||
colId: TableColumn.TRACK_NUMBER,
|
||||
field: 'trackNumber',
|
||||
headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }),
|
||||
headerName: 'Track',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data.trackNumber : undefined),
|
||||
width: 80,
|
||||
},
|
||||
userFavorite: {
|
||||
cellClass: (params) => (params.value ? 'visible ag-cell-favorite' : 'ag-cell-favorite'),
|
||||
cellRenderer: FavoriteCell,
|
||||
colId: TableColumn.USER_FAVORITE,
|
||||
field: 'userFavorite',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center', preset: 'userFavorite' }),
|
||||
headerName: 'Favorite',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) =>
|
||||
params.data ? params.data.userFavorite : undefined,
|
||||
width: 50,
|
||||
},
|
||||
userRating: {
|
||||
cellClass: (params) => (params.value?.userRating ? 'visible ag-cell-rating' : 'ag-cell-rating'),
|
||||
cellRenderer: RatingCell,
|
||||
colId: TableColumn.USER_RATING,
|
||||
field: 'userRating',
|
||||
headerComponent: (params: IHeaderParams) =>
|
||||
GenericTableHeader(params, { position: 'center', preset: 'userRating' }),
|
||||
headerName: 'Rating',
|
||||
suppressSizeToFit: true,
|
||||
valueGetter: (params: ValueGetterParams) => (params.data ? params.data : undefined),
|
||||
width: 95,
|
||||
},
|
||||
};
|
||||
|
||||
export const getColumnDef = (column: TableColumn) => {
|
||||
return tableColumns[column as keyof typeof tableColumns];
|
||||
return tableColumns[column as keyof typeof tableColumns];
|
||||
};
|
||||
|
||||
export const getColumnDefs = (columns: PersistedTableColumn[]) => {
|
||||
const columnDefs: ColDef[] = [];
|
||||
for (const column of columns) {
|
||||
const presetColumn = tableColumns[column.column as keyof typeof tableColumns];
|
||||
if (presetColumn) {
|
||||
columnDefs.push({
|
||||
...presetColumn,
|
||||
initialWidth: column.width,
|
||||
...column.extraProps,
|
||||
});
|
||||
const columnDefs: ColDef[] = [];
|
||||
for (const column of columns) {
|
||||
const presetColumn = tableColumns[column.column as keyof typeof tableColumns];
|
||||
if (presetColumn) {
|
||||
columnDefs.push({
|
||||
...presetColumn,
|
||||
initialWidth: column.width,
|
||||
...column.extraProps,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return columnDefs;
|
||||
return columnDefs;
|
||||
};
|
||||
|
||||
interface VirtualTableProps extends AgGridReactProps {
|
||||
autoFitColumns?: boolean;
|
||||
autoHeight?: boolean;
|
||||
deselectOnClickOutside?: boolean;
|
||||
transparentHeader?: boolean;
|
||||
autoFitColumns?: boolean;
|
||||
autoHeight?: boolean;
|
||||
deselectOnClickOutside?: boolean;
|
||||
transparentHeader?: boolean;
|
||||
}
|
||||
|
||||
export const VirtualTable = forwardRef(
|
||||
(
|
||||
{
|
||||
autoFitColumns,
|
||||
deselectOnClickOutside,
|
||||
autoHeight,
|
||||
transparentHeader,
|
||||
onColumnMoved,
|
||||
onNewColumnsLoaded,
|
||||
onGridReady,
|
||||
onGridSizeChanged,
|
||||
...rest
|
||||
}: VirtualTableProps,
|
||||
ref: Ref<AgGridReactType | null>,
|
||||
) => {
|
||||
const tableRef = useRef<AgGridReactType | null>(null);
|
||||
(
|
||||
{
|
||||
autoFitColumns,
|
||||
deselectOnClickOutside,
|
||||
autoHeight,
|
||||
transparentHeader,
|
||||
onColumnMoved,
|
||||
onNewColumnsLoaded,
|
||||
onGridReady,
|
||||
onGridSizeChanged,
|
||||
...rest
|
||||
}: VirtualTableProps,
|
||||
ref: Ref<AgGridReactType | null>,
|
||||
) => {
|
||||
const tableRef = useRef<AgGridReactType | null>(null);
|
||||
|
||||
const mergedRef = useMergedRef(ref, tableRef);
|
||||
const mergedRef = useMergedRef(ref, tableRef);
|
||||
|
||||
const deselectRef = useClickOutside(() => {
|
||||
if (tableRef?.current?.api && deselectOnClickOutside) {
|
||||
tableRef?.current?.api?.deselectAll();
|
||||
}
|
||||
});
|
||||
const deselectRef = useClickOutside(() => {
|
||||
if (tableRef?.current?.api && deselectOnClickOutside) {
|
||||
tableRef?.current?.api?.deselectAll();
|
||||
}
|
||||
});
|
||||
|
||||
const defaultColumnDefs: ColDef = useMemo(() => {
|
||||
return {
|
||||
lockPinned: true,
|
||||
lockVisible: true,
|
||||
resizable: true,
|
||||
};
|
||||
}, []);
|
||||
const defaultColumnDefs: ColDef = useMemo(() => {
|
||||
return {
|
||||
lockPinned: true,
|
||||
lockVisible: true,
|
||||
resizable: true,
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Auto fit columns on column change
|
||||
useEffect(() => {
|
||||
if (!tableRef?.current?.api) return;
|
||||
if (autoFitColumns && tableRef?.current?.api) {
|
||||
tableRef?.current?.api?.sizeColumnsToFit?.();
|
||||
}
|
||||
}, [autoFitColumns]);
|
||||
// Auto fit columns on column change
|
||||
useEffect(() => {
|
||||
if (!tableRef?.current?.api) return;
|
||||
if (autoFitColumns && tableRef?.current?.api) {
|
||||
tableRef?.current?.api?.sizeColumnsToFit?.();
|
||||
}
|
||||
}, [autoFitColumns]);
|
||||
|
||||
// Reset row heights on row height change
|
||||
useEffect(() => {
|
||||
if (!tableRef?.current?.api) return;
|
||||
tableRef?.current?.api?.resetRowHeights();
|
||||
tableRef?.current?.api?.redrawRows();
|
||||
}, [rest.rowHeight]);
|
||||
// Reset row heights on row height change
|
||||
useEffect(() => {
|
||||
if (!tableRef?.current?.api) return;
|
||||
tableRef?.current?.api?.resetRowHeights();
|
||||
tableRef?.current?.api?.redrawRows();
|
||||
}, [rest.rowHeight]);
|
||||
|
||||
const handleColumnMoved = useCallback(
|
||||
(e: ColumnMovedEvent) => {
|
||||
if (!e?.api) return;
|
||||
onColumnMoved?.(e);
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns, onColumnMoved],
|
||||
);
|
||||
const handleColumnMoved = useCallback(
|
||||
(e: ColumnMovedEvent) => {
|
||||
if (!e?.api) return;
|
||||
onColumnMoved?.(e);
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns, onColumnMoved],
|
||||
);
|
||||
|
||||
const handleNewColumnsLoaded = useCallback(
|
||||
(e: NewColumnsLoadedEvent) => {
|
||||
if (!e?.api) return;
|
||||
onNewColumnsLoaded?.(e);
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns, onNewColumnsLoaded],
|
||||
);
|
||||
const handleNewColumnsLoaded = useCallback(
|
||||
(e: NewColumnsLoadedEvent) => {
|
||||
if (!e?.api) return;
|
||||
onNewColumnsLoaded?.(e);
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns, onNewColumnsLoaded],
|
||||
);
|
||||
|
||||
const handleGridReady = useCallback(
|
||||
(e: GridReadyEvent) => {
|
||||
if (!e?.api) return;
|
||||
onGridReady?.(e);
|
||||
if (autoHeight) e.api.setDomLayout('autoHeight');
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoHeight, autoFitColumns, onGridReady],
|
||||
);
|
||||
const handleGridReady = useCallback(
|
||||
(e: GridReadyEvent) => {
|
||||
if (!e?.api) return;
|
||||
onGridReady?.(e);
|
||||
if (autoHeight) e.api.setDomLayout('autoHeight');
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoHeight, autoFitColumns, onGridReady],
|
||||
);
|
||||
|
||||
const handleGridSizeChanged = useCallback(
|
||||
(e: GridSizeChangedEvent) => {
|
||||
if (!e?.api) return;
|
||||
onGridSizeChanged?.(e);
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns, onGridSizeChanged],
|
||||
);
|
||||
const handleGridSizeChanged = useCallback(
|
||||
(e: GridSizeChangedEvent) => {
|
||||
if (!e?.api) return;
|
||||
onGridSizeChanged?.(e);
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns, onGridSizeChanged],
|
||||
);
|
||||
|
||||
const handleModelUpdated = useCallback(
|
||||
(e: ModelUpdatedEvent) => {
|
||||
if (!e?.api) return;
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns],
|
||||
);
|
||||
const handleModelUpdated = useCallback(
|
||||
(e: ModelUpdatedEvent) => {
|
||||
if (!e?.api) return;
|
||||
if (autoFitColumns) e.api?.sizeColumnsToFit?.();
|
||||
},
|
||||
[autoFitColumns],
|
||||
);
|
||||
|
||||
return (
|
||||
<TableWrapper
|
||||
ref={deselectRef}
|
||||
className={
|
||||
transparentHeader ? 'ag-header-transparent ag-theme-alpine-dark' : 'ag-theme-alpine-dark'
|
||||
}
|
||||
>
|
||||
<AgGridReact
|
||||
ref={mergedRef}
|
||||
animateRows
|
||||
maintainColumnOrder
|
||||
suppressAsyncEvents
|
||||
suppressContextMenu
|
||||
suppressCopyRowsToClipboard
|
||||
suppressMoveWhenRowDragging
|
||||
suppressPaginationPanel
|
||||
suppressScrollOnNewData
|
||||
blockLoadDebounceMillis={200}
|
||||
cacheBlockSize={300}
|
||||
cacheOverflowSize={1}
|
||||
defaultColDef={defaultColumnDefs}
|
||||
enableCellChangeFlash={false}
|
||||
headerHeight={36}
|
||||
rowBuffer={30}
|
||||
rowSelection="multiple"
|
||||
{...rest}
|
||||
onColumnMoved={handleColumnMoved}
|
||||
onGridReady={handleGridReady}
|
||||
onGridSizeChanged={handleGridSizeChanged}
|
||||
onModelUpdated={handleModelUpdated}
|
||||
onNewColumnsLoaded={handleNewColumnsLoaded}
|
||||
/>
|
||||
</TableWrapper>
|
||||
);
|
||||
},
|
||||
return (
|
||||
<TableWrapper
|
||||
ref={deselectRef}
|
||||
className={
|
||||
transparentHeader
|
||||
? 'ag-header-transparent ag-theme-alpine-dark'
|
||||
: 'ag-theme-alpine-dark'
|
||||
}
|
||||
>
|
||||
<AgGridReact
|
||||
ref={mergedRef}
|
||||
animateRows
|
||||
maintainColumnOrder
|
||||
suppressAsyncEvents
|
||||
suppressContextMenu
|
||||
suppressCopyRowsToClipboard
|
||||
suppressMoveWhenRowDragging
|
||||
suppressPaginationPanel
|
||||
suppressScrollOnNewData
|
||||
blockLoadDebounceMillis={200}
|
||||
cacheBlockSize={300}
|
||||
cacheOverflowSize={1}
|
||||
defaultColDef={defaultColumnDefs}
|
||||
enableCellChangeFlash={false}
|
||||
headerHeight={36}
|
||||
rowBuffer={30}
|
||||
rowSelection="multiple"
|
||||
{...rest}
|
||||
onColumnMoved={handleColumnMoved}
|
||||
onGridReady={handleGridReady}
|
||||
onGridSizeChanged={handleGridSizeChanged}
|
||||
onModelUpdated={handleModelUpdated}
|
||||
onNewColumnsLoaded={handleNewColumnsLoaded}
|
||||
/>
|
||||
</TableWrapper>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue