Add album grouping column (#1722)

* Add album grouping column

---------

Co-authored-by: jeffvli <jeffvictorli@gmail.com>
This commit is contained in:
Norman
2026-02-26 20:34:55 -08:00
committed by GitHub
parent 4918b412b2
commit eb8913479b
18 changed files with 467 additions and 120 deletions
@@ -30,6 +30,7 @@ import { isNoHorizontalPaddingColumn } from '/@/renderer/components/item-list/it
import { ActionsColumn } from '/@/renderer/components/item-list/item-table-list/columns/actions-column';
import { AlbumArtistsColumn } from '/@/renderer/components/item-list/item-table-list/columns/album-artists-column';
import { AlbumColumn } from '/@/renderer/components/item-list/item-table-list/columns/album-column';
import { AlbumGroupColumn } from '/@/renderer/components/item-list/item-table-list/columns/album-group-column';
import { ArtistsColumn } from '/@/renderer/components/item-list/item-table-list/columns/artists-column';
import { ComposerColumn } from '/@/renderer/components/item-list/item-table-list/columns/composer-column';
import { CountColumn } from '/@/renderer/components/item-list/item-table-list/columns/count-column';
@@ -213,6 +214,11 @@ const ItemTableListColumnBase = (props: ItemTableListColumn) => {
case TableColumn.SONG_COUNT:
return <CountColumn {...props} {...dragProps} controls={controls} type={type} />;
case TableColumn.ALBUM_GROUP:
return (
<AlbumGroupColumn {...props} {...dragProps} controls={controls} type={type} />
);
case TableColumn.ARTIST:
return <ArtistsColumn {...props} {...dragProps} controls={controls} type={type} />;
@@ -362,6 +368,27 @@ export const ItemTableListColumn = memo(ItemTableListColumnBase, (prevProps, nex
const NonMutedColumns = [TableColumn.TITLE, TableColumn.TITLE_ARTIST, TableColumn.TITLE_COMBINED];
export function isAlbumGroupingActive(columns: { id: string; isEnabled?: boolean }[]): boolean {
return columns.some((col) => col.id === TableColumn.ALBUM_GROUP && col.isEnabled);
}
export function isLastInAlbumGroup(
rowIndex: number,
getRowItem: ((index: number) => unknown) | undefined,
enableHeader: boolean | undefined,
dataLength: number,
): boolean {
const item = getRowItem?.(rowIndex) as null | undefined | { album?: string };
if (!item?.album) return true;
const nextRowIndex = rowIndex + 1;
const maxRow = enableHeader ? dataLength + 1 : dataLength;
if (nextRowIndex >= maxRow) return true;
const nextItem = getRowItem?.(nextRowIndex) as null | undefined | { album?: string };
return !nextItem || nextItem.album !== item.album;
}
export const TableColumnTextContainer = (
props: ItemTableListColumn & {
children: React.ReactNode;
@@ -493,7 +520,14 @@ export const TableColumnTextContainer = (
props.enableHorizontalBorders &&
props.enableHeader &&
props.rowIndex > 0 &&
(props.rowIndex === 1 || !isLastRow),
(isAlbumGroupingActive(props.columns)
? isLastInAlbumGroup(
props.rowIndex,
props.getRowItem,
!!props.enableHeader,
props.data.length,
)
: props.rowIndex === 1 || !isLastRow),
[styles.withVerticalBorder]: props.enableVerticalBorders && !isLastColumn,
})}
data-row-index={isDataRow ? `${props.tableId}-${props.rowIndex}` : undefined}
@@ -641,13 +675,24 @@ export const TableColumnContainer = (
[styles.paddingXl]: props.cellPadding === 'xl',
[styles.paddingXs]: props.cellPadding === 'xs',
[styles.right]: props.columns[props.columnIndex].align === 'end',
[styles.rowHoverHighlightEnabled]: isDataRow && props.enableRowHoverHighlight,
[styles.rowSelected]: isDataRow && isSelected,
[styles.rowHoverHighlightEnabled]:
isDataRow &&
props.enableRowHoverHighlight &&
props.type !== TableColumn.ALBUM_GROUP,
[styles.rowSelected]:
isDataRow && isSelected && props.type !== TableColumn.ALBUM_GROUP,
[styles.withHorizontalBorder]:
props.enableHorizontalBorders &&
props.enableHeader &&
props.rowIndex > 0 &&
(props.rowIndex === 1 || !isLastRow),
(isAlbumGroupingActive(props.columns)
? isLastInAlbumGroup(
props.rowIndex,
props.getRowItem,
!!props.enableHeader,
props.data.length,
)
: props.rowIndex === 1 || !isLastRow),
[styles.withVerticalBorder]: props.enableVerticalBorders && !isLastColumn,
})}
data-row-index={isDataRow ? `${props.tableId}-${props.rowIndex}` : undefined}
@@ -898,6 +943,9 @@ export const columnLabelMap: Record<TableColumn, ReactNode | string> = {
[TableColumn.ALBUM_COUNT]: i18n.t('table.column.albumCount', {
postProcess: 'upperCase',
}) as string,
[TableColumn.ALBUM_GROUP]: i18n.t('table.config.label.albumGroup', {
postProcess: 'upperCase',
}) as string,
[TableColumn.ARTIST]: i18n.t('table.column.artist', { postProcess: 'upperCase' }) as string,
[TableColumn.BIOGRAPHY]: i18n.t('table.column.biography', {
postProcess: 'upperCase',