Files
tatlock-ui/docs/UI_LAYOUT.md
T
Jeroen SchweitzerandClaude Opus 4.5 948e104ce5 feat: add reusable panel system with FilterPanel widget
- Update UI_LAYOUT.md with comprehensive panel taxonomy
- Document Nav Panel, Filter Panel, Detail Panel, Chat Dock specs
- Add panel header behavior (bottom-docked for left panels)
- Add responsive breakpoints with panel folding summary
- Create PanelHeader widget with dockToBottom option
- Create FilterPanel widget for data filtering sidebars
- Refactor Control Room to use FilterPanel
- Remove external links from sidebar (cleanup)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 14:54:14 +01:00

26 KiB

UI Layout Specification

This document defines the layout structure, responsive behavior, and component constraints for Tatlock UI. It implements the "Rooms of the Estate" metaphor from PHILOSOPHY.md.

Navigation Structure

The UI uses a tabbed room navigation in the header rather than a traditional sidebar. Each "room" represents a distinct usage context, reducing cognitive clutter.

Room Purpose Chat Dock Default
Front Hall Dashboard - estate overview, quick access, activity Expanded
Control Room Infrastructure - containers, stacks, monitoring Collapsed
Parlor Housekeeping - home automation, devices, scenes Collapsed
Library Knowledge - docs, notes, bookmarks (future) Collapsed

Hidden for now:

  • Study - Secretarial tasks (email, calendaring) - future implementation

Layout Structure

┌─────────────────────────────────────────────────────────────────────────────┐
│  HEADER BAR (56px, with logo bulge overlay)                                 │
│  [◯Logo◯] [Room Icons] ─────────────────────────────────── [Profile Menu]  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────┐ ┌─────────────────────────────────┐ ┌───────────────────┐  │
│  │ NAV PANEL   │ │  PRIMARY CONTENT                │ │  CHAT DOCK        │  │
│  │             │ │                                 │ │                   │  │
│  │ Room-level  │ │  ┌──────────┐ ┌──────────────┐  │ │  Tatlock AI       │  │
│  │ navigation  │ │  │ FILTER   │ │ DATA GRID    │  │ │  assistant        │  │
│  │ (sections)  │ │  │ PANEL    │ │              │  │ │                   │  │
│  │             │ │  │          │ │              │  │ │  Persistent       │  │
│  │ 280px fixed │ │  │ Optional │ │ flex: 1      │  │ │  across rooms     │  │
│  │             │ │  │ 280px    │ │              │  │ │                   │  │
│  └─────────────┘ │  └──────────┘ └──────────────┘  │ │  280px-33vw       │  │
│                  │                                 │ │                   │  │
│                  │  flex: 1                        │ │  flex: 0          │  │
│                  └─────────────────────────────────┘ └───────────────────┘  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

Panel Taxonomy

All panels share common styling patterns but serve different purposes.

Panel Types

Panel Position Purpose Width Content Alignment
Header Bar Top Room nav, profile 56px height Logo in bulge, rest at bottom
Nav Panel Left Room-level section nav 280px fixed Header docked to bottom
Filter Panel Left (inside content) Data filtering/search 280px fixed Header docked to bottom
Detail Panel Right (inside content) Selected item details 320-400px Standard header
Chat Dock Right AI assistant 280px-33vw Standard header

Panel Header Behavior

All left-side panels (Nav Panel, Filter Panel) dock their header content to the bottom of the header area. This accommodates the logo bulge that overlays into their space.

┌─────────────────────────┐
│                         │  ← Logo bulge overlays this space
│         (empty)         │
│                         │
│  [Icon] Title   [Action]│  ← Content docked to bottom (8px margin)
├─────────────────────────┤
│  Panel content...       │

Right-side panels (Detail Panel, Chat Dock) use standard vertically-centered headers since the logo bulge doesn't reach them.


Panel Configurations by Room

Front Hall

┌────────────────────────────────────────────────────────────────┬────────────┐
│  PRIMARY CONTENT (no nav panel)                                │ CHAT DOCK  │
│  Dashboard cards, activity feed                                │ (expanded) │
└────────────────────────────────────────────────────────────────┴────────────┘

Control Room

