Skip to content

A list view's description is served but never rendered — ObjectView's relay drops it on the way to ListView #7199

Description

@os-warren

Authored, validated, built, served — and silently invisible. ListViewSchema.description on a per-list-view entry (listViews.<name>.description) never reaches the renderer that has code to display it.

Measured

On a real app (ai.objectstack.duly, booted objectstack dev, console at /_console/apps/duly_app/duly_task/view/by_unit), with this authored on the by_unit list view:

by_unit: {
  label: 'By business unit',
  type: 'grid',
  description: 'Open and in-progress work only. Group counts are computed over the loaded page — …',}

The value survives every layer up to the browser:

layer carries description?
dist/objectstack.json (built artifact, /views/0/listViews/by_unit)
GET /api/v1/meta/view/duly_task
rendered DOM ([data-testid="view-description"]) ❌ absent
anywhere in document.documentElement.outerHTML, incl. title attributes ❌ absent

So the server is right and the renderer is willing — packages/plugin-list/src/ListView.tsx already has the branch:

{schema.description && (schema.appearance?.showDescription !== false) && (
  <div  data-testid="view-description">
    {typeof schema.description === 'string' ? schema.description : ''}
  </div>
)}

Where it is lost

packages/app-shell/src/views/ObjectView.tsx, in renderListView. fullSchema is built by spreading the object's listSchema and then relaying selected keys off the active viewDef:

const fullSchema: ListViewSchema = {
    ...listSchema,
    label: viewDef.label ?? listSchema.label,
    rowHeight: viewDef.rowHeight ?? listSchema.rowHeight,
    sort: (viewDef as any).sort ?? listSchema.sort,
    filter: (() => {  })(),

label, sort, filter, hiddenFields, inlineEdit, color, allowExport and others are each relayed. description is not, so schema.description can only ever be the object-level list view's description — a per-view one is unreachable.

Why it is worth a card

This is the "declared and inert" shape: nothing errors, the authoring gates (validate, typecheck, test, build) all pass, the API serves the value, and the only symptom is that the sentence the author wrote for the user is not on the screen. An author has no way to notice short of diffing the DOM.

It bites hardest where it is most wanted: a view description is the natural place to disclose a caveat about the view itself (scope, staleness, "this lens is for browsing, the dashboard is authoritative"). That is precisely the text that silently goes missing.

Two notes for whoever picks this up

  1. A second bug sits one line below the relay. ListView.tsx renders typeof schema.description === 'string' ? schema.description : '' — but ListViewSchema.description is I18nLabelSchema, i.e. string | { en, 'zh-CN' }. An inline locale map renders as empty string, which is the same silent-blank failure by a different route. Worth fixing in the same pass, or the fix only works for plain strings.
  2. appearance.showDescription defaults to true, so no author opt-in is missing here — the value simply never arrives.

Found while scoping a grouped grid in objectstack-ai/duly#86 (the view description was the place the card asked for a residual caveat to be stated for users). Not filing a fix from that side — the app metadata is correct as authored.

Related, same family (authored view metadata not reaching the renderer): #7179 (grid grouping fields absent from the query projection), #7189 (grid grouping and per-group counts computed over the fetched page).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions