Skip to content

view/layout-without-binding covers only 3 of the 6 view types that have a binding block — timeline, tree and map fall through the same trapdoor #14106

Description

@os-warren

Measured on @objectstack/cli 17.2.0 / @objectstack/spec 17.2.0, from a real app (objectstack-ai/duly), while adding kanban / gantt / timeline lenses over one object.

The rule

checkViewCompleteness (spec/dist/kernelfunctional-completeness.ts) drives the view/layout-without-binding warning off this table:

var VIEW_BINDING_BLOCKS = {
  kanban: "kanban",
  calendar: "calendar",
  gantt: "gantt"
};

ListViewSchema.type has nine members, and six of them carry a type-specific binding block: kanban, calendar, gantt, timeline, map, tree. The table names three.

Why the other three are the same defect, not a lesser one

The rule's own message is "the renderer falls back to literal default field names … the view renders empty while authoring reports success." That is literally what the uncovered three do. From the console's ListView adapter (plugins-views-*.js, 17.2.0), the fallbacks are hard-coded strings:

view type renderer fallback when the block is absent gate
calendar startDateField || 'start_date', endDateField || 'end_date' ✅ warns
gantt startDateField || 'start_date', endDateField || 'end_date', progressField || 'progress', dependenciesField || 'dependencies' ✅ warns
kanban groupBy = groupByField || groupField || <inferred> ✅ warns
timeline startDateField || 'created_at', titleField || 'name' ❌ silent
map locationField || 'location' ❌ silent
tree labelField || titleField || 'name' ❌ silent

timeline is the sharpest of the three: 'created_at' is a plausible-looking name that many objects do not declare, and the timeline renderer drops every row whose start date does not parse — so the view is blank, not merely mis-titled.

Reproduction (measured, both directions)

In a stack with a duly_task object that declares neither created_at nor start_date:

  1. listViews.recent = { type: 'timeline', … } with its timeline: { startDateField: 'last_update_at', titleField: 'subject', … } block → os validate --jsonwarnings: [].
  2. Delete the timeline block (confirmed on disk: startDateField occurrences 1 → 0, marker present) → os validate --jsonwarnings: [] again, valid: true. No diagnostic at all.
  3. Same ablation against the sibling gantt view → view/layout-without-binding warning fires as designed.

So the gate is working; the table it reads is short.

Suggested fix

Extend VIEW_BINDING_BLOCKS to the full set and give each the same shaped fix hint the existing three carry:

var VIEW_BINDING_BLOCKS = {
  kanban: "kanban", calendar: "calendar", gantt: "gantt",
  timeline: "timeline", map: "map", tree: "tree",
};

Hints, matching the required keys in each block's schema:

  • timeline: { startDateField: '<date_field>', titleField: '<text_field>' } (both required by TimelineConfigSchema)
  • map: { latitudeField: '<number_field>', longitudeField: '<number_field>' } or { locationField: '<field>' }
  • tree: { labelField: '<text_field>', parentField: '<self_lookup_field>' }

tree is the one worth a second look: TreeConfigSchema's keys are all optional, so "has a tree block" is a weaker assertion there than for the others — see the sibling issue on tree having no value-grouped mode.

Related

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions