add remaining table columns

This commit is contained in:
jeffvli
2025-10-09 11:06:10 -07:00
parent 076710672c
commit c5c9311d00
10 changed files with 207 additions and 10 deletions
@@ -15,8 +15,9 @@ export const ActionsColumn = (props: ItemTableListInnerColumn) => {
icon="ellipsisHorizontal"
iconProps={{
color: 'muted',
size: 'lg',
size: 'md',
}}
size="xs"
variant="subtle"
/>
</TableColumnContainer>
@@ -0,0 +1,17 @@
.group {
gap: var(--theme-spacing-sm) var(--theme-spacing-xs);
overflow: hidden;
}
.group a {
cursor: pointer;
}
.artists-container {
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
line-height: 1.4;
-webkit-box-orient: vertical;
color: var(--theme-colors-foreground-muted);
}
@@ -0,0 +1,62 @@
import { memo, useMemo } from 'react';
import { generatePath, Link } from 'react-router-dom';
import styles from './album-artists-column.module.css';
import {
ItemTableListInnerColumn,
TableColumnContainer,
TableColumnTextContainer,
} from '/@/renderer/components/item-list/item-table-list/item-table-list-column';
import { AppRoute } from '/@/renderer/router/routes';
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
import { Text } from '/@/shared/components/text/text';
import { RelatedAlbumArtist } from '/@/shared/types/domain-types';
const ArtistsColumn = (props: ItemTableListInnerColumn) => {
const row: RelatedAlbumArtist[] | undefined = (
props.data as (RelatedAlbumArtist[] | undefined)[]
)[props.rowIndex]?.[props.columns[props.columnIndex].id];
const artists = useMemo(() => {
if (!row) return [];
return row.map((artist) => {
const path = generatePath(AppRoute.LIBRARY_ARTISTS_DETAIL, {
artistId: artist.id,
});
return { ...artist, path };
});
}, [row]);
if (Array.isArray(row)) {
return (
<TableColumnContainer {...props}>
<div className={styles.artistsContainer}>
{artists.map((artist, index) => (
<Text
component={Link}
isLink
isMuted
isNoSelect
key={artist.id}
to={artist.path}
>
{artist.name}
{index < artists.length - 1 && ', '}
</Text>
))}
</div>
</TableColumnContainer>
);
}
return (
<TableColumnTextContainer {...props}>
<Skeleton />
</TableColumnTextContainer>
);
};
export const ArtistsColumnMemo = memo(ArtistsColumn);
export { ArtistsColumnMemo as ArtistsColumn };
@@ -18,8 +18,9 @@ export const FavoriteColumn = (props: ItemTableListInnerColumn) => {
iconProps={{
color: row ? 'primary' : 'muted',
fill: row ? 'primary' : undefined,
size: 'lg',
size: 'md',
}}
size="xs"
variant="subtle"
/>
</TableColumnContainer>
@@ -12,7 +12,11 @@ export const RatingColumn = (props: ItemTableListInnerColumn) => {
if (typeof row === 'number' || row === null) {
return (
<TableColumnContainer {...props}>
<Rating className={row ? undefined : 'hover-only-flex'} value={row || 0} />
<Rating
className={row ? undefined : 'hover-only-flex'}
size="xs"
value={row || 0}
/>
</TableColumnContainer>
);
}
@@ -19,7 +19,7 @@ export const RowIndexColumn = (props: ItemTableListInnerColumn) => {
<ActionIcon
className={clsx(styles.expand, 'hover-only')}
icon="arrowDownS"
iconProps={{ color: 'muted', size: 'xl' }}
iconProps={{ color: 'muted', size: 'md' }}
onClick={(e) =>
controls.onItemExpand?.(
props.data[props.rowIndex] as any,
@@ -27,6 +27,7 @@ export const RowIndexColumn = (props: ItemTableListInnerColumn) => {
e,
)
}
size="xs"
variant="subtle"
/>
<Text className="hide-on-hover" isMuted>
@@ -0,0 +1,30 @@
.title-combined {
display: grid;
grid-template-columns: calc(var(--row-height) - var(--theme-spacing-sm)) 1fr;
gap: var(--theme-spacing-sm);
align-items: center;
height: 100%;
}
.text-container {
display: grid;
grid-template-rows: 1fr 1fr;
gap: 2px;
min-width: 0;
}
.title {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.artists {
display: block;
overflow: hidden;
text-overflow: ellipsis;
font-size: 0.875rem;
color: var(--theme-colors-foreground-muted);
white-space: nowrap;
user-select: none;
}
@@ -0,0 +1,66 @@
import { CSSProperties, useMemo } from 'react';
import { generatePath, Link } from 'react-router-dom';
import styles from './title-combined-column.module.css';
import {
ItemTableListInnerColumn,
TableColumnContainer,
TableColumnTextContainer,
} from '/@/renderer/components/item-list/item-table-list/item-table-list-column';
import { AppRoute } from '/@/renderer/router/routes';
import { Image } from '/@/shared/components/image/image';
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
import { Text } from '/@/shared/components/text/text';
import { RelatedAlbumArtist } from '/@/shared/types/domain-types';
export const TitleCombinedColumn = (props: ItemTableListInnerColumn) => {
const row: object | undefined = (props.data as (any | undefined)[])[props.rowIndex];
const artists = useMemo(() => {
if (row && 'artists' in row && Array.isArray(row.artists)) {
return (row.artists as RelatedAlbumArtist[]).map((artist) => {
const path = generatePath(AppRoute.LIBRARY_ARTISTS_DETAIL, {
artistId: artist.id,
});
return { ...artist, path };
});
}
return [];
}, [row]);
if (row && 'name' in row && 'imageUrl' in row && 'artists' in row) {
const rowHeight = props.getRowHeight(props.rowIndex, props);
return (
<TableColumnContainer
className={styles['title-combined']}
containerStyle={{ '--row-height': `${rowHeight}px` } as CSSProperties}
{...props}
>
<Image containerClassName={styles.image} src={row.imageUrl as string} />
<div className={styles['text-container']}>
<Text className={styles.title} isNoSelect>
{row.name as string}
</Text>
<div className={styles.artists}>
{artists.map((artist, index) => (
<span key={artist.id}>
<Text component={Link} isLink isMuted isNoSelect to={artist.path}>
{artist.name}
</Text>
{index < artists.length - 1 && ', '}
</span>
))}
</div>
</div>
</TableColumnContainer>
);
}
return (
<TableColumnTextContainer {...props}>
<Skeleton />
</TableColumnTextContainer>
);
};