Port Policy Store editor config field renderer
What does this MR do and why?
The Policy Store editor's Build policy step renders a configuration form for whichever trigger, rule, or action the user selects. Each catalog item declares its own fields array, so the form is driven by that data rather than hand-written per item.
This transfers the renderer and its dependencies out of the prototype in ee/app/assets/javascripts/security_policies/components/create as-is.
| File | Source | Diff from source |
|---|---|---|
editor/generic_config.vue |
create/generic_config.vue |
i18n namespace; field-type constants + predicate methods |
editor/multi_badge_selector.vue |
create/multi_badge_selector.vue |
byte-identical |
editor/helpers.js |
constants/helpers.js |
byte-identical |
editor/rego_templates_modal.vue |
create/rego_templates_modal.vue |
i18n namespace; one import path; reads REGO_TEMPLATES directly |
editor/rego_templates.js |
constants/rego_templates.js |
i18n namespace |
editor/constants.js |
— | field-type constants appended to the existing file |
generic_config_spec.js |
the matching prototype spec | import paths; drives the component through its public interface |
| 2 other specs | the matching prototype specs | import paths |
generic_config.vue therefore arrives with the prototype's full field-type set — toggle, checkbox, sla_matrix, code, multi_badge, select, textarea, segment, and a text fallback. helpers.js (idAsOption) comes with it because the prototype's options are { id, label } objects.
Porting generic_config.vue as-is also brings rego_templates_modal.vue and rego_templates.js, because its code field imports the modal. That is MR 7 content arriving early; MR 7 replaces the 3 ported templates with the catalog's 24.
Four deviations from a straight port
-
Every field declaring a
defaultis seeded, not just the firstcodefield. The prototype seeded code fields only, so atoggleorcheckboxwithdefault: truerendered as checked while its key stayed absent from the saved payload — the user had to click it twice to persist the value they were already being shown.rule_types.jsin the source declaresdenyUnlisted: default trueandsameVersionRef: default true, both consumed by MRs 4–6, so this would have silently dropped values once the catalog lands. Defaults emit as a single update, sinceupdaterebuilds the object from the current value and seeding field by field would drop all but the last. -
Field
typevalues are named constants, and dispatch goes through predicate methods.FIELD_TYPE_TOGGLE,FIELD_TYPE_SLA_MATRIX, and the rest live ineditor/constants.js; the renderer readsv-if="isToggle(field)"rather thanv-if="field.type === 'toggle'". The catalog declares atypeon all 214 of its field definitions, so a bare string misspelled there renders nothing and raises no error.FIELD_TYPESis exported as a collection so a catalog-shape spec can assert every field uses a supported type.Three of these constants get renamed in MR 2, which reconciles the renderer's vocabulary with the catalog's (
multi_badge→multiselect,segment→segmented,toggle/checkbox→boolean). -
The templates modal reads
REGO_TEMPLATESdirectly instead of through$options.$optionsis only needed for values a template renders; this one is used solely in a computed, so the component option was dead weight. -
generic_config_spec.jstests through the public interface. It previously calledupdate,updateMatrix, andsegmentButtonClasson the instance viawrapper.vm. It now emits from the rendered controls and asserts on what the component emits and renders. That also closed a gap: assertingsegmentButtonClass's return value never exercised the click handler, so a broken segment button would have passed. There is now a test for it.
Nothing mounts the renderer yet. The catalog and the Build policy step itself land in later MRs, so this change is not reachable in the UI.
Carried over as-is, worth a reviewer's attention
Two things came across unchanged that are worth deciding on separately, rather than being quietly fixed in a port:
multi_badge_selector.vueis not keyboard-operable.GlBadgerenders a<span>, so@clickon it gives no focus, no role, and no announced selection state. There is no badge-as-toggle precedent in the codebase to copy — the only clickable-badge usage (vue_shared/components/topic_badges.vue) useshref, which makes it a link, and that does not fit a select/deselect toggle. Picking the right control needs design input; 21 of the 214 catalog fields aremultiselect.helptext renders in a tooltip on aGlIcon, which is not focusable, so the text is unreachable by keyboard and screen reader.
Where this sits in the series
This MR is part of the Build policy step breakdown in https://gitlab.com/gitlab-org/gitlab/-/issues/607341#mr-breakdown.
| MR | Scope | Merge depends on | Parallel with | UI change |
|---|---|---|---|---|
| 1 — this MR | Port generic_config.vue + deps as-is |
— | — | No — plumbing only |
| 2 | Field types the catalog needs and the port lacks (8) + vocabulary reconciliation | 1 | 3 | No — plumbing only |
| 3 | Build step shell + 20 triggers | 1 | 2 | Yes — first visible build step |
| 4 | Rules: Advanced + Security, Process, Quality, Code, Deployment (19) | 2, 3 | 5, 6, 8, 9 | Yes |
| 5 | Rules: Compliance, Governance, Supply Chain, Configuration, CI Components (12) | 2, 3 | 4, 6, 8, 9 | Yes |
| 6 | Rules: AI (10) | 2, 3 | 4, 5, 8, 9 | Yes |
| 7 | Custom rule templates: 24 from the catalog, replacing the 3 ported here | 4 | 8, 9, 10 | Yes |
| 8 | Actions: Enforcement, Notification, Tracking (14) | 2, 3 | 4, 5, 6, 9 | Yes |
| 9 | Actions: Automation, AI (8) | 2, 3 | 4, 5, 6, 8 | Yes |
| 10 | a_custom + custom action templates (9) |
7, 9 | — | Yes |
| 11 | Metadata endpoints | 3, !246660 (closed) | 4–10 | Loading/error states only |
| 12 | Step validation | 3, and ≥1 of 4–6, ≥1 of 8–9 | 11 | Yes |
Carries a Changelog: added trailer with EE: true.
References
- Implements MR 1 of https://gitlab.com/gitlab-org/gitlab/-/issues/607341
- Parent epic: https://gitlab.com/groups/gitlab-org/-/work_items/22542
- Source of the ported components: !246660 (closed)
- Catalog data (the
fieldscontract this renders):prototype/src/prototypes/policies-v2/catalog.jsin https://gitlab.com/gitlab-com/gitlab-ux/security-compliance-ux/srm-ux-group/policies-v2
Screenshots or screen recordings
No UI change. Nothing mounts GenericConfig yet — the Build policy step still renders its placeholder. The first visible change in this series is MR 3.
Verified by Jest only; see below.
How to set up and validate locally
There is nothing to click. Validate with the specs:
yarn jest ee/spec/frontend/policy_store68 tests pass across nine suites. The three ported specs cover generic_config, multi_badge_selector, and rego_templates_modal; the rest are the existing editor and list suites, included to confirm the rebase onto the reworked editor shell did not disturb them.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.