┌───────────┬──────────────────────────────────────────────────────┬──────────┐
│ NAV PANEL │  PRIMARY CONTENT                                     │ CHAT     │
│           │  ┌────────────┬────────────────────────────────────┐ │ DOCK     │
│ Sections: │  │ FILTER     │ DATA GRID                          │ │          │
│ • Contai. │  │ PANEL      │ Container/Stack list               │ │ (collap- │
│ • Stacks  │  │            │                                    │ │  sed)    │
│ • Network │  │ Stack list │                                    │ │          │
│ • Volumes │  │ + search   │                                    │ │          │
└───────────┴──┴────────────┴────────────────────────────────────┴─┴──────────┘

Parlor

┌───────────┬────────────────────────────────────────────────────┬────────────┐
│ NAV PANEL │  PRIMARY CONTENT                                   │ CHAT DOCK  │
│           │  Device controls, scenes                           │ (collapsed)│
│ Areas:    │                                                    │            │
│ • Living  │                                                    │            │
│ • Bedroom │                                                    │            │
│ • Kitchen │                                                    │            │
└───────────┴────────────────────────────────────────────────────┴────────────┘

Component Roles

Component Flex Description
Header Bar intrinsic (56px) Logo bulge, room icons, profile menu
Nav Panel flex: 0, 280px Room-level section navigation
Filter Panel flex: 0, 280px Data filtering within a section
Primary Content flex: 1 Main working area
Detail Panel flex: 0, 320-400px Selected item details (optional)
Chat Dock flex: 0, intrinsic Tatlock assistant, collapsible

Responsive Breakpoints

Wide (>= 1200px)

┌───────────┬─────────────────────────────────────────────┬────────────────────┐
│ NAV PANEL │  [Filter Panel]  [═══ Data Grid ═══]        │  CHAT DOCK         │
│ (280px)   │  (280px)         (flex: 1)                  │  (expanded, 320px) │
└───────────┴─────────────────────────────────────────────┴────────────────────┘
  • All panels visible
  • Chat dock expanded by default on Front Hall
  • Nav panel visible with full labels
  • Filter panel visible (where applicable)
  • Full data grid columns

Medium (>= 800px, < 1200px)

┌───────────┬───────────────────────────────────────────────────────────┬────┐
│ NAV PANEL │  [Filter Panel]  [═══════════ Data Grid ═══════════]      │ 💬 │
│ (280px)   │  (280px)         (flex: 1)                                │48px│
└───────────┴───────────────────────────────────────────────────────────┴────┘
  • Chat dock collapsed to icon rail (48px)
  • Click chat icon to expand as overlay
  • Nav panel still visible
  • Filter panel still visible
  • Data grid may hide some columns

Compact (>= 600px, < 800px)

┌────┬───────────────────────────────────────────────────────────────────┬────┐
│ ≡  │  [═══════════════════════ Content ═══════════════════════]        │ 💬 │
│48px│  Filter panel becomes top bar or collapsible                      │48px│
└────┴───────────────────────────────────────────────────────────────────┴────┘
  • Nav panel collapses to icon rail (48px), expands as drawer on tap
  • Filter panel moves to top of content or becomes collapsible
  • Chat dock remains collapsed (48px)
  • Data grid shows essential columns only

Mobile (< 600px)

┌────────────────────────────────────────────────────────────────────────┐
│  HEADER: [≡] [Room Icons scroll] ─────────────────────────────── [💬] │
├────────────────────────────────────────────────────────────────────────┤
│                                                                        │
│  [═══════════════════════ Content ══════════════════════]              │
│  Filter as expandable section at top                                   │
│                                                                        │
└────────────────────────────────────────────────────────────────────────┘
  • Single column layout
  • Nav panel opens as full-screen drawer (hamburger menu)
  • Filter panel becomes expandable section at top of content
  • Chat opens as bottom sheet (60vh max)
  • Data grid becomes card list or single-column table

Panel Folding Summary

Panel Wide (≥1200) Medium (≥800) Compact (≥600) Mobile (<600)
Nav Panel 280px visible 280px visible 48px rail → drawer Hidden → drawer
Filter Panel 280px visible 280px visible Collapsed/top bar Expandable section
Chat Dock 320px expanded 48px rail → overlay 48px rail → overlay Icon → bottom sheet
Detail Panel 320-400px slide-in 320px slide-in Full-width overlay Full-screen

Component Constraints

Component Min Width Max Width Collapse Behavior
Chat Dock (expanded) 280px 33vw Collapses to icon rail
Chat Dock (collapsed) 48px 48px -
Context Sidebar 200px - Collapses to 56px icon rail, then drawer
Stat Card 180px 1fr Grid reflows
Service Card 120px 1fr Grid reflows
Data Grid 400px - Horizontal scroll if needed

Room Wireframes

Front Hall (Dashboard)

Primary landing page. Chat dock expanded by default.

┌─────────────────────────────────────────────────────────────┬─────────────────┐
│                                                             │                 │
│  STAT CARDS (auto-fit grid, min 180px)                      │  TATLOCK CHAT   │
│  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │                 │
│  │ CPU         │ │ Memory      │ │ Disk        │ │Containe│ │  [conversation] │
│  │ 45%         │ │ 62%         │ │ 78%         │ │ 34/40  │ │                 │
│  │ ████████░░░ │ │ ██████████░ │ │ ███████████ │ │ ██████ │ │                 │
│  └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │                 │
│                                                             │                 │
│  QUICK ACCESS (auto-fill grid, min 120px)                   │                 │
│  ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐    │                 │
│  │ 🎬     │ │ 🔍     │ │ 📚     │ │ 🎮     │ │ 🌐     │    │                 │
│  │Jellyfin│ │SearXNG │ │ Wiki   │ │ AMP    │ │Requests│    │                 │
│  │● Online│ │● Online│ │● Online│ │● Online│ │● Online│    │                 │
│  └────────┘ └────────┘ └────────┘ └────────┘ └────────┘    │                 │
│                                                             │                 │
│  RECENT ACTIVITY                                            │  [input field]  │
│  ┌────────────────────────────────────────────────────────┐ │                 │
│  │ 📦 Container 'ollama' restarted            15 min ago  │ │                 │
│  │ 🏠 Living room set to evening mode          1 hr ago   │ │                 │
│  │ 🔄 System backup completed                  2 hrs ago  │ │                 │
│  └────────────────────────────────────────────────────────┘ │                 │
│                                                             │                 │
└─────────────────────────────────────────────────────────────┴─────────────────┘

Components:

  • Stat Cards: CPU, Memory, Disk, Containers
  • Quick Access: Service cards grid (external links)
  • Recent Activity: Timeline of system events

Control Room (Infrastructure)

Context sidebar with section navigation. Chat collapsed.

┌───────────────┬───────────────────────────────────────────────────────┬──────┐
│               │                                                       │      │
│  SECTIONS     │  CONTAINERS                        [Search] [+ New]   │  💬  │
│               │  ─────────────────────────────────────────────────── │      │
│  ▸ Containers │  ☑ NAME          STATUS    CPU    MEM    IMAGE    ⋮  │      │
│    Stacks     │  ☐ jellyfin      ● Run     2.3%   1.2GB  latest   ⋮  │      │
│    Networks   │  ☐ ollama        ● Run     45%    8.0GB  0.1.32   ⋮  │      │
│    Volumes    │  ☐ postgres      ● Run     1.1%   512MB  16-alp   ⋮  │      │
│    Images     │  ☐ redis         ● Run     0.2%   128MB  7-alp    ⋮  │      │
│               │  ☐ authentik     ○ Stop    -      -      2024.2   ⋮  │      │
│  ──────────── │  ─────────────────────────────────────────────────── │      │
│    Netdata  ↗ │  Showing 5 of 40                    < 1 2 3 4 5 >    │      │
│    Portainer↗ │                                                       │      │
│    NPM      ↗ │                                                       │      │
│               │                                                       │      │
└───────────────┴───────────────────────────────────────────────────────┴──────┘

Components:

  • Context Sidebar: Section nav + external links
  • DataGrid: Container list with bulk actions
  • Detail Panel: Opens on row selection (replaces grid or slides in)

Parlor (Housekeeping)

Context sidebar with areas and scenes. Chat collapsed.

