## Summary
Adds the authoring experience for dashboard sections (create, rename, delete, manage tiles) and introduces a polymorphic `DashboardContainer` abstraction that future-proofs the schema for tabs and groups.
Builds on #1900 (core collapsible sections mechanics). Closes#1897.
### Schema: `DashboardSection` → `DashboardContainer`
- Renamed `DashboardSectionSchema` → `DashboardContainerSchema` with a new `type` field (`'section'` for now, extensible to `'group'` / `'tab'` later)
- `sectionId` → `containerId` on tiles
- `sections` → `containers` on dashboards
- Updated across all packages: common-utils types, API Mongoose model, app types, import/export utils
### Authoring UX
| Action | How |
|---|---|
| **Create section** | Dashboard `...` overflow menu → "Add Section" |
| **Rename section** | Click the title text directly (Kibana-style inline editing) |
| **Delete section** | Hover section header → `...` → Delete Section (tiles become ungrouped, not deleted) |
| **Collapse/expand** | Click section header chevron |
| **Toggle default state** | Hover header → `...` → Collapse/Expand by Default |
| **Add tile to section** | Hover section header → `+` button opens tile editor pre-assigned to that section |
| **Move tile to section** | Hover tile → grid icon → pick target section from dropdown |
| **Move tile out** | Same dropdown → "(Ungrouped)" |

### UX polish (informed by best practices research)
- **Click-to-rename** — click section title text to edit inline (no menu navigation needed)
- **Hover-only controls** — `...` menu and `+` button only appear on section header hover, keeping view mode clean
- **"Add Section" demoted** — moved from equal-sized button to dashboard overflow menu (section creation is less frequent than tile creation)
- **"Move to Section" reordered** — placed before delete button for discoverability, uses `IconLayoutList` instead of `IconFolders`
### What's NOT in this PR (follow-up work)
- **Drag tiles between sections** — needs `react-dnd` custom drag layer; data model already supports it (`containerId` update)
- **Reorder sections** — needs sortable list library; data model supports it (array order)
- **Tabs / Groups** — new container types; just add to the `type` enum and build UIs
## Test plan
- [x] 30 unit tests pass (16 existing schema/grouping + 14 new authoring operations)
- [x] All 110 dashboard tests pass unchanged
- [x] ESLint clean
- [x] No TypeScript errors in changed files
- [x] Backward compatible — dashboards without containers render exactly as before
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
- Adds data model support for collapsible sections: `DashboardSection` schema with `id`, `title`, `collapsed` fields
- Tiles can optionally reference a section via `sectionId`
- Dashboards gain an optional `sections` array
- `SectionHeader` component renders a clickable bar with chevron toggle and tile count when collapsed
- Per-section `ReactGridLayout` grids: collapsed sections don't mount tiles at all, so no queries fire (lazy loading)
- Fully backward compatible — dashboards without sections render exactly as before
## Architecture
Uses a **multi-grid** approach: each section gets its own `ReactGridLayout` instance. This avoids the y-offset shifting complexity of a single-grid approach and gives us lazy loading for free (collapsed sections = unmounted tiles = no API calls).
Key tradeoff: cross-section drag-and-drop is not supported in this PR — that's addressed in the follow-up authoring UX issue (#1897).
## Test plan
- [x] 13 new tests covering schema validation, backward compatibility, tile grouping, and lazy loading filtering
- [x] All 93 existing dashboard tests pass unchanged
- [x] ESLint clean (no errors)
- [x] TypeScript compiles without errors in changed files
Closes#1896🤖 Generated with [Claude Code](https://claude.com/claude-code)