-
-
Notifications
You must be signed in to change notification settings - Fork 180
Open
Description
Overview
Implement a Views module that serves as the foundation for all admin list pages. Instead of separate hardcoded implementations for content list, collections list, users list, etc., Views provides a unified system for querying and displaying data in tables.
This is inspired by Drupal's Views module but simplified for a headless CMS context.
Core Concept
Views are saved queries with configurable table display. Users can:
- Create a view by selecting a base table/collection
- Choose which fields to display as columns
- Set default filters and sorts
- Optionally expose filters for users to adjust
- Save and reuse the view
Architecture
┌─────────────────────────────────────────────────┐
│ ViewRenderer │
│ (single component renders any view as table) │
└─────────────────────────────────────────────────┘
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ System │ │ System │ │ Custom │
│ Views │ │ Views │ │ Views │
│(content, │ │(users, │ │ (user │
│collections)│ │ media) │ │ created) │
└───────────┘ └───────────┘ └───────────┘
System views = Built-in, non-deletable, power existing admin pages
Custom views = User-created for their collections
Benefits
- DRY - One table renderer, one filter form builder, one pagination component
- Customizable - Users can modify default views (add columns, change filters)
- Consistent UX - Same patterns across all list pages
- Less code - Remove duplicated list template implementations
- Extensible - New list pages are just view configurations
Data Model
views Table
CREATE TABLE views (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
display_name TEXT NOT NULL,
description TEXT,
-- Query source
base_table TEXT NOT NULL, -- 'content', 'collections', 'users', 'media'
collection_id TEXT, -- For content views, which collection (NULL = all)
-- What fields to show (JSON array)
columns TEXT NOT NULL,
-- Default filters (JSON - QueryFilter format)
default_filters TEXT,
-- Default sort (JSON array)
default_sort TEXT,
-- Which filters users can adjust (JSON array)
exposed_filters TEXT,
-- Row actions (JSON array) - edit, delete, duplicate, etc.
row_actions TEXT,
-- Bulk actions enabled (JSON array)
bulk_actions TEXT,
-- Pagination
items_per_page INTEGER DEFAULT 20,
-- System view flag (cannot be deleted)
is_system INTEGER DEFAULT 0,
-- Metadata
is_active INTEGER DEFAULT 1,
created_by TEXT REFERENCES users(id),
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);Column Configuration
interface ViewColumn {
field: string // "data.title", "status", "created_at", "author.email"
label: string // Display label
sortable?: boolean // Allow sorting by this column
width?: string // CSS width
renderer?: string // Custom renderer: 'status_badge', 'date', 'author_avatar', 'link'
}Exposed Filter Configuration
interface ExposedFilter {
field: string
label: string
type: 'text' | 'select' | 'status' | 'date' | 'date_range'
options?: { value: string; label: string }[]
}System Views (Pre-installed)
1. Content List View
Replaces current /admin/content implementation
{
"name": "system_content",
"display_name": "All Content",
"base_table": "content",
"collection_id": null,
"columns": [
{ "field": "title", "label": "Title", "sortable": true, "renderer": "link" },
{ "field": "collection.display_name", "label": "Collection", "sortable": true },
{ "field": "status", "label": "Status", "renderer": "status_badge" },
{ "field": "author.name", "label": "Author", "renderer": "author_avatar" },
{ "field": "updated_at", "label": "Updated", "sortable": true, "renderer": "date" }
],
"exposed_filters": [
{ "field": "collection_id", "label": "Collection", "type": "select" },
{ "field": "status", "label": "Status", "type": "status" },
{ "field": "search", "label": "Search", "type": "text" }
],
"default_sort": [{ "field": "updated_at", "order": "desc" }],
"row_actions": ["edit", "duplicate", "delete"],
"bulk_actions": ["publish", "unpublish", "delete"],
"is_system": true
}2. Collections List View
Replaces current /admin/collections
3. Users List View
Replaces current /admin/users
4. Media Library View
Replaces current /admin/media
Implementation Tasks
Phase 1: Core Infrastructure
- Add
viewstable to schema.ts - Create migration
- Add Zod validation schemas and TypeScript types
- Create
ViewServiceclass (CRUD + query execution) - Create
ViewQueryBuilder(extends/uses QueryFilterBuilder)
Phase 2: Admin UI Components
- Create
ViewRenderercomponent (renders any view as table) - Create
ExposedFilterFormcomponent - Create
RowActionscomponent - Create
BulkActionscomponent - Create cell renderers (status_badge, date, link, author_avatar)
Phase 3: Admin Routes & Templates
- Create
/admin/viewsroutes - Views list template
- View builder form template
- View results template
Phase 4: System Views
- Create system view seed data
- Wire up
/admin/contentto use system content view - Wire up
/admin/collectionsto use system collections view - Wire up
/admin/usersto use system users view - Wire up
/admin/mediato use system media view
Phase 5: Cleanup
- Remove old hardcoded list templates
- Remove old list-specific route handlers
- Update admin sidebar menu
Files to Create
packages/core/src/
├── db/schema.ts # Add views table
├── services/view-service.ts # View CRUD & query execution
├── services/view-query-builder.ts # SQL generation
├── routes/admin-views.ts # Admin routes
├── templates/
│ ├── components/
│ │ ├── view-renderer.template.ts # Main table renderer
│ │ ├── view-exposed-filters.template.ts # Filter form
│ │ ├── view-row-actions.template.ts # Per-row actions
│ │ ├── view-bulk-actions.template.ts # Bulk action bar
│ │ └── view-cell-renderers.template.ts # Status badge, date, etc.
│ └── pages/
│ ├── admin-views-list.template.ts # List of views
│ └── admin-views-form.template.ts # Create/edit view
├── seeds/system-views.ts # Pre-installed system views
Files to Modify
packages/core/src/
├── app.ts # Register views routes
├── templates/layouts/admin-layout-catalyst.template.ts # Add Views menu item
Files to Eventually Remove
packages/core/src/templates/pages/
├── admin-content-list.template.ts # Replaced by ViewRenderer
├── admin-collections-list.template.ts # Replaced by ViewRenderer
├── admin-users-list.template.ts # Replaced by ViewRenderer
Out of Scope for v1
- Multiple display formats (grid, cards) - table only
- Field formatters beyond basic (date, status_badge, link)
- Complex relationships beyond author
- Aggregation (COUNT, SUM)
- View cloning/export/import
- Access control per view
- Caching layer
Success Criteria
v1 is complete when:
- ✅ Views can be created/edited/deleted from admin
- ✅ Custom views work for any collection
- ✅ System content view powers
/admin/content - ✅ Exposed filters work with HTMX live updates
- ✅ Row actions (edit, delete) work
- ✅ Bulk actions work
- ✅ Pagination works
- ✅ Old content list template is removed
References
Metadata
Metadata
Assignees
Labels
No labels