remove ag-grid

This commit is contained in:
jeffvli
2025-11-15 20:07:42 -08:00
parent b5eadb64a1
commit 0de8035ca9
15 changed files with 19 additions and 561 deletions
-74
View File
@@ -1,74 +0,0 @@
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
import { ChangeEvent, MutableRefObject, useCallback } from 'react';
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid/virtual-infinite-grid';
import { useListContext } from '/@/renderer/context/list-context';
import {
UseHandleListFilterChangeProps,
useListFilterRefresh,
} from '/@/renderer/hooks/use-list-filter-refresh';
import { useListStoreActions, useListStoreByKey } from '/@/renderer/store';
import { ListDisplayType } from '/@/shared/types/types';
export type UseDisplayRefreshProps = UseHandleListFilterChangeProps & {
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
itemCount?: number;
tableRef: MutableRefObject<AgGridReactType | null>;
};
export const useDisplayRefresh = <TFilter>({
gridRef,
isClientSideSort,
itemCount,
itemType,
server,
tableRef,
}: UseDisplayRefreshProps) => {
const { customFilters, handlePlay, pageKey } = useListContext();
const { display, filter } = useListStoreByKey<TFilter>({ key: pageKey });
const { handleRefreshGrid, handleRefreshTable } = useListFilterRefresh({
isClientSideSort,
itemCount,
itemType,
server,
});
const { setFilter, setTablePagination } = useListStoreActions();
const refresh = useCallback(
(filter: unknown) => {
if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) {
handleRefreshTable(tableRef, filter);
setTablePagination({ data: { currentPage: 0 }, key: pageKey });
} else {
handleRefreshGrid(gridRef, filter);
}
},
[
display,
gridRef,
handleRefreshGrid,
handleRefreshTable,
pageKey,
setTablePagination,
tableRef,
],
);
const search = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
const searchTerm = e.target.value === '' ? undefined : e.target.value;
const updatedFilters = setFilter({
customFilters,
data: { searchTerm },
itemType,
key: pageKey,
});
return updatedFilters;
},
[customFilters, itemType, pageKey, setFilter],
);
return { customFilters, filter, handlePlay, refresh, search };
};
@@ -1,177 +0,0 @@
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
import { IDatasource } from '@ag-grid-community/core';
import { QueryKey, useQueryClient } from '@tanstack/react-query';
import orderBy from 'lodash/orderBy';
import { MutableRefObject, useCallback, useMemo } from 'react';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid/virtual-infinite-grid';
import { BasePaginatedResponse, LibraryItem, ServerListItem } from '/@/shared/types/domain-types';
export interface UseHandleListFilterChangeProps {
isClientSideSort?: boolean;
itemCount?: number;
itemType: LibraryItem;
server: null | ServerListItem;
}
const BLOCK_SIZE = 500;
export const useListFilterRefresh = ({
isClientSideSort,
itemCount,
itemType,
server,
}: UseHandleListFilterChangeProps) => {
const queryClient = useQueryClient();
const queryKeyFn: ((serverId: string, query: Record<any, any>) => QueryKey) | null =
useMemo(() => {
switch (itemType) {
case LibraryItem.ALBUM:
return queryKeys.albums.list;
case LibraryItem.ALBUM_ARTIST:
return queryKeys.albumArtists.list;
case LibraryItem.ARTIST:
return queryKeys.artists.list;
case LibraryItem.GENRE:
return queryKeys.genres.list;
case LibraryItem.PLAYLIST:
return queryKeys.playlists.list;
case LibraryItem.SONG:
return queryKeys.songs.list;
default:
return null;
}
}, [itemType]);
const queryFn: ((args: any) => Promise<BasePaginatedResponse<any> | null | undefined>) | null =
useMemo(() => {
switch (itemType) {
case LibraryItem.ALBUM:
return api.controller.getAlbumList;
case LibraryItem.ALBUM_ARTIST:
return api.controller.getAlbumArtistList;
case LibraryItem.ARTIST:
return api.controller.getArtistList;
case LibraryItem.GENRE:
return api.controller.getGenreList;
case LibraryItem.PLAYLIST:
return api.controller.getPlaylistList;
case LibraryItem.SONG:
return api.controller.getSongList;
default:
return null;
}
}, [itemType]);
const handleRefreshTable = useCallback(
async (tableRef: MutableRefObject<AgGridReactType | null>, filter: any) => {
if (!tableRef || !queryKeyFn || !queryFn) {
return;
}
const dataSource: IDatasource = {
getRows: async (params) => {
const limit = params.endRow - params.startRow;
const startIndex = params.startRow;
const query = { ...filter, limit, startIndex };
const queryKey = queryKeyFn(server?.id || '', query);
const results = await queryClient.fetchQuery({
queryFn: async ({ signal }) => {
return queryFn({
apiClientProps: {
serverId: server?.id || '',
signal,
},
query,
});
},
queryKey,
});
if (isClientSideSort && results?.items) {
const sortedResults = orderBy(
results.items,
[(item) => String(item[filter.sortBy]).toLowerCase()],
filter.sortOrder === 'DESC' ? ['desc'] : ['asc'],
);
params.successCallback(
sortedResults || [],
results?.totalRecordCount || itemCount,
);
return;
}
if (results?.totalRecordCount === null) {
const hasMoreRows = results?.items?.length === BLOCK_SIZE;
const lastRowIndex = hasMoreRows
? undefined
: (filter.offset || 0) + results.items.length;
params.successCallback(
results?.items || [],
hasMoreRows ? undefined : lastRowIndex,
);
return;
}
params.successCallback(results?.items || [], results?.totalRecordCount || 0);
},
rowCount: undefined,
};
tableRef.current?.api.setDatasource(dataSource);
tableRef.current?.api.purgeInfiniteCache();
tableRef.current?.api.ensureIndexVisible(0, 'top');
},
[isClientSideSort, itemCount, queryClient, queryFn, queryKeyFn, server],
);
const handleRefreshGrid = useCallback(
async (gridRef: MutableRefObject<null | VirtualInfiniteGridRef>, filter: any) => {
if (!gridRef || !queryKeyFn || !queryFn) {
return;
}
gridRef.current?.scrollTo(0);
gridRef.current?.resetLoadMoreItemsCache();
const query = { ...filter, limit: 200, startIndex: 0 };
const queryKey = queryKeyFn(server?.id || '', query);
const res = await queryClient.fetchQuery({
queryFn: async ({ signal }) => {
return queryFn({
apiClientProps: {
serverId: server?.id || '',
signal,
},
query,
});
},
queryKey,
});
if (!res?.items) {
return;
}
gridRef.current?.setItemData(res.items);
},
[queryClient, queryFn, queryKeyFn, server],
);
return {
handleRefreshGrid,
handleRefreshTable,
};
};
-73
View File
@@ -1,73 +0,0 @@
import { RowNode } from '@ag-grid-community/core';
import { AgGridReact } from '@ag-grid-community/react';
import { MutableRefObject, useCallback, useEffect } from 'react';
import { useEventStore, UserEvent } from '/@/renderer/store/event.store';
import { Song } from '/@/shared/types/domain-types';
export const useSongChange = (
handler: (ids: string[], event: UserEvent) => void,
enabled: boolean,
) => {
useEffect(() => {
if (!enabled) return () => {};
const unSub = useEventStore.subscribe((state) => {
if (state.event) {
handler(state.ids, state.event);
}
});
return () => {
unSub();
};
}, [handler, enabled]);
};
export const useTableChange = (
tableRef: MutableRefObject<AgGridReact | null>,
enabled: boolean,
) => {
const handler = useCallback(
(ids: string[], event: UserEvent) => {
const api = tableRef.current?.api;
if (!api) return;
const idSet = new Set(ids);
api.forEachNode((node: RowNode<Song>) => {
if (!node.data || !idSet.has(node.data.id)) return;
// Make sure to use setData instead of setDataValue. setDataValue
// will error if the column does not exist, whereas setData won't care
switch (event.event) {
case 'favorite': {
if (node.data.userFavorite !== event.favorite) {
node.setData({ ...node.data, userFavorite: event.favorite });
}
break;
}
case 'play':
if (node.data.lastPlayedAt !== event.timestamp) {
node.setData({
...node.data,
lastPlayedAt: event.timestamp,
playCount: node.data.playCount + 1,
});
}
node.data.lastPlayedAt = event.timestamp;
break;
case 'rating': {
if (node.data.userRating !== event.rating) {
node.setData({ ...node.data, userRating: event.rating });
}
break;
}
}
});
},
[tableRef],
);
useSongChange(handler, enabled);
};