Skip to content

fix(ui): normalize single embedded dataset#257

Merged
fahimfaisaal merged 2 commits into
mainfrom
fix/single-dataset-payload-normalize
Jul 21, 2026
Merged

fix(ui): normalize single embedded dataset#257
fahimfaisaal merged 2 commits into
mainfrom
fix/single-dataset-payload-normalize

Conversation

@fahimfaisaal

@fahimfaisaal fahimfaisaal commented Jul 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Fix crash when embedded HTML has a single dataset object (window.VIZB_DATA = {...}) instead of an array: load paths now always go through classifyPayload, so .map is never called on a plain object.
  • Rename classifyRemotePayloadclassifyPayload / RemotePayloadDataPayload because classification is shared by remote, embedded, and dev fixtures.
  • Remove the unused useDataPoint.normalize.test.ts mirror (real coverage lives in remoteData.test.ts).
  • Rename UI type and identifiers from DataSet to Dataset to match Go and standard English (DatasetHeader, filterDatasetSettings, activeDataset, etc.).

Test plan

  • pnpm exec vue-tsc -b (UI typecheck)
  • pnpm exec vitest run (UI unit tests)
  • Open a single-dataset HTML chart and confirm the dashboard loads without .map is not a function
  • Open a multi-dataset HTML chart and confirm tabs still work
  • Optional: --data-url catalog + detail fetch still works

Summary by CodeRabbit

  • New Features
    • Added support for loading dashboards from either a single dataset or multiple datasets.
    • Improved handling of dataset details loaded on demand, including safer retries and selection updates.
  • Bug Fixes
    • Corrected chart axes, 3D availability, chart settings, and swap controls to consistently use the active dataset.
    • Improved URL synchronization for dataset selection and chart configuration.
  • Refactor
    • Standardized dataset terminology across the dashboard, selectors, settings, and data-loading workflows.

Embedded HTML injects one DataSet object, but getDataSets assumed an
array and crashed with ".map is not a function". Route all load paths
through classifyPayload (renamed from classifyRemotePayload) and drop
the unused normalizeDataSets mirror test.
Align UI naming with Go's Dataset type and standard English casing.
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR renames dataset types and APIs to Dataset, updates remote payload classification and detail loading, and rewires dashboard, settings, chart, and URL synchronization code to consume the renamed state and selection contracts.

Changes

Dataset contract migration

