Draft: Convert hand-written render bootstraps via normalizeRender and compatH

What does this MR do and why?

Stacked on !247299 (merged) (the boring initVueApp wave) — retarget to master when it merges. This MR carries the 64 bootstraps that the wave deliberately defers: files whose render functions do more than mount a component with static props, so the plain { component, props, events } shape cannot express them.

Why normalizeRender + compatH

Vue 3 render functions are zero-argument and take flat props; Vue 2 render functions receive h and pass a structured data object (props/on/class/scopedSlots). Two existing helpers (~/lib/utils/vue3compat/) bridge that for hand-written renders:

  • compatH(tag, data, children) — identity h on Vue 2; on Vue 3 it flattens the v2 data object into flat props, camelizes on: listeners to onX, and converts scopedSlots to slots. This keeps the render function written once in the familiar v2 shape.
  • normalizeRender(options) — wraps component options so @vue/compat's legacy-render detection stays correct for zero-argument render functions.

What is in here beyond the mechanical wrap

Most files are the wrap alone. The bespoke ones are commented in place:

  • Detached mounts (render_math, render_kroki, render_image_lightbox, alert.js, vue_alerts): the Vue 2 idiom vm.$mount() + insert $el has no Vue 3 equivalent, so a placeholder element is inserted and mounted on; teardown pairs unmountVueApp (which removes the rendered DOM on Vue 3) with the manual removal that covers Vue 2.
  • Root-instance APIs (toggles/index.js): callers read/write the root's reactive data. Subscribing via instance $on is Vue-2-only, so the contract is documented and change handlers pass through the events option.
  • import_entities/import_projects and issues/show carry review-flagged oddities (inheritAttrs, getNoteableData at the bootstrap layer) — kept behavior-preserving here; the suggested refactors are follow-up material.

A second commit adds the version-branched hand-written renders deferred in the wave's second review round: filtered_search/recent_searches_root.js (root-level reactive data, RENDER_FUNCTION opt-out, Vue 2 version branch for the data-object h signature) and render_vue_component_for_legacy_js.js (the shared legacy-JS bridge with the same shape).

Two companion specs ride along (user_popovers_spec, init_duo_panel_spec) because they assert against the converted bootstrap shapes.

All conversions in this MR are the exact content that was CI-proven on the pre-split !247299 (merged) (full run-all-rspec + run-rspec-vue3 matrix, pipeline 2716536446 lineage).

MR acceptance checklist

Edited by Illya Klymov

Merge request reports

Loading
Loading