Skip to content

Commit 6e55939

Browse files
authored
Merge pull request #114 from keyxmakerx/claude/fix-navbar-features-page-8RZuE
Claude/fix navbar features page 8 r zu e
2 parents cea673d + 0ed8c39 commit 6e55939

54 files changed

Lines changed: 4211 additions & 244 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ai/decisions.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,3 +1019,34 @@ is skipped for trusted built-in plugins but enforced for user extensions via
10191019
(calendar before sessions/timeline).
10201020
- Removed migrate_preflight.go and bandaid lint tests from migrate_test.go.
10211021
- Fresh DB only — no backward compatibility with the old 63-migration sequence.
1022+
1023+
---
1024+
1025+
## ADR-029: Features Page Consolidation (Plugin Hub + Addon Settings → Single Page)
1026+
1027+
**Date:** 2026-03-10
1028+
**Status:** Accepted
1029+
1030+
**Context:** Campaign feature management was split across two pages:
1031+
1. **Plugin Hub** (`/campaigns/:id/plugins`) — read-only card grid visible to all members.
1032+
2. **Addon Settings** (`/campaigns/:id/addons/settings`) — owner-only toggle list.
1033+
1034+
This created confusion: owners had two "features" pages with different layouts and
1035+
capabilities. Non-owners could see features but couldn't tell which were enabled.
1036+
1037+
**Decision:** Consolidate into a single Features page at `/campaigns/:id/plugins`.
1038+
- All members see the card grid with enable/disable status.
1039+
- Owners see inline toggle buttons on each card.
1040+
- The old `/addons/settings` route, handler, and full-page template are removed.
1041+
- The addons fragment route (`/addons/fragment`) remains for the Customization Hub.
1042+
- Toggle forms include `redirect_to=plugins` so the handler redirects back to the
1043+
unified page after toggling.
1044+
1045+
**Alternatives considered:**
1046+
- Keep both pages with cross-links: still confusing, maintenance burden.
1047+
- Merge into the Customization Hub: too buried, features deserve top-level access.
1048+
1049+
**Consequences:**
1050+
- Single source of truth for feature management.
1051+
- Owners can manage features directly from the same page all members see.
1052+
- Future enhancements (per-addon entity usage, "offline" banners) have one target page.

.ai/status.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,66 @@
88
<!-- ====================================================================== -->
99

