Saved Views
A saved view is a named filter configuration for the content list (the entry browser's "list view"). Capture the filters you use often — content type, site, status, search — under a name, then re-apply them in one click from the Views dropdown.
Views are scoped per tenant + project. Each view is owned by the user who created it and can optionally be shared with the whole project.
What a view stores
{
id: string;
name: string;
description?: string;
filters: { // open-ended; today's axes:
contentType?: string;
site?: string;
locale?: string;
status?: "draft" | "published";
workflowState?: string;
translationStatus?: string;
assignee?: string;
search?: string;
stale?: boolean;
};
sort?: { field: string; direction: "asc" | "desc" } | null;
columns?: string[] | null;
isShared: boolean; // false → creator only, true → all project members
createdById: string;
createdAt: string;
}
filters, sort, and columns are open-ended JSON so new filter axes can be added without a migration. The admin UI currently saves and applies the filters portion (content type, site, status, search); sort and columns are plumbed through the API and model for future list-view controls.
Ownership & visibility
- Visibility: you see your own views (shared or not) plus every view in the project marked
isShared: true. API-key callers see only shared views. - Editing: a view can only be edited or deleted by its creator — even when shared. A non-owner attempting to change one gets
403 view_not_owned. - Sharing is just the
isSharedflag — it controls who can see the view, never who can edit it.
Using views in the admin UI
The content list view (toggle off the tree browser) has a Views dropdown:
- All Content clears all filters.
- My Views — your own views, each with an inline delete button (and a share icon if shared).
- Shared Views — views other members shared with the project (apply-only).
When at least one filter is active, a Save View button appears. It opens a dialog for a name, optional description, and a Share with team checkbox. Changing any individual filter clears the "active view" marker. Filtering is applied in-memory over the loaded rows for a snappy experience on typical project sizes.
API
All paths are prefixed /api/v1/projects/{slug}; every operation requires the read permission.
| Method | Path | Notes |
|---|---|---|
GET | /views | List your own + shared views (newest first). |
POST | /views | Create a view. Requires a signed-in session (401 session_required for API-key callers). |
PUT | /views/{id} | Update (partial). Creator only (403 view_not_owned). |
DELETE | /views/{id} | Delete. Creator only. 204 on success. |
POST /api/v1/projects/demo/views
{
"name": "Unpublished blog posts",
"description": "Drafts I still need to ship",
"filters": { "contentType": "articlePage", "status": "draft" },
"isShared": true
}
Create/update/delete are recorded in the audit log (view.created, view.updated, view.deleted).
Lineage: saved views shipped in the V2 wave.