diff --git a/src/renderer/components/virtual-table/cells/actions-cell.tsx b/src/renderer/components/virtual-table/cells/actions-cell.tsx new file mode 100644 index 00000000..9660f743 --- /dev/null +++ b/src/renderer/components/virtual-table/cells/actions-cell.tsx @@ -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 ( + + + + ); +}; diff --git a/src/renderer/components/virtual-table/headers/generic-table-header.tsx b/src/renderer/components/virtual-table/headers/generic-table-header.tsx index ce209102..c85fa2b7 100644 --- a/src/renderer/components/virtual-table/headers/generic-table-header.tsx +++ b/src/renderer/components/virtual-table/headers/generic-table-header.tsx @@ -2,11 +2,11 @@ import type { ReactNode } from 'react'; import type { IHeaderParams } from '@ag-grid-community/core'; import { AiOutlineNumber } from 'react-icons/ai'; 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 { _Text } from '/@/renderer/components/text'; -type Presets = 'duration' | 'rowIndex' | 'userFavorite' | 'userRating'; +type Presets = 'duration' | 'rowIndex' | 'userFavorite' | 'userRating' | 'actions'; type Options = { children?: ReactNode; @@ -41,6 +41,12 @@ const TextHeaderWrapper = styled(_Text)<{ position: Options['position'] }>` `; const headerPresets = { + actions: ( + + ), duration: ( ActionsCell(params), + colId: TableColumn.ACTIONS, + headerComponent: () => <>, + suppressSizeToFit: true, + width: 25, + }, album: { cellRenderer: (params: ICellRendererParams) => GenericCell(params, { isLink: true, position: 'left' }), diff --git a/src/renderer/components/virtual-table/table-config-dropdown.tsx b/src/renderer/components/virtual-table/table-config-dropdown.tsx index 3b73c6b9..c7464852 100644 --- a/src/renderer/components/virtual-table/table-config-dropdown.tsx +++ b/src/renderer/components/virtual-table/table-config-dropdown.tsx @@ -35,6 +35,7 @@ export const SONG_TABLE_COLUMNS = [ { label: 'Size', value: TableColumn.SIZE }, { label: 'Favorite', value: TableColumn.USER_FAVORITE }, { label: 'Rating', value: TableColumn.USER_RATING }, + { label: 'Actions', value: TableColumn.ACTIONS }, // { label: 'Skip', value: TableColumn.SKIP }, ]; @@ -53,6 +54,7 @@ export const ALBUM_TABLE_COLUMNS = [ { label: 'Plays', value: TableColumn.PLAY_COUNT }, { label: 'Favorite', value: TableColumn.USER_FAVORITE }, { label: 'Rating', value: TableColumn.USER_RATING }, + { label: 'Actions', value: TableColumn.ACTIONS }, ]; export const ALBUMARTIST_TABLE_COLUMNS = [ @@ -68,6 +70,7 @@ export const ALBUMARTIST_TABLE_COLUMNS = [ { label: 'Song Count', value: TableColumn.SONG_COUNT }, { label: 'Favorite', value: TableColumn.USER_FAVORITE }, { label: 'Rating', value: TableColumn.USER_RATING }, + { label: 'Actions', value: TableColumn.ACTIONS }, ]; export const PLAYLIST_TABLE_COLUMNS = [ @@ -78,6 +81,7 @@ export const PLAYLIST_TABLE_COLUMNS = [ { label: 'Owner', value: TableColumn.OWNER }, // { label: 'Genre', value: TableColumn.GENRE }, { label: 'Song Count', value: TableColumn.SONG_COUNT }, + { label: 'Actions', value: TableColumn.ACTIONS }, ]; interface TableConfigDropdownProps { diff --git a/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts b/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts index 0f54172a..ff1d8c80 100644 --- a/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts +++ b/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts @@ -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 { Album, AlbumArtist, Artist, LibraryItem, QueueSong, Song } from '/@/renderer/api/types'; import { openContextMenu, SetContextMenuItems } from '/@/renderer/features/context-menu/events'; @@ -8,27 +8,40 @@ export const useHandleTableContextMenu = ( contextMenuItems: SetContextMenuItems, context?: any, ) => { - const handleContextMenu = (e: CellContextMenuEvent) => { - if (!e.event) return; - const clickEvent = e.event as MouseEvent; - clickEvent.preventDefault(); - - let selectedNodes = sortBy(e.api.getSelectedNodes(), ['rowIndex']); - let selectedRows = selectedNodes.map((node) => node.data); - - if (!e.data?.id) { - return; + const handleContextMenu = ( + e?: CellContextMenuEvent, + gridApi?: GridApi, + click?: MouseEvent, + ) => { + let clickEvent: MouseEvent | undefined = click; + if (e) { + if (!e?.event) return; + clickEvent = e?.event as MouseEvent; + clickEvent.preventDefault(); } - const shouldReplaceSelected = !selectedNodes - .map((node) => node.data.id) - .includes(e.data.id); + const api = gridApi || e?.api; - if (shouldReplaceSelected) { - e.api.deselectAll(); - e.node.setSelected(true); - selectedRows = [e.data]; - selectedNodes = e.api.getSelectedNodes(); + console.log('api :>> ', api); + + if (!api) return; + + 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({ @@ -36,10 +49,10 @@ export const useHandleTableContextMenu = ( data: selectedRows, dataNodes: selectedNodes, menuItems: contextMenuItems, - tableApi: e.api, + tableApi: api, type: itemType, - xPos: clickEvent.clientX, - yPos: clickEvent.clientY, + xPos: clickEvent?.clientX || 0, + yPos: clickEvent?.clientY || 0, }); }; diff --git a/src/renderer/types.ts b/src/renderer/types.ts index 8952a424..cf0263ec 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -127,6 +127,7 @@ export type QueryBuilderGroup = { }; export enum TableColumn { + ACTIONS = 'actions', ALBUM = 'album', ALBUM_ARTIST = 'albumArtist', ALBUM_COUNT = 'albumCount',