1010
## Last Updated
11+
2026-03-11 -- **Sprint W-0.5: Visual Customization (IN PROGRESS).**
12+
13+
25. Starting W-0.5: Per-campaign brand name/logo, topbar color/gradient/image customization, visual editor Appearance tab in Customization Hub. Also fixing 3 bugs from W-0 (event listener leak in sidebar_tree.js, touch listener cleanup in sidebar_reorg.js, ES2020 optional chaining compat) and updating stale entity/campaign documentation.
14+
15+
### Previous Update
16+
2026-03-11 -- **Sprint W-0: Nav Menu Reorg Mode (COMPLETE).**
17+
18+
24. W-0 complete: Sidebar reorg mode toggle button (Owner-only, grip icon next to "Categories" header), inline category drag-to-reorder with visibility toggles, conditional entity drag-and-drop (only active in reorg mode), touch D&D support for mobile, `data-entity-type-id` on category links, auto-exit on navigation. New file `sidebar_reorg.js`. Modified `sidebar_tree.js` to gate D&D behind `data-reorg-active`. Relations `.ai.md` updated with graph visualization features.
19+
20+
### Previous Update
21+
2026-03-10 -- **Sprint V-4: Enhanced Graph View & Cover Images (COMPLETE).**
22+
23+
18. **@Mention edges in graph**: `FindAllMentionLinks()` in entity repository scans `entry_html` for `data-mention-id` attributes across a campaign. `MentionLink` model. `GetMentionLinks()` service method. `MentionLinkProvider` interface bridges entities→relations without circular imports. Mention edges appear as dashed purple lines in the D3 graph.
24+
25+
19. **Graph API filtering**: `GetFilteredGraphData()` with `GraphFilter` struct supporting `types` (entity type slugs), `search` (name match), `focus`+`hops` (BFS local/ego graph), `include_mentions`, `include_orphans`. BFS subgraph extraction via `bfsSubgraph()`. `GraphEdge.Kind` field distinguishes "relation" vs "mention" edges.
26+
27+
20. **Graph UI enhancements**: Updated `relation_graph.js` with: filter toolbar (type multi-select, search input, mention toggle, orphan toggle), dashed mention edges with purple color, node sizing by connection count, type-based clustering via `d3.forceX/forceY`, orphan nodes with dotted borders, enhanced legend showing edge types and orphan indicator.
28+
29+
21. **Graph page template updates**: `GraphPage` handler now fetches entity types for filter dropdown. Template passes entity types as JSON via `data-entity-types` attribute. `EntityTypeListerForGraph` interface with adapter.
30+
31+
22. **Cover image layout block**: Migration `000004_cover_image` adds `cover_image_path` column to entities. `cover_image` block type registered in block registry. `blockCoverImage()` templ component with configurable height (sm/md/lg) and overlay (none/gradient/dark). `UpdateCoverImageAPI` endpoint at `PUT /campaigns/:id/entities/:eid/cover-image`. Reuses `image-upload` widget for upload.
32+
33+
23. **Local graph block**: `local_graph` block type registered in block registry. `blockLocalGraph()` renders a mini `relation-graph` widget with `data-focus-entity` and `data-hops` attributes for ego-graph mode on entity profile pages.
34+
35+
### Previous Update
36+
2026-03-10 -- **Sprint V-3: Content Templates (COMPLETE).**
37+
38+
12-17. Content templates: migration, CRUD, template picker, editor slash command, default templates, Customization Hub tab.
39+
40+
### Previous Update
41+
2026-03-10 -- **Cleanup & consolidation pass after bug fixes.**
42+
43+
7. **JSON injection fix**: HX-Trigger header in `CreateEntityType` error path used string concatenation to build JSON. Replaced with `json.Marshal()` to prevent malformed JSON from error messages containing special characters.
44+
45+
8. **Orphaned addon settings page removed**: Deleted `/addons/settings` route, `CampaignAddonsPage` handler, and `CampaignAddonsPageTempl` template — all superseded by the unified Plugin Hub at `/plugins`. Fragment route (`/addons/fragment`) kept for Customization Hub.
46+
47+
9. **Fallback redirect updated**: `ToggleCampaignAddon` non-HTMX fallback now redirects to `/plugins` instead of the removed `/addons/settings`.
48+
49+
10. **Dead HTMX attributes cleaned**: Removed `hx-target`/`hx-swap` from Plugin Hub toggle forms since the handler always responds with `HX-Redirect` (the swap targets were never used).
50+
51+
11. **ADR-029 recorded**: Features page consolidation decision documented in `.ai/decisions.md`.
52+
53+
### Previous Update
54+
2026-03-10 -- **Bug fixes & UX improvements (navbar, features page, entity templates).**
55+
56+
1. **Drag-and-drop CSRF fix**: `sidebar_tree.js` reorderEntity() was using raw `fetch()` without CSRF token, causing 403 on drag-drop reorder. Added `Chronicle.getCsrf()` header.
57+
58+
2. **Nav menu lag fix**: `sidebar_drill.js` category switching caused stale content flash. Now shows loading spinner immediately and uses prefetch cache for instant swaps.
59+
60+
3. **Entity template creation fix**: `entity_types.templ` form lacked `hx-target`/`hx-swap`, causing broken page when HTMX swapped full page into form. Added proper targeting, partial response on error, and `chronicle:notify` HX-Trigger support in notifications.js.
61+
62+
4. **Features page consolidation**: Merged Plugin Hub (read-only) and Addon Settings (management) into a single Features page at `/campaigns/:id/plugins`. Owners see inline enable/disable toggles. Added `AddonID` and `Installed` fields to `PluginHubAddon`. Settings page link now points to `/plugins`. Toggle handler supports `redirect_to=plugins` for redirect after toggle.
63+
64+
5. **Quick notes discoverability**: After creating a quick note, toast now includes a clickable "View in Journal" link. Added `html` option to `Chronicle.notify()`.
65+
66+
6. **Fully hideable navbar**: Added sidebar hide button (double-angle-left icon) next to pin button. When hidden, sidebar fully disappears (0px width). Floating restore button appears at top-left. State persists in `localStorage`.
67+
68+
Branch: `claude/fix-navbar-features-page-8RZuE`.
69+
70+
### Previous Update
1171
2026-03-10 -- **Per-player visibility + Co-DM grants (Phase 2 complete).** Implemented per-player content sharing across all content types:
1272

