Add actions table column
This commit is contained in:
parent
817675ee0e
commit
179129b7cb
6 changed files with 79 additions and 24 deletions
22
src/renderer/components/virtual-table/cells/actions-cell.tsx
Normal file
22
src/renderer/components/virtual-table/cells/actions-cell.tsx
Normal 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>
|
||||
);
|
||||
};
|
|
@ -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: (
|
||||
<RiMoreFill
|
||||
color="var(--ag-header-foreground-color)"
|
||||
size="1em"
|
||||
/>
|
||||
),
|
||||
duration: (
|
||||
<FiClock
|
||||
color="var(--ag-header-foreground-color)"
|
||||
|
|
|
@ -33,6 +33,7 @@ import { TableColumn, TablePagination as TablePaginationType } from '/@/renderer
|
|||
import { FavoriteCell } from '/@/renderer/components/virtual-table/cells/favorite-cell';
|
||||
import { RatingCell } from '/@/renderer/components/virtual-table/cells/rating-cell';
|
||||
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-pagination';
|
||||
|
@ -50,6 +51,14 @@ const TableWrapper = styled.div`
|
|||
dayjs.extend(relativeTime);
|
||||
|
||||
const tableColumns: { [key: string]: ColDef } = {
|
||||
actions: {
|
||||
cellClass: 'ag-cell-favorite',
|
||||
cellRenderer: (params: ICellRendererParams) => ActionsCell(params),
|
||||
colId: TableColumn.ACTIONS,
|
||||
headerComponent: () => <></>,
|
||||
suppressSizeToFit: true,
|
||||
width: 25,
|
||||
},
|
||||
album: {
|
||||
cellRenderer: (params: ICellRendererParams) =>
|
||||
GenericCell(params, { isLink: true, position: 'left' }),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<any>,
|
||||
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,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ export type QueryBuilderGroup = {
|
|||
};
|
||||
|
||||
export enum TableColumn {
|
||||
ACTIONS = 'actions',
|
||||
ALBUM = 'album',
|
||||
ALBUM_ARTIST = 'albumArtist',
|
||||
ALBUM_COUNT = 'albumCount',
|
||||
|
|
Reference in a new issue