Draft: Add display_config to GLQL schema display types

What does this MR do and why?

GET /api/v4/glql/schema publishes a JSON document describing the GLQL query language. Its display_types array is maintained by hand in lib/analytics/glql/schema.rb, and each entry carried only name, description, and, for aggregating types, selections.

A GLQL block can pass a displayConfig: map of options through to the presenter that renders it. Nothing in the schema said which options exist, for any display type. Not even stacked, which the chart presenters have read since before the schema endpoint existed. A consumer of the schema, in particular the Data Analyst agent that writes GLQL blocks from it, had no way to know an option was available.

This MR adds an optional display_config array to a display type entry. Each element has name (the camelCase key set under displayConfig:), kind, description, and, for enums, a values list.

  • stat declares eight properties: description, metaIcon, metaText, metaTooltip, title, titleIcon, unit, and variant. These are the GlSingleStat props a GLQL block can meaningfully set. variant is an Enum of neutral, info, success, warning, danger, and tier, taken from badgeVariantOptions in @gitlab/ui.
  • columnChart, barChart, and areaChart declare stacked. They already read it, so only the declaration is new. lineChart does not read it, so it declares nothing.
  • kind reuses the value_kinds vocabulary the rest of the document is written in (String, Boolean, Enum), so a consumer reads one set of type names.
  • The two property lists are private constants rather than inline hashes, and the three chart types share one constant. The serialized document still repeats the entry under each type, so a consumer never resolves a reference.
  • DEEP_FREEZE now also freezes each property hash and its values array, because the document is memoized and handed out by reference.

Deliberately excluded from stat, each for a reason: value, because the presenter derives it from the query result; useDelimiters, shouldAnimate, and animationDecimalPlaces, because they need a raw number but the presenter passes an already formatted string; titleIconClass, because it would let a GLQL block inject arbitrary CSS classes; and the default slot, because YAML has no channel for slot content.

Scope, and what is deliberately not here

This is step 1 of the six-step plan in the issue, the schema half only. stat.vue does not read any of these keys yet. The presenter work and the user-facing docs follow in the same issue. Setting one of the new stat options today is accepted and ignored, exactly as an unknown key is today.

doc/user/glql/display_types.md and the displayConfig row in doc/user/glql/_index.md are therefore untouched on purpose. Documenting the options as user-facing before the presenter reads them would describe something that silently does nothing.

One judgment call worth a reviewer's attention

Declaring stacked on the three chart types goes slightly beyond the issue, which scopes step 1 to the stat options. The reasoning: a display_config key that appears only on stat tells a consumer, by omission, that the charts accept no options, which is false. It is three lines of data and no behaviour change, and it is easy to drop if you disagree.

Tests and docs

  • spec/lib/analytics/glql/schema_spec.rb gains three immutability examples, plus two structural ones: every declared property has a name, a description, and a kind the document itself defines, and values appears on enums and only on enums. Both structural examples were checked against deliberately corrupted data, a bad kind and a stray values, to confirm they fail for the right reason.
  • doc/api/glql.md gains a display_config row in the display_types[] table, a new display_types[].display_config[] table, and the attribute in the truncated example response. The existing documentation guard spec reads its table paths out of the markdown, so it covers the new table without being changed.

Verification

  • spec/lib/analytics/glql/schema_spec.rb and spec/lib/analytics/glql/documentation_spec.rb: 23 examples, 0 failures.
  • spec/requests/api/glql_spec.rb -e 'GET /glql/schema': 7 examples, 0 failures.
  • RuboCop, Vale, and markdownlint clean.

How to verify by hand

Request GET /api/v4/glql/schema and read display_types. The stat entry carries a display_config array of eight properties. columnChart, barChart, and areaChart each carry one, stacked. lineChart, list, orderedList, and table carry none. Nothing in the rendered output of a GLQL block changes.

References

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Merge request reports

Loading
Loading