Layer / File(s) Summary
Dataset and remote data contracts
ui/src/types/index.ts, ui/src/lib/remoteData.ts, ui/src/lib/filterDatasetSettings.ts, ui/src/global.d.ts, ui/src/lib/*.test.ts
Renames DataSet APIs to Dataset, introduces classifyPayload and DataPayload, supports single or array global payloads, and validates fetched detail identifiers.
Dataset loading and selection
ui/src/composables/useDataPoint.ts
Loads and normalizes datasets, caches detail requests, replaces selected entries, guards stale selections, and exposes renamed dataset and retry APIs.
Dashboard and settings integration
ui/src/components/*, ui/src/components/settings/*, ui/src/composables/useActiveChartShape.ts, ui/src/composables/useSettingsStore.ts, ui/src/views/Dashboard.vue
Updates component props, events, chart inputs, settings calculations, swap handling, and dashboard rendering to use Dataset naming.
URL synchronization and initialization
ui/src/composables/useUrlRouter.ts, ui/src/composables/useDashboardInit.ts, ui/src/composables/*test.ts
Updates URL selection, deferred detail retries, arrangement serialization, initialization watchers, and test fixtures for the renamed dataset state.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

  • goptics/vizb#251: Updates the same dataset and active-dataset contracts with deep-link selection behavior.

Suggested labels: ui

Suggested reviewers: hfl0506

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing UI handling of a single embedded dataset.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/single-dataset-payload-normalize

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@fahimfaisaal fahimfaisaal added the ui ui-related tasks label Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
ui/src/composables/useDataPoint.ts (1)

108-114: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the ref mutation inside the datasetsProcessed computed getter.

Mutating datasets.value from within the getter that reads it is a Vue anti-pattern (computed getters are expected to be side-effect free). It's also now vestigial: classifyPayload (line 22/28/33) already normalizes every load path into { mode: 'full', datasets: [...] } / { mode: 'catalog', entries: [...] }, and datasets is typed shallowRef<Dataset[]>, so every writer (payload.entries.map(...) / payload.datasets.map(...)) always assigns an array. The !Array.isArray branch is unreachable given the current contract, yet it still triggers an extra reactive write on every evaluation path that would hit it.

♻️ Proposed fix: make the getter pure
 const datasetsProcessed = computed<Dataset[]>(() => {
-  if (!Array.isArray(datasets.value)) {
-    datasets.value = [datasets.value]
-  }
-
-  return datasets.value
+  return Array.isArray(datasets.value) ? datasets.value : [datasets.value]
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/composables/useDataPoint.ts` around lines 108 - 114, Remove the
!Array.isArray branch and its assignment from the datasetsProcessed computed
getter. Return datasets.value directly, keeping the getter pure and relying on
the existing array normalization performed by classifyPayload and the typed
writers.
ui/src/views/Dashboard.vue (1)

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial

Run task build:ui before building the CLI or running Go tests.

As per coding guidelines, please ensure you run task build:ui after this ui/ change before running Go tests or CLI builds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/src/views/Dashboard.vue` at line 1, Run task build:ui after the
Dashboard.vue change and before building the CLI or running Go tests; no source
changes are required.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@ui/src/composables/useDataPoint.ts`:
- Around line 108-114: Remove the !Array.isArray branch and its assignment from
the datasetsProcessed computed getter. Return datasets.value directly, keeping
the getter pure and relying on the existing array normalization performed by
classifyPayload and the typed writers.

In `@ui/src/views/Dashboard.vue`:
- Line 1: Run task build:ui after the Dashboard.vue change and before building
the CLI or running Go tests; no source changes are required.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e026274e-1b4e-483d-8c54-0e30bce368c4

📥 Commits

Reviewing files that changed from the base of the PR and between 354caee and fd5b298.

📒 Files selected for processing (21)
  • ui/src/components/ChartCard.vue
  • ui/src/components/DatasetHeader.vue
  • ui/src/components/Selector.vue
  • ui/src/components/SettingsPanel.vue
  • ui/src/components/settings/SwapControl.vue
  • ui/src/composables/useActiveChartShape.test.ts
  • ui/src/composables/useActiveChartShape.ts
  • ui/src/composables/useDashboardInit.ts
  • ui/src/composables/useDataPoint.normalize.test.ts
  • ui/src/composables/useDataPoint.ts
  • ui/src/composables/useSettingsStore.test.ts
  • ui/src/composables/useSettingsStore.ts
  • ui/src/composables/useUrlRouter.test.ts
  • ui/src/composables/useUrlRouter.ts
  • ui/src/global.d.ts
  • ui/src/lib/filterDatasetSettings.test.ts
  • ui/src/lib/filterDatasetSettings.ts
  • ui/src/lib/remoteData.test.ts
  • ui/src/lib/remoteData.ts
  • ui/src/types/index.ts
  • ui/src/views/Dashboard.vue
💤 Files with no reviewable changes (1)
  • ui/src/composables/useDataPoint.normalize.test.ts

@fahimfaisaal fahimfaisaal changed the title fix(ui): normalize single embedded dataset and rename DataSet to Dataset fix(ui): normalize single embedded dataset Jul 21, 2026
@fahimfaisaal
fahimfaisaal merged commit b17af15 into main Jul 21, 2026
5 checks passed
@fahimfaisaal
fahimfaisaal deleted the fix/single-dataset-payload-normalize branch July 21, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ui ui-related tasks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant