mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-12 07:12:54 +01:00
221 lines
6.2 KiB
Markdown
221 lines
6.2 KiB
Markdown
# DASH-001: Tabbed Navigation System
|
|
|
|
## Overview
|
|
|
|
Replace the current single-view dashboard with a proper tabbed interface. This is the foundation task that enables all other dashboard improvements.
|
|
|
|
## Context
|
|
|
|
The current Noodl editor dashboard (`projectsview.ts`) uses a basic pane-switching mechanism with jQuery. A new launcher is being developed in `packages/noodl-core-ui/src/preview/launcher/` using React, which already has a sidebar-based navigation but needs proper tab support for the main content area.
|
|
|
|
This task focuses on the **new React-based launcher** only. The old jQuery launcher will be deprecated.
|
|
|
|
## Current State
|
|
|
|
### Existing New Launcher Structure
|
|
```
|
|
packages/noodl-core-ui/src/preview/launcher/
|
|
├── Launcher/
|
|
│ ├── Launcher.tsx # Main component with PAGES array
|
|
│ ├── components/
|
|
│ │ ├── LauncherSidebar/ # Left navigation
|
|
│ │ ├── LauncherPage/ # Page wrapper
|
|
│ │ ├── LauncherProjectCard/
|
|
│ │ └── LauncherSearchBar/
|
|
│ └── views/
|
|
│ ├── Projects.tsx # Current projects view
|
|
│ └── LearningCenter.tsx # Empty learning view
|
|
└── template/
|
|
└── LauncherApp/ # App shell template
|
|
```
|
|
|
|
### Current Page Definition
|
|
```typescript
|
|
// In Launcher.tsx
|
|
export enum LauncherPageId {
|
|
LocalProjects,
|
|
LearningCenter
|
|
}
|
|
|
|
export const PAGES: LauncherPageMetaData[] = [
|
|
{ id: LauncherPageId.LocalProjects, displayName: 'Recent Projects', icon: IconName.CircleDot },
|
|
{ id: LauncherPageId.LearningCenter, displayName: 'Learn', icon: IconName.Rocket }
|
|
];
|
|
```
|
|
|
|
## Requirements
|
|
|
|
### Functional Requirements
|
|
|
|
1. **Tab Bar Component**
|
|
- Horizontal tab bar at the top of the main content area
|
|
- Visual indicator for active tab
|
|
- Smooth transition when switching tabs
|
|
- Keyboard navigation support (arrow keys, Enter)
|
|
|
|
2. **Tab Configuration**
|
|
- Projects tab (default, opens first)
|
|
- Learn tab (tutorials, guides)
|
|
- Templates tab (project starters)
|
|
- Extensible for future tabs (Marketplace, Settings)
|
|
|
|
3. **State Persistence**
|
|
- Remember last active tab across sessions
|
|
- Store in localStorage or electron-store
|
|
|
|
4. **URL/Deep Linking (Optional)**
|
|
- Support for `noodl://dashboard/projects` style deep links
|
|
- Query params for tab state
|
|
|
|
### Non-Functional Requirements
|
|
|
|
- Tab switching should feel instant (<100ms)
|
|
- No layout shift when switching tabs
|
|
- Accessible (WCAG 2.1 AA compliant)
|
|
- Consistent with existing noodl-core-ui design system
|
|
|
|
## Technical Approach
|
|
|
|
### 1. Create Tab Bar Component
|
|
|
|
Create a new component in `noodl-core-ui` that can be reused:
|
|
|
|
```
|
|
packages/noodl-core-ui/src/components/layout/TabBar/
|
|
├── TabBar.tsx
|
|
├── TabBar.module.scss
|
|
├── TabBar.stories.tsx
|
|
└── index.ts
|
|
```
|
|
|
|
### 2. Update Launcher Structure
|
|
|
|
```typescript
|
|
// New page structure
|
|
export enum LauncherPageId {
|
|
Projects = 'projects',
|
|
Learn = 'learn',
|
|
Templates = 'templates'
|
|
}
|
|
|
|
export interface LauncherTab {
|
|
id: LauncherPageId;
|
|
label: string;
|
|
icon?: IconName;
|
|
component: React.ComponentType;
|
|
}
|
|
|
|
export const LAUNCHER_TABS: LauncherTab[] = [
|
|
{ id: LauncherPageId.Projects, label: 'Projects', icon: IconName.Folder, component: Projects },
|
|
{ id: LauncherPageId.Learn, label: 'Learn', icon: IconName.Book, component: LearningCenter },
|
|
{ id: LauncherPageId.Templates, label: 'Templates', icon: IconName.Components, component: Templates }
|
|
];
|
|
```
|
|
|
|
### 3. State Management
|
|
|
|
Use React context for tab state:
|
|
|
|
```typescript
|
|
// LauncherContext.tsx
|
|
interface LauncherContextValue {
|
|
activeTab: LauncherPageId;
|
|
setActiveTab: (tab: LauncherPageId) => void;
|
|
}
|
|
```
|
|
|
|
### 4. Persistence Hook
|
|
|
|
```typescript
|
|
// usePersistentTab.ts
|
|
function usePersistentTab(key: string, defaultTab: LauncherPageId) {
|
|
// Load from localStorage on mount
|
|
// Save to localStorage on change
|
|
}
|
|
```
|
|
|
|
## Files to Create
|
|
|
|
1. `packages/noodl-core-ui/src/components/layout/TabBar/TabBar.tsx`
|
|
2. `packages/noodl-core-ui/src/components/layout/TabBar/TabBar.module.scss`
|
|
3. `packages/noodl-core-ui/src/components/layout/TabBar/TabBar.stories.tsx`
|
|
4. `packages/noodl-core-ui/src/components/layout/TabBar/index.ts`
|
|
5. `packages/noodl-core-ui/src/preview/launcher/Launcher/LauncherContext.tsx`
|
|
6. `packages/noodl-core-ui/src/preview/launcher/Launcher/hooks/usePersistentTab.ts`
|
|
7. `packages/noodl-core-ui/src/preview/launcher/Launcher/views/Templates.tsx`
|
|
|
|
## Files to Modify
|
|
|
|
1. `packages/noodl-core-ui/src/preview/launcher/Launcher/Launcher.tsx`
|
|
- Import and use TabBar
|
|
- Implement tab switching logic
|
|
- Wrap with LauncherContext
|
|
|
|
2. `packages/noodl-core-ui/src/components/layout/index.ts`
|
|
- Export TabBar component
|
|
|
|
## Implementation Steps
|
|
|
|
### Phase 1: TabBar Component
|
|
1. Create TabBar component with basic functionality
|
|
2. Add styling consistent with noodl-core-ui
|
|
3. Write Storybook stories for testing
|
|
4. Add keyboard navigation
|
|
|
|
### Phase 2: Launcher Integration
|
|
1. Create LauncherContext
|
|
2. Create usePersistentTab hook
|
|
3. Integrate TabBar into Launcher.tsx
|
|
4. Create empty Templates view
|
|
|
|
### Phase 3: Polish
|
|
1. Add tab transition animations
|
|
2. Test accessibility
|
|
3. Add deep link support (if time permits)
|
|
|
|
## Testing Checklist
|
|
|
|
- [ ] Tabs render correctly
|
|
- [ ] Clicking tab switches content
|
|
- [ ] Active tab is visually indicated
|
|
- [ ] Keyboard navigation works (Tab, Arrow keys, Enter)
|
|
- [ ] Tab state persists after closing/reopening
|
|
- [ ] No layout shift on tab switch
|
|
- [ ] Works at different viewport sizes
|
|
- [ ] Screen reader announces tab changes
|
|
|
|
## Design Reference
|
|
|
|
The tab bar should follow the existing Tabs component style in noodl-core-ui but be optimized for the launcher context (larger, more prominent).
|
|
|
|
See: `packages/noodl-core-ui/src/components/layout/Tabs/`
|
|
|
|
## Dependencies
|
|
|
|
- None (this is a foundation task)
|
|
|
|
## Blocked By
|
|
|
|
- None
|
|
|
|
## Blocks
|
|
|
|
- DASH-002 (Project List Redesign)
|
|
- DASH-003 (Project Organization)
|
|
- DASH-004 (Tutorial Section Redesign)
|
|
|
|
## Estimated Effort
|
|
|
|
- Component creation: 2-3 hours
|
|
- Launcher integration: 2-3 hours
|
|
- Polish and testing: 1-2 hours
|
|
- **Total: 5-8 hours**
|
|
|
|
## Success Criteria
|
|
|
|
1. User can switch between Projects, Learn, and Templates tabs
|
|
2. Tab state persists across sessions
|
|
3. Component is reusable for other contexts
|
|
4. Passes accessibility audit
|
|
5. Matches existing design system aesthetics
|