Files
bookhoard/COLLECTIONS_HTMX_IMPLEMENTATION.md
T
john-okeefe 1352d05ca3 docs: add Collections HTMX implementation documentation
Add comprehensive documentation tracking the HTMX Server-Side Rendering
implementation for the Collections page.

Document contents:
- Summary of completed implementation (March 2025)
- Detailed list of all files created and modified
- Step-by-step workflow for each CRUD operation
  (Create, Edit, Delete, Restore System Collection)
- Verification instructions
- Key discoveries and lessons learned:
  * Templ syntax limitations in conditionals
  * Route registration order requirements
  * HTMX fragment theming inheritance
  * Color handling best practices
  * Browser caching considerations

Purpose:
- Historical record of implementation approach
- Reference for future developers
- Documentation of project patterns and conventions
- Guide for troubleshooting similar features
2026-03-01 21:00:43 -05:00

6.5 KiB
Raw Blame History

Collections Page HTMX SSR - COMPLETED

This document tracks the completed HTMX Server-Side Rendering implementation for the Collections page.

Summary

Status: COMPLETED Date: 2025-03-01 Goal: Replace broken JavaScript with HTMX SSR for all collection CRUD operations

What Was Done

1. Created Modal Templates

templates/collection_modal.templ (129 lines)

  • Single modal template for both create and edit
  • Uses conditional if collection.ID != "" to switch modes
  • HTMX forms: hx-post for create, hx-put for edit
  • Tailwind color buttons (no hex colors)
  • CSS variables for theming

templates/restore_system_collection_modal.templ (32 lines)

  • Restore system collections modal
  • HTMX form with hx-post to /api/dashboard/restore-system-collection
  • Dropdown with 4 system collections

2. Added Backend Routes

File: internal/router/frontend.go

Three new routes added (lines 241-294):

  • GET /collections/create-modal - Returns empty modal for create
  • GET /collections/:id/edit-modal - Returns modal with collection data for edit
  • GET /collections/restore-modal - Returns restore system collection modal

Important: Routes placed BEFORE /collections/:id to avoid path conflicts.

3. Updated Collections Page Template

File: templates/collections.templ

Removed:

  • Old delete confirmation modal (lines 21-37)
  • Old restore system collection modal (lines 38-66)
  • Old create modal with inline JavaScript (lines 148-198)

Already in place:

  • Modal container <div id="modal-container"></div>
  • HTMX buttons for create/edit/restore
  • hx-confirm for delete
  • hx-redirect for page reload after operations
  • Script tag: <script src="/static/collections.js"></script>

4. Created TypeScript Helper

File: web/src/collections.ts

Functions:

  • selectColor(color: string) - Color selection with visual feedback
  • closeCollectionModal() - Closes modal and resets form
  • initColorSelection() - Initializes color selection on page load

Compiled to: web/static/collections.js

5. Generated Templates

Ran templ generate to create:

  • templates/collection_modal_templ.go
  • templates/restore_system_collection_modal_templ.go

6. Followed Project Guidelines

  • TailwindCSS classes only (bg-blue-500, etc.)
  • CSS variables for theming (var(--text-primary), etc.)
  • TypeScript only (no JavaScript)
  • No OOP (functional style)
  • Full SSR with HTMX
  • Progressive enhancement (forms work without JS)

How It Works

Create Collection

  1. User clicks " New Collection" button
  2. HTMX sends GET to /collections/create-modal
  3. Server renders modal (empty form)
  4. HTMX swaps modal into #modal-container
  5. User fills form and clicks "Create Collection"
  6. HTMX form submits with hx-post="/api/collections"
  7. On success, hx-redirect reloads /collections page

Edit Collection

  1. User clicks ✏️ button on collection card
  2. HTMX sends GET to /collections/{id}/edit-modal
  3. Server fetches collection data and renders modal (pre-filled)
  4. HTMX swaps modal into #modal-container
  5. User modifies and clicks "Update Collection"
  6. HTMX form submits with hx-put="/api/collections/{id}"
  7. On success, hx-redirect reloads /collections page

Delete Collection

  1. User clicks 🗑️ button on collection card
  2. HTMX hx-confirm shows browser's native confirm dialog
  3. User clicks "Delete"
  4. HTMX sends DELETE to /api/collections/{id}
  5. On success, hx-redirect reloads /collections page

Restore System Collection

  1. User clicks "🔄 Restore System" button
  2. HTMX sends GET to /collections/restore-modal
  3. Server renders restore modal
  4. HTMX swaps modal into #modal-container
  5. User selects collection and clicks "Restore"
  6. HTMX form submits with hx-post="/api/dashboard/restore-system-collection"
  7. On success, hx-redirect reloads /collections page

File Changes

Created Files

  • templates/collection_modal.templ
  • templates/collection_modal_templ.go (generated)
  • templates/restore_system_collection_modal.templ
  • templates/restore_system_collection_modal_templ.go (generated)

Modified Files

  • templates/collections.templ - Removed old JavaScript modals, cleaned up to 147 lines
  • web/src/collections.ts - Color selection functions
  • internal/router/frontend.go - Added 3 modal routes

Compiled Files

  • web/static/collections.js - Compiled from TypeScript

Verification

To verify the implementation works:

# Build TypeScript
npm run build

# Generate templates
templ generate

# Build application
go build ./...

# Start server
podman compose up -d

# Check logs
podman compose logs -f server

Test at http://localhost:8080/collections:

  • Create new collection
  • Edit existing collection
  • Delete collection (with confirmation)
  • Restore system collection
  • View collection details

Key Discoveries

1. Templ Syntax

Cannot use complex conditionals in attribute values:

 style="border-color: { if collection.ID != "" { collection.Color } else { "blue" } }"
 style="border-color: { collection.Color }"

2. Route Order

Modal routes must come before detail routes:

 frontendProtected.GET("/collections/create-modal", ...)
 frontendProtected.GET("/collections/:id/edit-modal", ...)
 frontendProtected.GET("/collections/:id", ...) // Must be last

3. HTMX Fragment Inheritance

Modal fragments inherit theme from parent page:

  • No <html>, <head>, or <body> tags in modal templates
  • Parent page has <body class="theme-{ user.Theme }">
  • CSS variables work correctly in modals

4. Color Handling

Backend ensures colors are valid:

  • Defaults to "blue" if empty
  • Stored as semantic names: "blue", "red", "yellow", "green", "purple"
  • Tailwind classes: bg-blue-500, bg-red-500, etc.

5. Page Reload Cache

Browsers cache aggressively. Use hx-redirect for clean reload after CRUD operations.

Next Steps

Implementation is complete. Optional enhancements:

  1. Validation: Add client-side validation for collection name length
  2. Bulk operations: Add bulk delete for multiple collections
  3. Sorting: Add drag-and-drop reordering
  4. Search: Add collection search/filter
  5. Export: Add JSON export/import

Notes

  • Why HTMX? Follows project guidelines for SSR with minimal JavaScript
  • Why single modal template? Reduces duplication, easier maintenance
  • Why modal as fragment? Inherits theming from parent, no duplicate HTML
  • Progressive enhancement: Forms work without JavaScript (redirect after submit)