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.
statdeclares eight properties:description,metaIcon,metaText,metaTooltip,title,titleIcon,unit, andvariant. These are theGlSingleStatprops a GLQL block can meaningfully set.variantis an Enum ofneutral,info,success,warning,danger, andtier, taken frombadgeVariantOptionsin@gitlab/ui.columnChart,barChart, andareaChartdeclarestacked. They already read it, so only the declaration is new.lineChartdoes not read it, so it declares nothing.kindreuses thevalue_kindsvocabulary 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_FREEZEnow also freezes each property hash and itsvaluesarray, 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.rbgains three immutability examples, plus two structural ones: every declared property has a name, a description, and akindthe document itself defines, andvaluesappears on enums and only on enums. Both structural examples were checked against deliberately corrupted data, a badkindand a strayvalues, to confirm they fail for the right reason.doc/api/glql.mdgains adisplay_configrow in thedisplay_types[]table, a newdisplay_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.rbandspec/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
- Issue: https://gitlab.com/gitlab-org/gitlab/-/work_items/622285
- Plan comment: https://gitlab.com/gitlab-org/gitlab/-/work_items/613467#note_3711541126
- Spike MR, closed unmerged: !250839 (closed)
- Approach decision: glql#182 (closed)
- Epic: https://gitlab.com/groups/gitlab-org/-/work_items/23225
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
- I have evaluated the MR acceptance checklist for this MR.