feat(berths): active-interests popover + row-density toggle on berth list
Two complementary UX upgrades on the berth list: 1. Active-interests popover — replaces the plain "Active interests" count cell with a click-to-expand popover. Each row shows the linked deal's client name, pipeline stage (with stage-badge tint), and a primary-star icon. Lazy-loads on first open (30s stale), capped at 20 entries server-side, sorted most-recently-updated first. Backed by `GET /api/v1/berths/[id]/active-interests`. 2. Row-density toggle — DataTable gains a `density: 'comfortable' | 'compact'` prop. Compact drops cell vertical padding from py-3 to py-1.5 so reps can scan many more berths per viewport on the high-density admin lists. Persisted alongside hidden-columns in `user_profiles.preferences. tablePreferences[entityType].density`. Hook returns `density + setDensity`; defaults to 'comfortable' for users who haven't chosen. The setter shares the same debounced PATCH with setHidden so toggling both doesn't multiply the network round-trips. Toolbar adds a Rows3/Rows4 icon button between the saved-views dropdown and the ColumnPicker. tooltip + aria-label flip to communicate the next state. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useEffect } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter, useParams } from 'next/navigation';
|
||||
import { Anchor, Plus } from 'lucide-react';
|
||||
import { Anchor, Plus, Rows3, Rows4 } from 'lucide-react';
|
||||
|
||||
import { useMobileChrome } from '@/components/layout/mobile/mobile-layout-provider';
|
||||
import { DataTable } from '@/components/shared/data-table';
|
||||
@@ -66,8 +66,13 @@ export function BerthList() {
|
||||
'berth:statusChanged': [['berths']],
|
||||
});
|
||||
|
||||
// Persisted column visibility — same pattern as ClientList / InterestList.
|
||||
const { hidden, setHidden } = useTablePreferences('berths', BERTH_DEFAULT_HIDDEN);
|
||||
// Persisted column visibility + row density — same pattern as
|
||||
// ClientList / InterestList; density is new and falls back to
|
||||
// 'comfortable' for users who haven't picked yet.
|
||||
const { hidden, setHidden, density, setDensity } = useTablePreferences(
|
||||
'berths',
|
||||
BERTH_DEFAULT_HIDDEN,
|
||||
);
|
||||
const columnVisibility = Object.fromEntries(hidden.map((id) => [id, false]));
|
||||
|
||||
return (
|
||||
@@ -112,6 +117,24 @@ export function BerthList() {
|
||||
setAllFilters(savedFilters);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
variant="outline"
|
||||
onClick={() => setDensity(density === 'compact' ? 'comfortable' : 'compact')}
|
||||
aria-label={
|
||||
density === 'compact'
|
||||
? 'Switch to comfortable row spacing'
|
||||
: 'Switch to compact row spacing'
|
||||
}
|
||||
title={density === 'compact' ? 'Comfortable rows' : 'Compact rows'}
|
||||
>
|
||||
{density === 'compact' ? (
|
||||
<Rows3 className="h-4 w-4" aria-hidden />
|
||||
) : (
|
||||
<Rows4 className="h-4 w-4" aria-hidden />
|
||||
)}
|
||||
</Button>
|
||||
<ColumnPicker columns={BERTH_COLUMN_OPTIONS} hidden={hidden} onChange={setHidden} />
|
||||
{canBulkAdd && (
|
||||
<Button asChild size="sm" variant="default">
|
||||
@@ -127,6 +150,7 @@ export function BerthList() {
|
||||
<DataTable<BerthRow>
|
||||
columns={berthColumns}
|
||||
columnVisibility={columnVisibility}
|
||||
density={density}
|
||||
data={data}
|
||||
isLoading={isLoading}
|
||||
pagination={{
|
||||
|
||||
Reference in New Issue
Block a user