Views
Seven visualization types for your data — Sheet, Kanban, Calendar, Gallery, List, Tree, and Gantt
Overview
Every resource in Supasheet can be rendered through seven different view types. You declare the available views in the table comment, and users can switch between them from the resource toolbar.
| View | Best for | Required hints |
|---|---|---|
| Sheet | Default spreadsheet view of all columns | None (always available) |
| Kanban | Items grouped by status / category | group, title, optional description, badge, date, read_only |
| Calendar | Time-based data with a start (and optional end) date | title, start_date, optional end_date, badge, read_only |
| Gallery | Card-style display with cover images | cover, title, optional description, badge |
| List | Compact vertical list with summary fields | title, optional description, field_1, field_2 |
| Tree | Hierarchical, parent–child data | parent, title, optional secondary |
| Gantt | Scheduling with date ranges, grouped rows, and progress | title, start_date, end_date, optional group, progress, badge, read_only |
Configuring Views
Views are declared in the JSON comment on the table. Each entry in views is a view, and primary_view is the id of the view to load by default when a user opens the resource.
COMMENT ON TABLE desk.projects IS $$
{
"icon": "FolderKanban",
"display": "block",
"primary_view": "kanban",
"views": [
{"id": "kanban", "name": "Projects By Status", "type": "kanban",
"group": "status", "title": "title", "description": "description",
"date": "start_date", "badge": "priority"},
{"id": "calendar", "name": "Project Timeline", "type": "calendar",
"title": "title", "start_date": "start_date", "end_date": "end_date",
"badge": "status"},
{"id": "gallery", "name": "Project Gallery", "type": "gallery",
"cover": "cover", "title": "title", "description": "description",
"badge": "status"},
{"id": "gantt", "name": "Project Roadmap", "type": "gantt",
"group": "status", "title": "title", "start_date": "start_date",
"end_date": "end_date", "progress": "progress", "badge": "priority"}
]
}
$$;The Sheet view is always available. You only need to declare it in views if you want to label it differently or change its position relative to the other views.
View Types
Sheet
The default tabular view. Renders every column, supports sorting, filtering, pagination, column reordering, and inline editing via the side sheet.
COMMENT ON TABLE invoices IS '{
"icon": "FileText",
"primary_view": "sheet",
"views": [
{"id": "sheet", "name": "All Invoices", "type": "sheet"}
]
}';Kanban
Cards grouped into columns by a single enum / text field.
| Field | Required | Purpose |
|---|---|---|
type | yes | Must be "kanban" |
group | yes | Column to group cards by (typically an enum) |
title | yes | Column shown as the card title |
description | no | Secondary line on each card |
badge | no | Column rendered as a styled badge (great for priority, status) |
date | no | Date column shown in the card footer |
read_only | no | When true, disables drag-and-drop between columns — the board becomes view-only |
COMMENT ON TABLE desk.tasks IS '{
"icon": "ListTodo",
"primary_view": "status",
"views": [
{"id": "status", "name": "Tasks By Status", "type": "kanban",
"group": "status", "title": "title", "description": "description",
"date": "created_at", "badge": "priority"},
{"id": "priority", "name": "Tasks By Priority", "type": "kanban",
"group": "priority", "title": "title", "description": "description",
"date": "created_at", "badge": "status"},
{"id": "archived", "name": "Archived (read-only)", "type": "kanban",
"group": "status", "title": "title", "description": "description",
"read_only": true}
]
}';Calendar
Renders records as events on a calendar. Supports day, week, and month layouts.
| Field | Required | Purpose |
|---|---|---|
type | yes | Must be "calendar" |
title | yes | Column shown as the event title |
start_date | yes | Event start (date / timestamptz column) |
end_date | no | Event end — if omitted the event is treated as a single-day item |
badge | no | Column rendered as a styled badge on the event |
read_only | no | When true, disables drag-to-move, resize, and click-to-create — the calendar becomes view-only |
COMMENT ON TABLE desk.projects IS '{
"icon": "FolderKanban",
"primary_view": "calendar",
"views": [
{"id": "calendar", "name": "Project Timeline", "type": "calendar",
"title": "title", "start_date": "start_date", "end_date": "end_date",
"badge": "status"},
{"id": "created", "name": "Created Date (read-only)", "type": "calendar",
"title": "title", "start_date": "created_at", "badge": "status",
"read_only": true}
]
}';Gallery
Card grid with cover images, ideal for product catalogues and media libraries.
| Field | Required | Purpose |
|---|---|---|
type | yes | Must be "gallery" |
cover | yes | FILE / AVATAR column to use as the card image |
title | yes | Column shown as the card title |
description | no | Secondary text under the title |
badge | no | Status / category badge |
COMMENT ON TABLE store.products IS '{
"icon": "Package",
"primary_view": "gallery",
"views": [
{"id": "gallery", "name": "Product Gallery", "type": "gallery",
"cover": "image", "title": "name", "description": "description",
"badge": "status"}
]
}';List
A compact vertical layout — useful for directories and reference lists where you want to display a small set of fields per row.
| Field | Required | Purpose |
|---|---|---|
type | yes | Must be "list" |
title | yes | Primary line |
description | no | Secondary line |
field_1 | no | Extra field rendered on the right of each row |
field_2 | no | Extra field rendered on the right of each row |
COMMENT ON TABLE blog.authors IS '{
"icon": "UserPen",
"primary_view": "list",
"views": [
{"id": "list", "name": "Authors List", "type": "list",
"title": "display_name", "description": "user.email",
"field_1": "language", "field_2": "country"}
]
}';Tree
Renders a hierarchy by following a self-referencing foreign key (or any column that stores the parent's primary key).
| Field | Required | Purpose |
|---|---|---|
type | yes | Must be "tree" |
parent | yes | Column that references the parent record |
title | yes | Column displayed as the node label |
secondary | no | Subtle text rendered next to the title |
COMMENT ON TABLE hr.departments IS '{
"icon": "Network",
"primary_view": "tree",
"views": [
{"id": "tree", "name": "Org Tree", "type": "tree",
"parent": "parent_id", "title": "name", "secondary": "code"},
{"id": "gallery", "name": "Department Gallery", "type": "gallery",
"cover": "cover", "title": "name", "description": "description",
"badge": "code"}
]
}';Tree views work best with explicit ordering — add a sort clause in the table's query metadata so siblings render in a deterministic order.
Gantt
Renders records as schedulable bars on a day/week/month/quarter/year timeline, optionally grouped into rows by an enum / text field. Bars support drag-to-reschedule, resize, and a progress fill.
| Field | Required | Purpose |
|---|---|---|
type | yes | Must be "gantt" |
title | yes | Column shown as the bar's label |
start_date | yes | Bar start (date / timestamptz column) |
end_date | yes | Bar end (date / timestamptz column) |
group | no | Column to group rows by (typically an enum) — omit for a flat list of rows |
progress | no | Numeric column (0–100) rendered as a fill inside the bar |
badge | no | Column that drives the bar's colour |
read_only | no | When true, disables drag-to-reschedule and resize — the gantt becomes view-only |
COMMENT ON TABLE desk.projects IS '{
"icon": "FolderKanban",
"primary_view": "gantt",
"views": [
{"id": "gantt", "name": "Project Roadmap", "type": "gantt",
"group": "status", "title": "title", "start_date": "start_date",
"end_date": "end_date", "progress": "progress", "badge": "priority"}
]
}';Rows without both a start_date and end_date value are skipped — every record needs a real date range to appear on the timeline. Use Calendar instead if your data only has a single date (or an optional end date).
Choosing the Default View
primary_view matches the id of one of the entries in views. It controls which view opens when a user clicks the resource in the sidebar.
{
"primary_view": "kanban",
"views": [
{"id": "kanban", "type": "kanban", ...},
{"id": "sheet", "type": "sheet"}
]
}If primary_view is omitted, the resource opens in the standard sheet view.
Inline Editing (Side Sheets)
Every view supports an inline editor that slides in from the side. When a user clicks a card (Kanban, Gallery, List, Calendar, Gantt), opens a row in the sheet, or expands a node in the tree, the editor opens in-place — you don't need to navigate to a separate detail page.
Inline editing uses the field sections defined in the metadata fields.sections configuration.
Singleton Resources
For tables that should only ever contain one row (settings tables, app config), use singleton: true. The sidebar entry skips the list view and opens the single record directly.
COMMENT ON TABLE blog.blog_settings IS '{
"icon": "BookOpen",
"name": "Blog Settings",
"singleton": true,
"fields": {
"sections": [
{"id": "identity", "title": "Identity",
"fields": ["blog_name", "tagline", "description", "logo"]},
{"id": "content", "title": "Content",
"fields": ["posts_per_page", "footer_text"]}
]
}
}';Inline Child Forms
Junction / detail tables (e.g. order_items, purchase_order_items) are rendered inside their parent record's detail page automatically, based on the foreign-key relationship — no metadata flag required. Rows inside that tab always open in an inline slide-over ("sheet") rather than navigating to a separate page.
inline_form: true is a related but separate opt-in: it makes the table's own standalone views (table/grid/kanban/etc.) use the same sheet overlay too, for the case where the table is ever browsed directly instead of through its parent's tab. Combine it with "display": "none" to also hide the table from the schema's resource list — the two settings are independent, but commonly paired for junction/line-item tables:
COMMENT ON TABLE store.order_items IS '{
"icon": "Receipt",
"inline_form": true,
"display": "none"
}';Best Practices
- Pick the view that matches the data shape. Kanban for status workflows, Calendar for time-based items, Gantt for scheduling with date ranges and progress, Gallery for visual records, Tree for hierarchies, List for compact lookups.
- Use
badgethoughtfully. Pair it with the enum metadata to colour-code statuses and priorities. - Define multiple views per resource. Users can switch between them — kanban-by-status and kanban-by-priority on the same table covers two distinct workflows for free.
- Set a
primary_viewthat reflects the dominant workflow. If you spend most of your time on the kanban, make that the default. - Always add a
sortin thequeryblock. Determinism beats surprises, especially in tree and list views.
Next Steps
- Metadata — Configure sections, filter templates, enum styling
- Query Configuration — Default sorts, filters, and joins
- Data Types — Custom types that power covers and badges