3.4 KiB
3.4 KiB
Design Document: Krate (Window Group) Feature Specification
Overview
A krate is a named group of detail windows for a single Kubernetes object or collection. Krates live on the canvas and serve as organizational units for related workspace views.
Core Responsibilities
- Group related windows together visually and logically
- Auto-fit frame around contained windows
- Manage window layout within krate boundaries
- Handle krate-level interactions (move, drag, collapse, expand)
Visual Container
Krate Frame
- Dashed border:
border: 1px dashed rgba(color, .3),border-radius: 18px - Background:
rgba(color, .04)(subtle color tint) - Auto-fit: Frame adjusts to bounding box of all windows + 30px padding
- Color: Matches namespace palette (e.g., payments:
#6fb1ff)
Header Bar
Above the frame:
- Shows object name + status badge + window count
- Drag handle: Move entire krate
- × button: Dismiss krate
- Minimize button (
—): Collapse to overview card - Double-click header: Collapse/expand toggle
Window Layout
Grid System
- Windows tiled in 2-column grid
- Column 0:
dx: 0 - Column 1:
dx: 412 - Row height: 416px
- Window default size: 380×362px
Properties
- Windows never overlap (snap-to-grid on release)
- When one window resized, siblings resize proportionally in same column/row
- Storage:
interface Window { wid: string; kind: 'detail' | 'collection'; tab: 'logs' | 'shell' | 'describe' | 'yaml'; dx: number; // offset within krate (column * 412) dy: number; // offset within krate (row * 416) w: number; h: number; }
Krate Interactions
Dragging
- Drag header = move entire krate
- Non-overlapping placement: On drag release, nudge to avoid overlap with other krates
- Gentle snap, not strict grid (allows flexibility while preventing overlap)
Collapse/Expand
- Minimized state: 230px-wide card showing:
- Name
- View-letter badges (Y/D/L/S)
- Status dot
- Window count
- Namespace
- Double-click collapsed card: Re-expand and fly camera to krate
Camera Fly
- On krate creation: animate camera to center krate at
zoom: 0.92 - Duration:
.52s cubic-bezier(.22,.8,.28,1) - Position: center of krate's bounding box
Krate State
interface Krate {
id: string;
objId: string | null; // null for collection krates
collScope?: { kind: 'namespace' | 'category', value: string };
label: string; // display name
status: string; // status badge text
color: string; // hex, from namespace palette
wx: number; wy: number; // world position (top-left of frame)
minimized: boolean;
windows: Window[];
seq: number; // for generating unique window IDs
}
Non-Overlapping Placement Algorithm
- Try computed default position
- Check bounding boxes against all existing krates
- If overlap, nudge by fixed increments (e.g., 20px right/down)
- Repeat until no overlap
- Same algorithm used on creation AND drag release
Gotchas
- Auto-fit frame: Re-compute bounding box whenever windows are added/removed/moved/resized
- Non-overlapping: Use AABB (Axis-Aligned Bounding Box) collision detection
- Window grid: Store
colWidthsandrowHeightsarrays for proper resize relationships (future enhancement) - Krate ID:
objIdis null for collections; otherwise references the Kubernetes object ID