Repository navigation
fix(ui): migrate dashboard record-listing tables to ListViews (ADR-0017) - #27
Merged
Merged
Conversation
The v9 single-form cutover (ADR-0021) left 19 `type:'table'` dashboard widgets across 11 dashboards bound to aggregate `*_metrics` datasets with only a count measure. Aggregate datasets return one grouped row, so these widgets — which were meant to list individual records — collapsed to a single count. Per the v9 release notes, a flat record listing is not an analytics dataset; it belongs in an object-bound ListView (ADR-0017). This change: - Removes all 19 broken record-listing table widgets from the dashboards. The matching `metric` widgets stay, so each dashboard keeps its at-a-glance counts; per-record detail now lives in object ListViews reachable from each app's navigation. - Reuses existing ListView tabs for 16 widgets that already had an equivalent surfaced (e.g. expense awaiting_approval / awaiting_reimbursement). - Adds ListViews + tabs for the genuine gaps: open_obligations (contracts), top_publications (content), escalated_tickets + my_queue tab (helpdesk), out_of_office_today (hr). Each removed widget has a comment pointing to the tab its records now live in. Verified: all 9 app packages build (schema validation) + marketplace compose clean; workspace typecheck passes; the live runtime serves the expense dashboard with no table widget and the expense_report view with the awaiting_approval / awaiting_reimbursement ListViews. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 11, 2026
os-zhuang
added a commit
that referenced
this pull request
Jun 11, 2026
…017) (#28) PR #27 migrated the dashboard record-listing tables to object-bound ListViews, leaving two filters as approximations. This closes them out. content: add `my_pieces` listView + "My Pieces" tab restoring the former `my_pieces_table` widget — status IN (backlog, drafting, in_review, approved, scheduled). The original intent was (assignee == me OR assignee IS NULL); the OR branch is unrepresentable because ListView `filter` is a flat AND-only array of {field,operator,value} rules (ViewFilterRule is additionalProperties:false, no and/or group, no disjunction operator in @objectstack/spec 9.0.0). Faithfully degraded to assignee == me — matching the existing `my_drafts` convention — with the limitation documented inline. hr: add `my_pending_approvals` listView + "Awaiting My Approval" tab restoring `pending_time_off_table` — status == 'submitted' AND approver == current user. Pure AND, so reproduced exactly; distinct from the existing "Pending" tab which shows all submitted requests. Verified: pnpm -r build (excl. @objectlab/all), @objectlab/all clean+compile, and pnpm -r typecheck all pass. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 11, 2026
os-zhuang
added a commit
that referenced
this pull request
Jun 11, 2026
The ADR-0021 single-form cutover renamed chart data keys to the dataset measure names (sum_amount, ticket_count, ...), but the chart widgets' chartConfig axis fields were left pointing at the old raw field names — so charts rendered axis labels with no data series. 17 chart widgets across all 11 dashboards were affected, in two forms: - 10 widgets had a chartConfig whose yAxis[].field referenced the old field name (amount, total_amount, signups) or a placeholder (value) instead of the dataset measure name. Repointed yAxis[].field to the measure declared in values[]. - 7 widgets (helpdesk tickets_by_*, content channel charts, hr headcount_by_dept) had no chartConfig at all. Added one mapping xAxis.field=dimension, yAxis.field=measure. Metric (KPI) widgets were unaffected (single scalar) and ListView record tables were already migrated in #27; only grouped charts were broken. Verified: static binding audit 0/17 broken (was 17); all apps build + marketplace compile clean; workspace typecheck passes; browser sweep of all 11 dashboards confirms charts now render real bars/lines/pies wherever the seed has data in-window (helpdesk, hr, expense, contracts, content). Remaining "No rows" panels are genuine empty-data states (their KPI metrics on the same dataset are also empty), not binding errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
os-zhuang
added a commit
that referenced
this pull request
Jun 11, 2026
The ADR-0021 single-form cutover renamed chart data keys to the dataset measure names (sum_amount, ticket_count, ...), but the chart widgets' chartConfig axis fields were left pointing at the old raw field names — so charts rendered axis labels with no data series. 17 chart widgets across all 11 dashboards were affected, in two forms: - 10 widgets had a chartConfig whose yAxis[].field referenced the old field name (amount, total_amount, signups) or a placeholder (value) instead of the dataset measure name. Repointed yAxis[].field to the measure declared in values[]. - 7 widgets (helpdesk tickets_by_*, content channel charts, hr headcount_by_dept) had no chartConfig at all. Added one mapping xAxis.field=dimension, yAxis.field=measure. Metric (KPI) widgets were unaffected (single scalar) and ListView record tables were already migrated in #27; only grouped charts were broken. Verified: static binding audit 0/17 broken (was 17); all apps build + marketplace compile clean; workspace typecheck passes; browser sweep of all 11 dashboards confirms charts now render real bars/lines/pies wherever the seed has data in-window (helpdesk, hr, expense, contracts, content). Remaining "No rows" panels are genuine empty-data states (their KPI metrics on the same dataset are also empty), not binding errors. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The v9 single-form cutover (ADR-0021) left 19
type:'table'dashboard widgets across 11 dashboards bound to aggregate*_metricsdatasets with only acountmeasure. Aggregate datasets return a single grouped row, so these widgets — which were meant to list individual records — collapsed to one count.Per the v9 release notes, "a flat record listing is not an analytics dataset — model it as an object-bound ListView (ADR-0017)."
DashboardWidgetis analytics-only (requiresdataset+values, no list type), so record listings cannot live on a dashboard; they belong in object ListViews surfaced through app navigation.Changes
metricwidgets stay (at-a-glance counts); per-record detail now lives in object ListViews reachable from each app's nav. Each removal has a comment pointing to the tab its records now live in.open_obligations(contracts)top_publications(content)escalated_tickets+my_queuetab (helpdesk)out_of_office_today(hr)Verification
tsctypecheck: 0 errorstablewidget;expense_reportview serves theawaiting_approval/awaiting_reimbursementListViewsNotes / approximations
content my_pieces_table("mine or unassigned") → mapped to existing "My Drafts" tab; the$orhalf isn't reproduced (ListView filter is an AND-array).hr pending_time_off_table(submitted and approver=me) → mapped to existing "Pending" tab; approver-scoping dropped.🤖 Generated with Claude Code