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
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Everything below has been built, tested, and verified. These items are stable an
- **Animation:** 7 presets, reduced-motion aware, page transitions (9 types with View Transitions API).
- **Notifications:** Toast/banner/snackbar with full CRUD integration.
- **View Enhancements:** Gallery, column summary, grouping, row color, density modes, view sharing, ViewTabBar (reorder, pin, context menu, type-switch, personal/shared grouping).
- **Inline View Config Panel:** Airtable-style right sidebar for view configuration (Page, Data, Appearance, User Filters, Actions, Advanced), breadcrumb header, record count footer — no page navigation required.
- **Inline View Config Panel:** Airtable-style right sidebar for view configuration (Page, Data, Appearance, User Filters, Actions, Advanced), breadcrumb header, record count footer, responsive mobile overlay, ARIA accessibility, auto-close on view switch — no page navigation required.

### Enterprise Features ✅

Expand Down
7 changes: 6 additions & 1 deletion ROADMAP_CONSOLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ These were the initial tasks to bring the console prototype to production-qualit
| **Global Undo/Redo (Ctrl+Z)** | ✅ Done (global UndoManager + batch ops + persistent stack) | Post v1.0 | Phase 16 (L1+L2) |
| Notification center | ✅ Partial (ActivityFeed with filter preferences) | Post v1.0 | Phase 17 (L2) |
| Activity feed | ✅ Done | Post v1.0 | Phase 17 (L1) |
| **Inline View Config Panel** | ✅ Done (Airtable-style right sidebar, breadcrumb header, record count footer) | Post v1.0 | Phase 20 |
| **Inline View Config Panel** | ✅ Done (Airtable-style right sidebar, breadcrumb header, record count footer, responsive mobile overlay, ARIA accessibility, auto-close on view switch) | Post v1.0 | Phase 20 |

### 5.5 Kanban & Visual Views

Expand Down Expand Up @@ -1100,6 +1100,10 @@ These were the initial tasks to bring the console prototype to production-qualit
2027 Q1+ — v2.0: AUTOMATION & WORKFLOWS (✅ L1 Complete)
═══════════════════════════════════════════════════════════
Phase 18: Automation & Workflows ██████████████ ✅ L1 Complete: AutomationBuilder, AutomationRunHistory, registered in ComponentRegistry

