Skip to content

Analytics label net: ObjectChart is a THIRD copy of the derivation glue — it can consume the core helpers #4389 extracted #4405

Description

@yinlianghui

Observation-class finding, measured while doing objectui#4389 (PR #4404). Nothing a user hits today — all three copies behave identically, and this one is fully pinned on its own surface. Filing so the last copy is retired deliberately rather than found later as drift, exactly as #4389 was.

What was found

objectui#4389 named two copies of the analytics label-net glue (plugin-dashboard's DatasetWidget and plugin-report's useDatasetDimensionLabels) and PR #4404 retired both. There is a third, which #4389 did not name and PR #4404 deliberately left alone as out of scope: packages/plugin-charts/src/ObjectChart.tsx.

It is the same shape, in the same order:

  • packages/plugin-charts/src/ObjectChart.tsx:259const apiFetch = context?.apiFetch;
  • :300 — locale-free optionMeta state, with a header saying why it is locale-free (objectui#4030), nearly word-for-word the one the other two carried
  • :355const doFetch = apiFetch ?? fetch;
  • :411apiFetch in the effect's deps (objectui#4121)
  • :422-448 — a translatorFor(path) closure and a buildDimensionLabelMap loop

translatorFor at :427 is logically identical to the two that PR #4404 deleted, down to the comment ("Bound to the object that OWNS the terminal field — crm_account for crm_account.industry, not the dataset's base object").

Why this is smaller than #4389 was

PR #4404 landed the React-free half in @object-ui/core:

  • dimensionOptionTranslator(meta, fieldOptionLabel) — exactly translatorFor
  • deriveDimensionLabelMaps(metaByPath, relabel, fieldOptionLabel) — exactly the loop
  • loadDimensionFieldMeta(loadObjectSchema, object, fieldPaths) — the read composition

So the derivation half is a pure-function swap with no React-layer change and no new dependency: plugin-charts already depends on @object-ui/core.

The hook half does not transfer as-is, and that is the part needing a decision rather than a patch. ObjectChart differs from the two surfaces #4389 covered:

  • it serves TWO paths, aggregate and dataset, where the other two serve only dataset;
  • its colour dimension is a single colorPath (aggregate groupBy or first dimension), not the dataset-shaped relabel array;
  • it carries fieldByDim as a dimension name to field path MAP, where the shared hook carries an ordered array;
  • its effect is keyed on schema.objectName / datasetKey / aggregateKey / schema.xAxisKey, a different signature from the dataset one.

@object-ui/react's useDatasetDimensionMeta could likely serve the dataset path with the aggregate path staying local, but that is a judgement about ObjectChart's shape, not a mechanical lift — hence a finding for triage rather than a queued card.

Suggested direction (for triage, not a decision)

  1. Cheap and safe now: swap translatorFor and the label-map loop for dimensionOptionTranslator / deriveDimensionLabelMaps. Pure functions, no behaviour change, no new dependency edge. This alone removes the third copy of the part that was actually duplicated three times.
  2. Needs a shape decision: whether the dataset path's read also moves onto useDatasetDimensionMeta, or whether ObjectChart's two-path effect stays local.

The two bug-fix properties #4389 singly-expressed (apiFetch in the deps, objectui#4121; locale NOT in the deps, objectui#4030 / PR #4324) are currently stated correctly in this file too — so this is drift risk, not drift. Step 1 does not change that; step 2 would inherit them from the shared hook instead of restating them.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions