Skip to content
Open
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
109 changes: 66 additions & 43 deletions src/features/dashboard/templates/list/table-cells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -313,66 +313,89 @@ export function TemplateNameCell({
)
}

export function CreatedAtCell({
getValue,
}: CellContext<Template | DefaultTemplate, unknown>) {
const dateValue = getValue() as string
export interface TemplatesTableMeta {
sortedColumnId?: string
}

const formattedTimestamp = useMemo(() => {
return formatLocalLogStyleTimestamp(dateValue, {
includeSeconds: false,
includeYear: true,
includeTimezone: true,
})
}, [dateValue])
type DateColumnId = 'createdAt' | 'updatedAt'

return (
<div
className={cn(
'h-full overflow-x-hidden whitespace-nowrap font-mono prose-table-numeric'
)}
>
<span className="text-fg-tertiary">
{formattedTimestamp?.datePart ?? '--'}
</span>{' '}
{formattedTimestamp?.timePart ?? '--'}{' '}
<span className="text-fg-tertiary">
{formattedTimestamp?.timezonePart ?? ''}
</span>
</div>
)
}
const DATE_CELL_FORMAT_OPTIONS = {
includeSeconds: false,
includeYear: true,
includeTimezone: true,
} as const

export function UpdatedAtCell({
getValue,
}: CellContext<Template | DefaultTemplate, unknown>) {
function DateTimeCell({
ctx,
columnId,
}: {
ctx: CellContext<Template | DefaultTemplate, unknown>
columnId: DateColumnId
}) {
'use no memo'

const { getValue, table, row } = ctx
const dateValue = getValue() as string

const formattedTimestamp = useMemo(() => {
return formatLocalLogStyleTimestamp(dateValue, {
includeSeconds: false,
includeYear: true,
includeTimezone: true,
})
}, [dateValue])
const formatted = useMemo(
() => formatLocalLogStyleTimestamp(dateValue, DATE_CELL_FORMAT_OPTIONS),
[dateValue]
)

const meta = table.options.meta as TemplatesTableMeta | undefined
const isSortedColumn = meta?.sortedColumnId === columnId

// Compare against the full loaded row model (not the virtualized window) so
// the first/last on-screen rows still see their true neighbours. Adjacency is
// a best guess over loaded pages; it may shift as more rows load in.
const rows = table.getRowModel().rows
const datePart = formatted?.datePart

const isTimePromoted = useMemo(() => {
if (!isSortedColumn || !datePart) return false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not restrict time promotion to the sorted column

When the table is sorted by Updated (the default), isSortedColumn is false for every Created cell, so the same-day check is skipped even if the Created dates of the rows immediately above or below match; sorting by Created has the symmetric problem for Updated. Since the new highlighting is meant to apply to the Created/Updated date cells based on adjacent rows, this leaves one of the two columns permanently in the default tertiary time style.

Useful? React with 👍 / 👎.


const sharesDate = (index: number) => {
const neighbor = rows[index]
if (!neighbor) return false
const neighborValue = neighbor.getValue(columnId) as string
return (
formatLocalLogStyleTimestamp(neighborValue, DATE_CELL_FORMAT_OPTIONS)
?.datePart === datePart
)
}

return sharesDate(row.index - 1) || sharesDate(row.index + 1)
}, [isSortedColumn, datePart, rows, row.index, columnId])

return (
<div
className={cn(
'h-full overflow-x-hidden whitespace-nowrap font-mono prose-table-numeric'
)}
>
<span className="text-fg-tertiary">
{formattedTimestamp?.datePart ?? '--'}
<span className="text-fg-secondary">{formatted?.datePart ?? '--'}</span>{' '}
<span
className={isTimePromoted ? 'text-fg-secondary' : 'text-fg-tertiary'}
>
{formatted?.timePart ?? '--'}
</span>{' '}
{formattedTimestamp?.timePart ?? '--'}{' '}
<span className="text-fg-tertiary">
{formattedTimestamp?.timezonePart ?? ''}
</span>
<span className="text-fg-tertiary">{formatted?.timezonePart ?? ''}</span>
</div>
)
}

export function CreatedAtCell(
ctx: CellContext<Template | DefaultTemplate, unknown>
) {
return <DateTimeCell ctx={ctx} columnId="createdAt" />
}

export function UpdatedAtCell(
ctx: CellContext<Template | DefaultTemplate, unknown>
) {
return <DateTimeCell ctx={ctx} columnId="updatedAt" />
}

export function VisibilityCell({
getValue,
}: CellContext<Template | DefaultTemplate, unknown>) {
Expand Down
4 changes: 4 additions & 0 deletions src/features/dashboard/templates/list/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ import HelpTooltip from '@/ui/help-tooltip'
import { SIDEBAR_TRANSITION_CLASSNAMES } from '@/ui/primitives/sidebar'
import {
TEMPLATES_DEFAULT_SORT_BASE,
TEMPLATES_DEFAULT_SORT_COLUMN_ID,
TEMPLATES_DEFAULT_SORT_DESC,
TEMPLATES_PAGE_SIZE,
} from './constants'
import TemplatesHeader from './header'
import { useTemplateTableStore } from './stores/table-store'
import { TemplatesTableBody as TableBody } from './table-body'
import type { TemplatesTableMeta } from './table-cells'
import { fallbackData, templatesTableConfig, useColumns } from './table-config'

const COLUMN_TO_SORT_BASE: Record<string, string> = {
Expand Down Expand Up @@ -71,6 +73,7 @@ export default function TemplatesTable() {
? sortColumn.desc !== false
: TEMPLATES_DEFAULT_SORT_DESC
const sort = `${sortBase}_${isDesc ? 'desc' : 'asc'}` as TemplatesSort
const sortedColumnId = sortColumn?.id ?? TEMPLATES_DEFAULT_SORT_COLUMN_ID

const {
data,
Expand Down Expand Up @@ -140,6 +143,7 @@ export default function TemplatesTable() {
onGlobalFilterChange: setGlobalFilter,
onSortingChange: setSorting,
onColumnSizingChange: setColumnSizing,
meta: { sortedColumnId } satisfies TemplatesTableMeta,
} as TableOptions<Template>)

const columnSizeVars = useColumnSizeVars(table)
Expand Down
Loading