1373
1. **Maps**: Added `visibility_rules` JSON column to `map_markers` and `map_drawings` (migration 002). Updated repository to filter with `JSON_CONTAINS` for non-owners. Updated `ListMarkers` signature to include `userID` for per-player filtering.

.ai/todo.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ Known broken or missing things, ordered by severity.
3333

3434
### Medium
3535

36+
- [x] **Drag-and-drop sidebar reorder fails with 403**`sidebar_tree.js:reorderEntity()` used raw `fetch()` without CSRF token. Fixed by adding `Chronicle.getCsrf()` to headers.
37+
- [x] **Nav menu flashes stale content on category switch**`sidebar_drill.js` kept old content visible during HTMX fetch. Fixed with immediate loading spinner and prefetch cache usage.
38+
- [x] **Entity template creation form broken for HTMX** — Form lacked `hx-target`/`hx-swap`, and error handler returned full page for HTMX requests. Added proper targeting, partial response, and `chronicle:notify` HX-Trigger support.
39+
- [x] **Features page appears duplicated** — Plugin Hub (read-only) and Addon Settings (management) were separate pages. Consolidated into single `/plugins` page with inline enable/disable toggles for owners.
40+
- [x] **Quick notes not discoverable after creation** — Toast only said "Note created" with no link. Added "View in Journal" clickable link in toast. Added `html` option to `Chronicle.notify()`.
41+
3642
- [x] **Unified permission model (Phase 1)** — Created `internal/permissions/role.go` with shared role constants and `CanSeeDmOnly`/`CanSetDmOnly` helpers. Replaced ~30 magic `role >= 3` checks across calendar, timeline, maps, entities, syncapi, app/routes. Fixed dm_only inconsistencies: tags now Owner-only (was Scribe+). Added Owner-only guards on dm_only creation in calendar events, timeline events, map markers. JS `permissions.js` uses named `ROLE_OWNER` constant. Permission matrix documented in `.ai/conventions.md`.
3743
- [x] **Per-player visibility + Co-DM grants (Phase 2)** — Maps: `visibility_rules` JSON on markers/drawings with `JSON_CONTAINS` filtering. Notes: `shared_with` JSON with Private/Everyone/Specific Players UI + member picker popover. Co-DM: `DmGrantIDs` in CampaignSettings, `IsDmGranted` in CampaignContext, `VisibilityRole()` method, DM grants API + settings UI. DM-granted users see dm_only content but cannot create it.
3844
- [x] **Tags not hideable from players** — Implemented `dm_only` column (migration 000038), role-based filtering in repo/service/handler, eye-slash badge + DM checkbox in tag_picker.js.
@@ -195,12 +201,14 @@ _Quick capture, backlinks, enhanced graph, editor power-ups. See `.ai/obsidian-n
195201
- [x] **Sprint V-1.5: Inline Secrets / DM-Only Blocks in Editor** — SecretMark TipTap extension (Ctrl+Shift+S toggle), `sanitize.StripSecretsHTML/JSON` server-side stripping for non-Scribe, `.chronicle-secret` CSS with amber eye-slash icon, toolbar button. Already implemented alongside V-1.
196202
- [x] **Sprint V-2: Backlinks Panel & Entity Aliases** — HTMX lazy-loaded backlinks with Redis caching + context snippets. Entity aliases table (migration 061), alias CRUD API, aliases widget (tag chips), search/auto-linker/mention integration via `ListNames()` UNION. 11 new tests.
197203
- [x] **Full-Page Journal & Category Nav Redesign** — Full-page journal view at `/campaigns/:id/journal` with two-panel Obsidian-like layout (note tree sidebar + TipTap editor, search, folder tabs, autosave). Journal link in sidebar nav (gated on notes addon). Notes FAB hidden on journal page to avoid sync conflicts. Removed "Session Journal" topbar button. Redesigned sidebar drill panel: merged header + action bar into compact clickable row (category name opens full page, replacing "View All"), count as pill badge, inline "+" button. Entity tree: folder/page icons, guide lines, smooth transitions, distinct reorder vs reparent D&D feedback.
198-
- [ ] **Sprint V-3: Content Templates**Pre-fill editor with structured content (Session Recap, etc.). Template picker in create flow + editor insert.
204+
- [x] **Sprint V-3: Content Templates**`content_templates` table, ContentTemplateService with CRUD + seeding, REST API, template picker on entity create form (loads by entity type), "Insert Template" slash command in editor, 4 default templates (Session Recap, NPC Profile, Location, Quest Log) seeded on campaign creation, Customization Hub "Content Templates" tab for management.
199205
- [ ] **Sprint V-4: Enhanced Graph View & Cover Images**@mention links in graph, entity type/tag filtering, local graph (N hops), clustering, orphan detection. Cover/banner image layout block type for entity pages.
200206
- [ ] **Sprint V-5: Session Journal Audio Attachments** — Audio file upload support in Session Journal notes. Users can attach audio recordings (voice memos, session recordings, ambient tracks) to session notes. Privacy controls: share audio with session participants (public to group) or keep private (visible only to uploader). Media plugin integration for storage/serving. Allowed MIME types: audio/mpeg, audio/ogg, audio/wav, audio/webm. Inline audio player in note view. Migration for audio attachment metadata.
201207

202208
### Phase W: Polish, Ecosystem & Delight
203209

210+
- [x] **Sprint W-0: Nav Menu Reorg Mode** — Small icon button near Dashboard in sidebar. Click to enter reorg mode for current level (categories or entities). Category level: drag to reorder category icons. Entity level: drag to reorder, create folders/submenus. Click again to exit reorg mode. Must work on desktop, tablet, and mobile. Button is context-aware: on base nav, reorders categories; drilled into a category, reorders entities.
211+
- [~] **Sprint W-0.5: Owner Visual Customization** — Change "Chronicle" brand name per-campaign with optional image/logo. Top bar color/gradient/animation/background image (responsive). Visual customization editor with faux site outline (editable boxes for colors/backgrounds). Appearance-only, not layout editing. Future: per-addon "feature in use" indicators showing which entities/pages use each feature, which widgets are available, click associations to navigate. Disabled feature banner with "offline" sticker instead of complete removal.
204212
- [ ] **Sprint W-1: Command Palette & Saved Filters** — Ctrl+Shift+P action palette with fuzzy search. Saved entity list filter presets as sidebar links in `saved_filters` table.
205213
- [ ] **Sprint W-2: Map Drawing Tools, Regions & Measurement** — Leaflet.Draw integration (freehand, polygons, circles, rectangles, text). Uses existing `map_drawings` table. Per-drawing visibility, color/opacity. Also: map regions (polygon fills/strokes/labels), measurement/distance tool, map embed layout block for entity pages.
206214
- [ ] **Sprint W-2.5: Nested / Linked Maps** — Click marker to open sub-map. `linked_map_id` on markers. Breadcrumb navigation between map levels. Competitive gap vs World Anvil/LegendKeeper.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DROP TABLE IF EXISTS content_templates;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
-- Content templates provide pre-filled editor content for entity creation.
2+
-- Templates can be global (is_global=1, campaign_id IS NULL) or per-campaign.
3+
CREATE TABLE IF NOT EXISTS content_templates (
4+
id INT AUTO_INCREMENT PRIMARY KEY,
5+
campaign_id CHAR(36) NULL,
6+
entity_type_id INT NULL,
7+
name VARCHAR(200) NOT NULL,
8+
description VARCHAR(500) NOT NULL DEFAULT '',
9+
content_json JSON NOT NULL,
10+
content_html TEXT NOT NULL DEFAULT '',
11+
icon VARCHAR(50) NOT NULL DEFAULT 'fa-file-lines',
12+
sort_order INT NOT NULL DEFAULT 0,
13+
is_global BOOLEAN NOT NULL DEFAULT FALSE,
14+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
15+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
16+
17+
INDEX idx_ct_campaign (campaign_id),
18+
INDEX idx_ct_entity_type (entity_type_id),
19+
INDEX idx_ct_global (is_global),
20+
21+
CONSTRAINT fk_ct_campaign FOREIGN KEY (campaign_id)
22+
REFERENCES campaigns(id) ON DELETE CASCADE,
23+
CONSTRAINT fk_ct_entity_type FOREIGN KEY (entity_type_id)
24+
REFERENCES entity_types(id) ON DELETE CASCADE
25+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE entities DROP COLUMN cover_image_path;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- Add cover_image_path column to entities for the cover image layout block.
2+
-- Stored separately from image_path (profile thumbnail) to allow both.
3+
ALTER TABLE entities ADD COLUMN cover_image_path VARCHAR(500) DEFAULT NULL AFTER image_path;

0 commit comments

Comments
 (0)