Skip to content

Commit b5b99b7

Browse files
Copilothotlong
andcommitted
Restore ViewTabBar as read-only view switcher (no drag/add)
Per reviewer feedback, ViewTabBar should remain visible for view switching but without design-mode features (drag-to-reorder, +add, context menu actions). - config={{ reorderable: false }} disables drag - No onAddView, onRenameView, onDuplicateView, etc. callbacks - Restore VIEW_TYPE_ICONS and related imports - Update tests to verify tabs render without design features Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent f7df05a commit b5b99b7

3 files changed

Lines changed: 48 additions & 8 deletions

File tree

apps/console/src/__tests__/ObjectView.test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ describe('ObjectView Component', () => {
170170
// Check Header (h1 only, breadcrumb removed)
171171
const headers = screen.getAllByText('Opportunity');
172172
expect(headers.length).toBeGreaterThanOrEqual(1);
173+
174+
// Check view tabs are rendered (without drag/add features)
175+
const allOppTexts = screen.getAllByText('All Opportunities');
176+
expect(allOppTexts.length).toBeGreaterThanOrEqual(1);
177+
expect(screen.getByText('Pipeline')).toBeInTheDocument();
173178

174179
// Check Grid is rendered (default)
175180
expect(screen.getByTestId('object-grid')).toBeInTheDocument();

apps/console/src/__tests__/ViewSwitching.test.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,17 @@ describe('Console View Switching Integration', () => {
9090
);
9191
};
9292

93-
it('no longer renders view tabs (moved to config panel)', () => {
93+
it('renders view tabs without drag or add features', () => {
9494
renderObjectView();
9595

96-
// ViewTabBar was removed, so view names should not appear as tabs
97-
// Only the default grid view is rendered
98-
expect(screen.queryByTestId('view-tab-bar')).not.toBeInTheDocument();
96+
// ViewTabBar should be present for switching views
97+
const allTasksElements = screen.getAllByText('All Tasks');
98+
expect(allTasksElements.length).toBeGreaterThanOrEqual(1);
99+
expect(screen.getByText('Board')).toBeInTheDocument();
100+
expect(screen.getByText('Schedule')).toBeInTheDocument();
101+
expect(screen.getByText('Roadmap')).toBeInTheDocument();
102+
expect(screen.getByText('History')).toBeInTheDocument();
103+
expect(screen.getByText('Sites')).toBeInTheDocument();
99104
});
100105

101106
it('switches to Timeline view correctly', async () => {

apps/console/src/components/ObjectView.tsx

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@
99
* - ListView delegation for non-grid view types (kanban, calendar, chart, etc.)
1010
*/
1111

12-
import { useMemo, useState, useCallback, useEffect } from 'react';
12+
import { useMemo, useState, useCallback, useEffect, type ComponentType } from 'react';
1313
import { useParams, useSearchParams, useNavigate } from 'react-router-dom';
1414
import { ObjectChart } from '@object-ui/plugin-charts';
1515
import { ListView } from '@object-ui/plugin-list';
1616
import { DetailView, RecordChatterPanel } from '@object-ui/plugin-detail';
17-
import { ObjectView as PluginObjectView } from '@object-ui/plugin-view';
17+
import { ObjectView as PluginObjectView, ViewTabBar } from '@object-ui/plugin-view';
18+
import type { ViewTabItem } from '@object-ui/plugin-view';
1819
// Import plugins for side-effects (registration)
1920
import '@object-ui/plugin-grid';
2021
import '@object-ui/plugin-kanban';
2122
import '@object-ui/plugin-calendar';
2223
import { Button, Empty, EmptyTitle, EmptyDescription, NavigationOverlay, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator } from '@object-ui/components';
23-
import { Plus, Table as TableIcon, Settings2, Wrench } from 'lucide-react';
24+
import { Plus, Table as TableIcon, Settings2, Wrench, KanbanSquare, Calendar, LayoutGrid, Activity, GanttChart, MapPin, BarChart3 } from 'lucide-react';
2425
import type { ListViewSchema, ViewNavigationConfig, FeedItem } from '@object-ui/types';
2526
import { MetadataToggle, MetadataPanel, useMetadataInspector } from './MetadataInspector';
2627
import { ViewConfigPanel } from './ViewConfigPanel';
@@ -31,6 +32,18 @@ import { useAuth } from '@object-ui/auth';
3132
import { useRealtimeSubscription, useConflictResolution } from '@object-ui/collaboration';
3233
import { useNavigationOverlay, SchemaRenderer } from '@object-ui/react';
3334

35+
/** Map view types to Lucide icons (Airtable-style) */
36+
const VIEW_TYPE_ICONS: Record<string, ComponentType<{ className?: string }>> = {
37+
grid: TableIcon,
38+
kanban: KanbanSquare,
39+
calendar: Calendar,
40+
gallery: LayoutGrid,
41+
timeline: Activity,
42+
gantt: GanttChart,
43+
map: MapPin,
44+
chart: BarChart3,
45+
};
46+
3447
const FALLBACK_USER = { id: 'current-user', name: 'Demo User' };
3548

3649
/**
@@ -732,7 +745,24 @@ export function ObjectView({ dataSource, objects, onEdit }: any) {
732745
</div>
733746
</div>
734747

735-
{/* View Tabs removed — view switching is handled via ViewConfigPanel (right sidebar) */}
748+
{/* View Tabs — read-only view switcher (design features like drag/add are in ViewConfigPanel) */}
749+
{views.length > 1 && (
750+
<div className="border-b px-3 sm:px-4 bg-background overflow-x-auto shrink-0">
751+
<ViewTabBar
752+
views={views.map((view: { id: string; label: string; type: string; filter?: any[]; sort?: any[] }) => ({
753+
id: view.id,
754+
label: view.label,
755+
type: view.type,
756+
hasActiveFilters: Array.isArray((view as any).filter) && (view as any).filter.length > 0,
757+
hasActiveSort: Array.isArray((view as any).sort) && (view as any).sort.length > 0,
758+
} as ViewTabItem))}
759+
activeViewId={activeViewId}
760+
onViewChange={handleViewChange}
761+
viewTypeIcons={VIEW_TYPE_ICONS}
762+
config={{ reorderable: false }}
763+
/>
764+
</div>
765+
)}
736766

737767
{/* 2. Content — Plugin ObjectView with ViewSwitcher + Filter + Sort */}
738768
<div className="flex-1 overflow-hidden relative flex flex-row">

0 commit comments

Comments
 (0)