Replies: 1 comment
|
Looks good. Approved |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Problem
The admin content list hardcodes its columns: Title / Status / (Locale when i18n is on) / Date (
packages/admin/src/components/ContentList.tsx). For collections whose identity lives in a custom field, the list is a wall of near-identical rows and editors open every entry to see the one field they're scanning for.Three concrete cases from a production migration (a film-festival site moving off WordPress):
tier(select),festival_track(select) andsort_order(integer) across ~80 partners. The list shows none of them.contact_submissionscollection where triage lives in asubmission_statusselect. We currently prefix the status into the title via abeforeSavehook ("[NUEVO] name · consulta") purely so it's visible in the list — a workaround that burns the title field for what should be a column.start_datetime+ avenuereference are the two things an editor scans for; neither is visible.We've built an interim read-only plugin admin page that re-lists one collection with its fields as columns, but that's a parallel surface that duplicates the stock list and has to be retired later. The gap is general and feels like it belongs in core.
Proposal
Let a collection declare extra list columns from custom fields.
Option A — collection-level config (my preference):
_emdash_collections(migration +SchemaRegistry+ seed apply), or a scalar column if you'd rather avoid JSON there._buildManifestalready emits per-fieldkind/label/ selectoptions; the collection entry gainslistColumns: string[]. Unknown/removed field slugs are dropped at manifest build (renames can't strand the admin).ContentListinserts one<td>per declared column between Title and Status. Rows already carry fulldata(getItemTitlereadsitem.data.title), so no API/server change is needed for rendering.Option B — field-level flag (
"showInList": trueon the field def): less plumbing conceptually, but column order becomes implicit (field order) and the collection-level intent ("this list shows these three things") gets scattered across field defs. Mentioning it in case you prefer the schema to stay field-centric.Rendering rules (v1)
select/multiSelect: resolve value → option label from the manifest options; unknown values render raw (visible, not blank).string/number/integer: as-is;boolean: ✓ / —;datetime: the same relative/short format the Date column uses.reference/repeater/portableText/image/file: excluded in v1 (references need a join or N+1 hydration — out of scope until there's a story for it; happy to note it as follow-up).Deliberate non-goals (v1)
orderBywhitelist staystitle|status|locale|updatedAt. Custom-field sort without indexes full-scans (exactly the issue Collection tables index only system columns — custom editorial fields used in where/orderBy get no index, so live list queries full-scan on D1 #1533 raises for D1); if/whenindexedfields land (discussion Add `indexed` option for custom field B-tree indexes #1649), the whitelist could grow per-column as a follow-up.What I'd ship in the PR
SchemaRegistryread/write + seed-schema support (+emdash typespassthrough if applicable)ContentListrendering (Lingui-wrapped headers from field labels), matching the existing table/i18n patternsemdashminor +@emdash-cms/adminminor)Happy to adjust the shape (A vs B, naming, cap, which kinds render in v1) to whatever fits the project's direction — nothing here is precious. If approved I'll open the PR with the AI-disclosure box checked (built with Claude Code; reviewed and owned by me).
Prior related threads I checked: #1533 (custom-field index full-scans), #1649 (
indexedfields), #1523 (bulk actions in the content list — adjacent but orthogonal). I didn't find an existing proposal for list columns.All reactions