Add actions table column

This commit is contained in:
jeffvli 2023-07-18 17:37:32 -07:00
parent 817675ee0e
commit 179129b7cb
6 changed files with 79 additions and 24 deletions

View file

@ -0,0 +1,22 @@
import type { ICellRendererParams } from '@ag-grid-community/core';
import { RiMoreFill } from 'react-icons/ri';
import { Button } from '/@/renderer/components/button';
import { CellContainer } from '/@/renderer/components/virtual-table/cells/generic-cell';
export const ActionsCell = ({ context, api }: ICellRendererParams) => {
return (
<CellContainer position="center">
<Button
compact
variant="subtle"
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
context.onCellContextMenu(undefined, api, e);
}}
>
<RiMoreFill />
</Button>
</CellContainer>
);
};

View file

@ -2,11 +2,11 @@ import type { ReactNode } from 'react';
import type { IHeaderParams } from '@ag-grid-community/core'; import type { IHeaderParams } from '@ag-grid-community/core';
import { AiOutlineNumber } from 'react-icons/ai'; import { AiOutlineNumber } from 'react-icons/ai';
import { FiClock } from 'react-icons/fi'; import { FiClock } from 'react-icons/fi';
import { RiHeartLine, RiStarLine } from 'react-icons/ri'; import { RiHeartLine, RiMoreFill, RiStarLine } from 'react-icons/ri';
import styled from 'styled-components'; import styled from 'styled-components';
import { _Text } from '/@/renderer/components/text'; import { _Text } from '/@/renderer/components/text';
type Presets = 'duration' | 'rowIndex' | 'userFavorite' | 'userRating'; type Presets = 'duration' | 'rowIndex' | 'userFavorite' | 'userRating' | 'actions';
type Options = { type Options = {
children?: ReactNode; children?: ReactNode;
@ -41,6 +41,12 @@ const TextHeaderWrapper = styled(_Text)<{ position: Options['position'] }>`
`; `;
const headerPresets = { const headerPresets = {
actions: (
<RiMoreFill
color="var(--ag-header-foreground-color)"
size="1em"
/>
),
duration: ( duration: (
<FiClock <FiClock
color="var(--ag-header-foreground-color)" color="var(--ag-header-foreground-color)"

View file

@ -33,6 +33,7 @@ import { TableColumn, TablePagination as TablePaginationType } from '/@/renderer
import { FavoriteCell } from '/@/renderer/components/virtual-table/cells/favorite-cell'; import { FavoriteCell } from '/@/renderer/components/virtual-table/cells/favorite-cell';
import { RatingCell } from '/@/renderer/components/virtual-table/cells/rating-cell'; import { RatingCell } from '/@/renderer/components/virtual-table/cells/rating-cell';
import { TablePagination } from '/@/renderer/components/virtual-table/table-pagination'; import { TablePagination } from '/@/renderer/components/virtual-table/table-pagination';
import { ActionsCell } from '/@/renderer/components/virtual-table/cells/actions-cell';
export * from './table-config-dropdown'; export * from './table-config-dropdown';
export * from './table-pagination'; export * from './table-pagination';
@ -50,6 +51,14 @@ const TableWrapper = styled.div`
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
const tableColumns: { [key: string]: ColDef } = { const tableColumns: { [key: string]: ColDef } = {
actions: {
cellClass: 'ag-cell-favorite',
cellRenderer: (params: ICellRendererParams) => ActionsCell(params),
colId: TableColumn.ACTIONS,
headerComponent: () => <></>,
suppressSizeToFit: true,
width: 25,
},
album: { album: {
cellRenderer: (params: ICellRendererParams) => cellRenderer: (params: ICellRendererParams) =>
GenericCell(params, { isLink: true, position: 'left' }), GenericCell(params, { isLink: true, position: 'left' }),

View file

@ -35,6 +35,7 @@ export const SONG_TABLE_COLUMNS = [
{ label: 'Size', value: TableColumn.SIZE }, { label: 'Size', value: TableColumn.SIZE },
{ label: 'Favorite', value: TableColumn.USER_FAVORITE }, { label: 'Favorite', value: TableColumn.USER_FAVORITE },
{ label: 'Rating', value: TableColumn.USER_RATING }, { label: 'Rating', value: TableColumn.USER_RATING },
{ label: 'Actions', value: TableColumn.ACTIONS },
// { label: 'Skip', value: TableColumn.SKIP }, // { label: 'Skip', value: TableColumn.SKIP },
]; ];
@ -53,6 +54,7 @@ export const ALBUM_TABLE_COLUMNS = [
{ label: 'Plays', value: TableColumn.PLAY_COUNT }, { label: 'Plays', value: TableColumn.PLAY_COUNT },
{ label: 'Favorite', value: TableColumn.USER_FAVORITE }, { label: 'Favorite', value: TableColumn.USER_FAVORITE },
{ label: 'Rating', value: TableColumn.USER_RATING }, { label: 'Rating', value: TableColumn.USER_RATING },
{ label: 'Actions', value: TableColumn.ACTIONS },
]; ];
export const ALBUMARTIST_TABLE_COLUMNS = [ export const ALBUMARTIST_TABLE_COLUMNS = [
@ -68,6 +70,7 @@ export const ALBUMARTIST_TABLE_COLUMNS = [
{ label: 'Song Count', value: TableColumn.SONG_COUNT }, { label: 'Song Count', value: TableColumn.SONG_COUNT },
{ label: 'Favorite', value: TableColumn.USER_FAVORITE }, { label: 'Favorite', value: TableColumn.USER_FAVORITE },
{ label: 'Rating', value: TableColumn.USER_RATING }, { label: 'Rating', value: TableColumn.USER_RATING },
{ label: 'Actions', value: TableColumn.ACTIONS },
]; ];
export const PLAYLIST_TABLE_COLUMNS = [ export const PLAYLIST_TABLE_COLUMNS = [
@ -78,6 +81,7 @@ export const PLAYLIST_TABLE_COLUMNS = [
{ label: 'Owner', value: TableColumn.OWNER }, { label: 'Owner', value: TableColumn.OWNER },
// { label: 'Genre', value: TableColumn.GENRE }, // { label: 'Genre', value: TableColumn.GENRE },
{ label: 'Song Count', value: TableColumn.SONG_COUNT }, { label: 'Song Count', value: TableColumn.SONG_COUNT },
{ label: 'Actions', value: TableColumn.ACTIONS },
]; ];
interface TableConfigDropdownProps { interface TableConfigDropdownProps {

View file

@ -1,4 +1,4 @@
import { CellContextMenuEvent } from '@ag-grid-community/core'; import { CellContextMenuEvent, GridApi } from '@ag-grid-community/core';
import sortBy from 'lodash/sortBy'; import sortBy from 'lodash/sortBy';
import { Album, AlbumArtist, Artist, LibraryItem, QueueSong, Song } from '/@/renderer/api/types'; import { Album, AlbumArtist, Artist, LibraryItem, QueueSong, Song } from '/@/renderer/api/types';
import { openContextMenu, SetContextMenuItems } from '/@/renderer/features/context-menu/events'; import { openContextMenu, SetContextMenuItems } from '/@/renderer/features/context-menu/events';
@ -8,27 +8,40 @@ export const useHandleTableContextMenu = (
contextMenuItems: SetContextMenuItems, contextMenuItems: SetContextMenuItems,
context?: any, context?: any,
) => { ) => {
const handleContextMenu = (e: CellContextMenuEvent) => { const handleContextMenu = (
if (!e.event) return; e?: CellContextMenuEvent,
const clickEvent = e.event as MouseEvent; gridApi?: GridApi<any>,
clickEvent.preventDefault(); click?: MouseEvent,
) => {
let selectedNodes = sortBy(e.api.getSelectedNodes(), ['rowIndex']); let clickEvent: MouseEvent | undefined = click;
let selectedRows = selectedNodes.map((node) => node.data); if (e) {
if (!e?.event) return;
if (!e.data?.id) { clickEvent = e?.event as MouseEvent;
return; clickEvent.preventDefault();
} }
const shouldReplaceSelected = !selectedNodes const api = gridApi || e?.api;
.map((node) => node.data.id)
.includes(e.data.id);
if (shouldReplaceSelected) { console.log('api :>> ', api);
e.api.deselectAll();
e.node.setSelected(true); if (!api) return;
selectedRows = [e.data];
selectedNodes = e.api.getSelectedNodes(); let selectedNodes = sortBy(api.getSelectedNodes(), ['rowIndex']);
let selectedRows = selectedNodes.map((node) => node.data);
if (e) {
if (!e.data?.id) return;
const shouldReplaceSelected = !selectedNodes
.map((node) => node.data.id)
.includes(e.data.id);
if (shouldReplaceSelected) {
e.api.deselectAll();
e.node.setSelected(true);
selectedRows = [e.data];
selectedNodes = e.api.getSelectedNodes();
}
} }
openContextMenu({ openContextMenu({
@ -36,10 +49,10 @@ export const useHandleTableContextMenu = (
data: selectedRows, data: selectedRows,
dataNodes: selectedNodes, dataNodes: selectedNodes,
menuItems: contextMenuItems, menuItems: contextMenuItems,
tableApi: e.api, tableApi: api,
type: itemType, type: itemType,
xPos: clickEvent.clientX, xPos: clickEvent?.clientX || 0,
yPos: clickEvent.clientY, yPos: clickEvent?.clientY || 0,
}); });
}; };

View file

@ -127,6 +127,7 @@ export type QueryBuilderGroup = {
}; };
export enum TableColumn { export enum TableColumn {
ACTIONS = 'actions',
ALBUM = 'album', ALBUM = 'album',
ALBUM_ARTIST = 'albumArtist', ALBUM_ARTIST = 'albumArtist',
ALBUM_COUNT = 'albumCount', ALBUM_COUNT = 'albumCount',