2027 Q1+ — v2.1: INLINE VIEW DESIGNER (✅ Complete)
═══════════════════════════════════════════════════════════
Phase 20: Inline ViewConfigPanel ██████████████ ✅ Complete: Airtable-style right sidebar, breadcrumb header, record count footer, responsive mobile overlay, ARIA accessibility, auto-close on view switch
```

### Milestone Summary
Expand All @@ -1114,6 +1118,7 @@ These were the initial tasks to bring the console prototype to production-qualit
| **v1.1** | v1.1.0 | ✅ Complete | Kanban + Forms + Import/Export (Phases 13-15); all L1 ✅ |
| **v1.2** | v1.2.0 | ✅ L1 Complete | Undo/Redo + Collaboration (Phases 16-17); L1 integrated into console |
| **v2.0** | v2.0.0 | ✅ L2 Complete | All L2 features: batch undo, expression formatting, conditional triggers, multi-step actions, swimlane persistence, keyboard nav, file validation, thread resolution, notification prefs |
| **v2.1** | v2.1.0 | ✅ Complete | Inline ViewConfigPanel (Phase 20): Airtable-style right sidebar for view configuration |

---

Expand Down
33 changes: 33 additions & 0 deletions apps/console/src/__tests__/ViewConfigPanel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,37 @@ describe('ViewConfigPanel', () => {
const noneTexts = screen.getAllByText('console.objectView.none');
expect(noneTexts.length).toBeGreaterThanOrEqual(2);
});

it('has correct ARIA attributes when open', () => {
render(
<ViewConfigPanel
open={true}
onClose={vi.fn()}
activeView={mockActiveView}
objectDef={mockObjectDef}
/>
);

const panel = screen.getByTestId('view-config-panel');
expect(panel).toHaveAttribute('role', 'complementary');
expect(panel).toHaveAttribute('aria-label', 'console.objectView.configureView');
});

it('is full-width on mobile via CSS classes', () => {
render(
<ViewConfigPanel
open={true}
onClose={vi.fn()}
activeView={mockActiveView}
objectDef={mockObjectDef}
/>
);

const panel = screen.getByTestId('view-config-panel');
// On mobile: absolute full-width overlay; on desktop: relative w-72
expect(panel.className).toContain('w-full');
expect(panel.className).toContain('sm:w-72');
expect(panel.className).toContain('absolute');
expect(panel.className).toContain('sm:relative');
});
});
2 changes: 2 additions & 0 deletions apps/console/src/components/ObjectView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ export function ObjectView({ dataSource, objects, onEdit, onRowClick }: any) {
// The plugin ObjectView returns the view ID directly via onViewChange
const matchedView = views.find((v: any) => v.id === newViewId);
if (!matchedView) return;
// Auto-close the config panel when switching views
setShowViewConfigPanel(false);
Comment on lines +126 to +127
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

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

The auto-close behavior when switching views is not covered by tests. Consider adding a test in ViewSwitching.test.tsx or ObjectView.test.tsx to verify that showViewConfigPanel is set to false when handleViewChange is called. This ensures the panel closes automatically when users switch between views, which is an important UX behavior mentioned in the PR description.

Copilot uses AI. Check for mistakes.
if (viewId) {
navigate(`../${matchedView.id}`, { relative: "path" });
} else {
Expand Down
16 changes: 14 additions & 2 deletions apps/console/src/components/ViewConfigPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* following the same pattern as MetadataPanel.
*/

import { useMemo } from 'react';
import { useMemo, useEffect, useRef } from 'react';
import { Button } from '@object-ui/components';
import { X, ChevronRight } from 'lucide-react';
import { useObjectTranslation } from '@object-ui/i18n';
Expand Down Expand Up @@ -96,6 +96,14 @@ function ToggleIndicator({ enabled }: { enabled: boolean }) {

export function ViewConfigPanel({ open, onClose, activeView, objectDef }: ViewConfigPanelProps) {
const { t } = useObjectTranslation();
const panelRef = useRef<HTMLDivElement>(null);

// Focus the panel when it opens for keyboard accessibility
useEffect(() => {
if (open && panelRef.current) {
panelRef.current.focus();
}
}, [open]);
Comment on lines +101 to +106
Copy link

Copilot AI Feb 21, 2026

Choose a reason for hiding this comment

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

The focus management effect in useEffect is not covered by tests. Consider adding a test to verify that the panel receives focus when opened, which is important for keyboard navigation and accessibility. This can be done by checking if panelRef.current.focus() was called or by verifying focus programmatically in the test.

Copilot uses AI. Check for mistakes.

const viewLabel = activeView.label || activeView.id;
const viewType = activeView.type || 'grid';
Expand Down Expand Up @@ -124,8 +132,12 @@ export function ViewConfigPanel({ open, onClose, activeView, objectDef }: ViewCo

return (
<div
ref={panelRef}
data-testid="view-config-panel"
className="w-72 lg:w-80 border-l bg-background flex flex-col shrink-0 z-20 transition-all overflow-hidden"
role="complementary"
aria-label={t('console.objectView.configureView')}
tabIndex={-1}
className="absolute inset-y-0 right-0 w-full sm:w-72 lg:w-80 sm:relative sm:inset-auto border-l bg-background flex flex-col shrink-0 z-20 transition-all overflow-hidden"
>
{/* Panel Header */}
<div className="px-4 py-3 border-b flex items-center justify-between shrink-0">
Expand Down
2 changes: 1 addition & 1 deletion examples/crm/objectstack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -767,4 +767,4 @@ export default defineStack({

},
plugins: [],
});
}, { strict: false }); // Defer validation to `objectstack compile` CLI to avoid Zod double-parse transform bug on form.sections.columns