Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions web/default/src/components/data-table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export {
export { useDebouncedColumnFilter } from './hooks/use-debounced-column-filter'

export const DISABLED_ROW_DESKTOP =
'[--data-table-card-bg:var(--table-disabled)] hover:[--data-table-card-bg:var(--table-disabled-hover)] [background-color:var(--table-disabled)] hover:[background-color:var(--table-disabled-hover)] [&>td:first-child]:[border-left-color:var(--table-disabled-border)] [&>td:first-child]:border-l-4 [&>td:first-child]:pl-1'
'[--data-table-card-bg:var(--table-disabled)] hover:[--data-table-card-bg:var(--table-disabled-hover)] data-[state=selected]:![--data-table-card-bg:var(--table-disabled)] data-[state=selected]:hover:![--data-table-card-bg:var(--table-disabled-hover)] [background-color:var(--table-disabled)] hover:[background-color:var(--table-disabled-hover)] [&>td:first-child]:[border-left-color:var(--table-disabled-border)] [&>td:first-child]:border-l-4 [&>td:first-child]:pl-1'

export const DISABLED_ROW_MOBILE =
'[--data-table-card-bg:var(--table-disabled)] [background-color:var(--table-disabled)]'
'[--data-table-card-bg:var(--table-disabled)] data-[state=selected]:![--data-table-card-bg:var(--table-disabled)] [background-color:var(--table-disabled)]'
16 changes: 11 additions & 5 deletions web/default/src/components/data-table/layout/card-grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export type DataTableCardHelpers = {
* Provided so custom renderers can match the default layout decision.
*/
compact: boolean
/**
* Row selection state captured before entering memoized custom card renderers.
*/
isSelected: boolean
}

export interface DataTableCardGridProps<TData> {
Expand Down Expand Up @@ -80,7 +84,7 @@ function CardGridSkeleton(props: {
{[1, 2, 3, 4, 5, 6].map((i) => (
<div
key={`${prefix}-${i}`}
className='space-y-3 rounded-lg border [background-color:var(--table-row)] p-3'
className='space-y-3 rounded-lg border bg-(--table-row) p-3'
>
<div className='flex items-center justify-between gap-2'>
<Skeleton className='h-4 w-32' />
Expand Down Expand Up @@ -108,8 +112,8 @@ function CardGridSkeleton(props: {
* the card view reusable across any table with zero per-feature work while
* still allowing a bespoke card design when desired.
*
* Selection (the `select` column) is intentionally not rendered in card mode;
* bulk selection remains a table-mode capability.
* The default generic card omits the `select` column. Custom `renderCard`
* implementations can use `helpers.isSelected` to keep selection UI in sync.
*/
export function DataTableCardGrid<TData>(props: DataTableCardGridProps<TData>) {
const { t } = useTranslation()
Expand Down Expand Up @@ -156,17 +160,19 @@ export function DataTableCardGrid<TData>(props: DataTableCardGridProps<TData>) {
<div className={props.gridClassName ?? DEFAULT_GRID_CLASSNAME}>
{rows.map((row) => {
const key = props.getRowKey ? props.getRowKey(row) : row.id
const isSelected = row.getIsSelected()
return (
<div
key={key}
data-slot='data-table-card'
data-state={isSelected ? 'selected' : undefined}
className={cn(
'rounded-lg border [background-color:var(--data-table-card-bg,var(--table-row))] px-3 py-2.5',
'rounded-lg border bg-(--data-table-card-bg,var(--table-row)) px-3 py-2.5 transition-[background-color,border-color] duration-150 data-[state=selected]:[--data-table-card-bg:color-mix(in_oklch,var(--primary)_7%,var(--table-row))] data-[state=selected]:border-primary/40',
props.getRowClassName?.(row)
)}
>
{props.renderCard ? (
props.renderCard(row, { compact })
props.renderCard(row, { compact, isSelected })
) : (
<CardRowContent row={row} compact={compact} />
)}
Expand Down
19 changes: 14 additions & 5 deletions web/default/src/features/channels/components/channel-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ const SENSITIVE_MASK = '••••'
* priority/weight spinners, balance refresh, response/test times, tag
* expand-collapse, and the per-row (or per-tag) actions menu.
*/
function ChannelCardComponent({ row }: { row: Row<Channel> }) {
function ChannelCardComponent({
row,
isSelected,
}: {
row: Row<Channel>
isSelected: boolean
}) {
const { t } = useTranslation()
const { sensitiveVisible } = useChannels()
const isTagRow = isTagAggregateRow(row.original)
Expand Down Expand Up @@ -81,16 +87,19 @@ function ChannelCardComponent({ row }: { row: Row<Channel> }) {
row.original.status !== CHANNEL_STATUS.MANUAL_DISABLED)

return (
<div className='flex flex-col gap-3'>
<div
data-state={isSelected ? 'selected' : undefined}
className='flex flex-col gap-3'
>
{/* Row 1: selection + type, with status badge + actions menu */}
<div className='flex items-center justify-between gap-2'>
<div className='flex min-w-0 flex-1 items-center gap-2'>
{!isTagRow && selectCell && (
<span className='flex-shrink-0'>{selectCell}</span>
<span className='shrink-0'>{selectCell}</span>
)}
<div className='min-w-0 overflow-hidden'>{typeCell}</div>
</div>
<div className='flex flex-shrink-0 items-center gap-1.5'>
<div className='flex shrink-0 items-center gap-1.5'>
{showStatusBadge && statusCell}
<ChannelRowActionsLayoutContext.Provider value='card'>
{actionsCell}
Expand Down Expand Up @@ -122,7 +131,7 @@ function ChannelCardComponent({ row }: { row: Row<Channel> }) {
{/* Right column (sits on the right, content left-aligned). A single
grid with content-sized columns keeps Priority/Weight and
Response/Last Tested aligned without wasting horizontal space. */}
<div className='grid flex-shrink-0 grid-cols-[auto_auto] items-center gap-x-3 gap-y-1'>
<div className='grid shrink-0 grid-cols-[auto_auto] items-center gap-x-3 gap-y-1'>
<span className={labelClass}>{t('Priority')}</span>
<span className={labelClass}>{t('Weight')}</span>
<div className='flex justify-start'>{priorityCell}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,9 @@ export function ChannelsTable() {
skeletonKeyPrefix='channel-skeleton'
enableCardView
viewModeStorageKey={CHANNELS_VIEW_MODE_STORAGE_KEY}
renderCard={(row) => <ChannelCard row={row} />}
renderCard={(row, { isSelected }) => (
<ChannelCard row={row} isSelected={isSelected} />
)}
cardGridClassName='grid grid-cols-1 gap-3 sm:gap-4 lg:grid-cols-3'
applyHeaderSize
toolbarProps={{
Expand Down