Schedules Vue 2 to Vue 3 migration (ITCR-1301)

Summary

Migrates the Schedules dashboard app (js/repeat/src/repeat.js, the results-table child component previously in js/schedules.js) from Vue 2 to Vue 3. Tracked as ITCR-1301; full wave-by-wave planning/decision/QA docs at https://github.com/ITCare-Company/schedule_v2_v3_queue.

Changes

  • new Vue({el, router, data:{...}}) -> createApp({data() {...}}).mount('#app').
  • Uses the shared openy_system/vue3 library (added in open-y-subprojects/openy_custom 3.2.0 -- Vue 3.5.41 full build, loaded from cdnjs, exposes window.Vue) instead of bundling Vue into js/repeat.js. webpack marks vue as externals: { vue: 'Vue' }, so import { createApp } from 'vue' resolves to Vue.createApp at runtime; js/repeat.js drops from ~242KB to ~44KB. openy_repeat.libraries.yml gains an openy_system/vue3 dependency; composer.json requires open-y-subprojects/openy_custom ^3.2.0. The legacy openy_system/vue (Vue 2) library is untouched -- AF3 and Camp Finder keep using it.
  • The shared build is the FULL Vue 3 build (with the runtime template compiler), which the root instance needs: it has no template/render option and compiles the server-rendered #app innerHTML at runtime.
  • Dropped vue-router entirely (routes:[] was never used for real routing, only as a URL query-string mirror) -- replaced with URLSearchParams/history.pushState.
  • Folded js/schedules.js's Vue.component('results', {...}) into repeat.js as a real child component, since Vue 3 removed the global Vue.component() API. Moved the <results inline-template> markup (Vue 3 removed inline-template entirely) into that component's own template: string, with $parent. prefixing added everywhere the markup previously relied on inline-template's implicit parent-scope inheritance.
  • Vue.config.devtools / Vue.nextTick() -> nextTick import from vue.
  • delimiters moved from a per-component option to app.config.compilerOptions.delimiters (Vue 3 removed the former).
  • Fixed a duplicate v-if="item.register_url" attribute on one element (Vue 2 tolerated it silently; Vue 3's compiler hard-errors on duplicate attributes).

Known follow-up (not fixed in this MR, flagged for a separate issue)

  • 3 Twig-translated strings ('h', 'min', the empty-results message) and the ajax-spinner Twig include, formerly inside the Twig-rendered inline-template, are now static English/default markup baked into the JS template string. Needs a proper prop-based fix before non-English sites pick this up.
  • A pre-existing (non-Vue3, unrelated to this migration) race condition: rapid clicks on two different class links can show stale modal data, since populatePopupClass's AJAX calls have no request cancellation/sequencing.
  • A pre-existing (non-Vue3) code nit: scrollToTop() checks screen.width instead of window.innerWidth.

Test plan

  • cd js/repeat && npm ci && npm run build -- clean build; [18] external "Vue" in the webpack output confirms Vue is not bundled.
  • Verified on a local YUSAOpenY standard/openy_carnation site: openy_system/vue3 resolves via library.discovery, openy_repeat/openy_repeat depends on it, the schedules page emits the cdnjs vue.global.prod.min.js script before repeat.js, and the rebuilt repeat.js (44KB) is served.
  • Earlier (pre-shared-lib) end-to-end run: dashboard renders real demo data, pagination, class/location popups, datepicker, add-to-calendar all correct; zero Vue console errors; zero raw ${...} text.
  • Full W6 QA visual/functional parity pass against the Vue 2 baseline, on a build that actually carries openy_custom 3.2.0 (not yet done).
Edited by Lera Shuklina

Merge request reports

Loading
Loading