┌───────────────┬───────────────────────────────────────────────────────┬──────┐
│               │                                                       │      │
│  AREAS        │  LIVING ROOM                                          │  💬  │
│               │  ─────────────────────────────────────────────────── │      │
│  ▸ Living Rm  │                                                       │      │
│    Bedroom    │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │      │
│    Kitchen    │  │ 💡       │ │ 📺       │ │ 🌡️       │ │ 🔌       │ │      │
│    Office     │  │ Ceiling  │ │ Samsung  │ │ Thermo   │ │ Outlet 1 │ │      │
│    Garage     │  │ 75%      │ │ OFF      │ │ 72°F     │ │ ON       │ │      │
│               │  │ ○─────●  │ │ [    ]   │ │ [-] [+]  │ │ [    ]   │ │      │
│  ──────────── │  └──────────┘ └──────────┘ └──────────┘ └──────────┘ │      │
│  SCENES       │                                                       │      │
│    🌅 Morning │  SCENES                                               │      │
│    ☀️ Day     │  ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐       │      │
│    🌆 Evening │  │ 🌅   │ │ ☀️   │ │ 🌆   │ │ 🌙   │ │ 🎬   │       │      │
│    🌙 Night   │  │ Morn │ │ Day  │ │ Eve  │ │Night │ │Movie │       │      │
│               │  └──────┘ └──────┘ └──────┘ └──────┘ └──────┘       │      │
└───────────────┴───────────────────────────────────────────────────────┴──────┘

Components:

  • Context Sidebar: Area list + scene shortcuts
  • Device Grid: Control tiles for current area
  • Scene Bar: Quick activation buttons

Grid Specifications

Stat Cards

grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1rem;
Viewport Width Cards per Row
>= 900px 4
>= 720px 3
>= 540px 2
< 540px 1

Service Cards

grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 0.75rem;

Reflows naturally based on available width.


Chat Dock Behavior

The Tatlock chat assistant is omnipresent - accessible from any room.

State Width Trigger
Expanded intrinsic (min 280px, max 33vw) Default on Front Hall, click icon elsewhere
Collapsed 48px (icon rail) Default on other rooms, viewport < 1200px
Overlay 90vw or 400px max Expanded on medium viewports
Bottom Sheet 100vw, 60vh max Mobile viewports
Fullscreen 100vw, 100vh User-triggered overlay (future)

Persistence: Conversation state persists across room navigation.

Future: Fullscreen mode provides an immersive chat experience as a modal overlay, independent of the current room.


Flutter Implementation Notes

Panel Widget Library

All panels are built from shared components in lib/shared/layouts/widgets/:

Widget File Purpose
PanelContainer panel_container.dart Base container for all panels
PanelHeader panel_header.dart Configurable header (bottom-docked or centered)
NavPanel nav_panel.dart Left-side room navigation
FilterPanel filter_panel.dart Left-side data filtering
DetailPanel detail_panel.dart Right-side item details
ChatDock chat_dock.dart Right-side AI assistant

PanelHeader Configuration

/// Panel header with configurable content alignment.
class PanelHeader extends StatelessWidget {
  const PanelHeader({
    required this.title,
    required this.icon,
    this.actions,
    this.dockToBottom = false, // true for left-side panels
  });
}

Left-side panels (Nav, Filter) use dockToBottom: true to accommodate the logo bulge:

  • Header height: 56px (matches app header)
  • Content aligned to bottom with 8px margin
  • Empty space at top allows logo bulge overlay

Right-side panels (Detail, Chat) use dockToBottom: false:

  • Standard vertically-centered content
  • No accommodation needed for logo bulge
Concept Flutter Widget
Breakpoint detection LayoutBuilder, MediaQuery
Main layout Row with Expanded and SizedBox
Collapsible dock AnimatedContainer or AnimatedSize
Grid layouts GridView.builder with SliverGridDelegateWithMaxCrossAxisExtent
Drawer fallback Scaffold.drawer or custom Drawer
Bottom sheet chat showModalBottomSheet or DraggableScrollableSheet

Breakpoint Constants

abstract class Breakpoints {
  static const double mobile = 600;
  static const double compact = 800;
  static const double medium = 1200;
}

Panel Width Constants

abstract class PanelWidths {
  static const double navPanel = 280;
  static const double filterPanel = 280;
  static const double detailPanel = 360;
  static const double chatDockExpanded = 320;
  static const double chatDockCollapsed = 48;
  static const double railWidth = 48;
}

Layout Builder Pattern

LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth >= Breakpoints.medium) {
      return WideLayout(...);
    } else if (constraints.maxWidth >= Breakpoints.compact) {
      return MediumLayout(...);
    } else {
      return CompactLayout(...);
    }
  },
)