[Bug 40788] New: Add a custom event to Vue/Vue Islands when the Vue is loaded
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 Bug ID: 40788 Summary: Add a custom event to Vue/Vue Islands when the Vue is loaded Change sponsored?: --- Product: Koha Version: Main Hardware: All OS: All Status: NEW Severity: enhancement Priority: P5 - low Component: Architecture, internals, and plumbing Assignee: koha-bugs@lists.koha-community.org Reporter: lucas@bywatersolutions.com QA Contact: testopia@bugs.koha-community.org To make Vue/Vue Islands work with customization from IntranetUserJS we need to add a custom event to tell JS the content is loaded. -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 Lisette Scheer <lisette@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |lisette@bywatersolutions.co | |m -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 David Cook <dcook@prosentient.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |dcook@prosentient.com.au --- Comment #1 from David Cook <dcook@prosentient.com.au> --- Can you flesh this one out some more? Are you wanting code in IntranetUserJS to run only after the Vue/Vue Islands have loaded and rendered output? In practice, I think this can be quite challenging because of the reactivity of Vue components. Like you might overwrite a label at page load time, but it can just get changed back during the normal course of operation for the Vue.js. Are you thinking a custom event that we'd dispatch to the "document" element from the Vue? That might work as a once off, but it might be necessary to have more hooks. I think it gets complicated quickly. -- I have pondered this one a bit in the past. I had a PHP app with several different Vue apps on the same page, and some third-party Javascript to try to customize the HTML (this was before Vue apps were added to the PHP app). I linked the Vue apps together using a simple event bus (suboptimal but easy enough for this simple case), but I think I ditched the third-party Javascript. Although the way I did that was by allowing custom alternative templates to be added on a per-instance level for the PHP app. So that different instances of the overall app (like Koha) could have different custom templates. That comes with a number of its own problems too, of course. -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #2 from David Cook <dcook@prosentient.com.au> --- Do you have any particular use cases in mind? I have been thinking that the designs used in IntranetUserJS might need to evolve in a Vue.js world. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #3 from Lucas Gass (lukeg) <lucas@bywatersolutions.com> --- (In reply to David Cook from comment #2)
Do you have any particular use cases in mind?
I have been thinking that the designs used in IntranetUserJS might need to evolve in a Vue.js world.
I think you may be right. Simple use case is: -Prior to 25.05 I was using a IntranetUserJS to add a custom link to the acquisitions menu ( #acquisitions-menu ). After upgrading to 25.05, that jQuery doesn't work consistently. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #4 from David Cook <dcook@prosentient.com.au> --- (In reply to Lucas Gass (lukeg) from comment #3)
I think you may be right. Simple use case is:
-Prior to 25.05 I was using a IntranetUserJS to add a custom link to the acquisitions menu ( #acquisitions-menu ). After upgrading to 25.05, that jQuery doesn't work consistently.
Ah so that will be bug 38941 changing the acquisitions menu into a Vue.js web component eh... That's a tricky one. I've got some ideas... -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #5 from David Cook <dcook@prosentient.com.au> --- First option which can be used immediately: I created a simple MutationObserver[1] that added a link to the acquisitions menu consistently. Basically, it just observes if the "acquisitions-menu" adds a child node, and fires when it does. Due to the design of that menu, it's pretty efficient, since that should just happen once. [1] const observer = new MutationObserver((mutations) => { let acq_menu = document.querySelector("div#acquisitions-menu ul"); if (acq_menu){ if ( ! document.querySelector("li#new_list") ){ let new_list = document.createElement("li"); new_list.id = "new_list"; let new_link = document.createElement('a'); new_link.textContent = 'Awesome link'; new_list.appendChild(new_link); acq_menu.appendChild(new_list); } } }); observer.observe(document.querySelector("acquisitions-menu"), { childList: true }); -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #6 from David Cook <dcook@prosentient.com.au> --- Second option which would take some development... In theory I think that we could use Vue.js mixins (https://vuejs.org/api/options-composition#mixins) to create and dispatch custom events. We could update koha-tmpl/intranet-tmpl/prog/js/vue/modules/islands.ts so it would be like "island_created", "island_mounted", etc. And then we could make sure the event had data in it so that the island itself could be located (like one does with a click handler using event.target). That could be cool. The usefulness will probably vary depending on the case I imagine. But that would just work for our Vue islands. For other Vue components... it gets harder because they get defined in all kinds of different places. Islands are handy because they're all managed through that one islands.ts file. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #7 from David Cook <dcook@prosentient.com.au> --- I suppose another option could be to make Vue.js menus specifically extensible in some way. But that would probably be difficult to do in a way that made everyone happy. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #8 from David Cook <dcook@prosentient.com.au> --- Another thought... at the moment IntranetUserJS is loaded via <script></script> Check out my comment here: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=38706#c12 If we had the ability to load IntranetUserJs snippets with different attributes, that changes things too. For instance, you could change the snippet to also be a "module", and then things can get interesting, as IntranetUserJS gets run *after* islands.esm in terms of DOM order. That said, I think the imports are done asynchronously so using something event-driven would be better. -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #9 from David Cook <dcook@prosentient.com.au> --- That said, while the above work for acquisitions-menu, for something like http://localhost:8081/cgi-bin/koha/acquisition/vendors/1 I think it could be tougher. Oh well. Certainly an interesting area to explore... -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #10 from Lucas Gass (lukeg) <lucas@bywatersolutions.com> --- Created attachment 196748 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=196748&action=edit Bug 40788: Add custom Vue event to ERM pages Patch from commit 5a26b7b -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #11 from Lucas Gass (lukeg) <lucas@bywatersolutions.com> --- This isn't ready, I'm just messing around. However: 1/ Apply patch 2/ yarn build 3/ add this to IntranetUserJS: $(document).one('koha:vue-loaded', function () { $('#shortcut').append('<div><a class href="https://help.bywatersolutions.com/portal/en/kb/products/koha/modules/tools" id="helper" target="_blank"><i class="fa-brands fa-readme"></i><span>Knowledgebase</span></a></div>'); console.log("BOOP"); }); -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #12 from Lucas Gass (lukeg) <lucas@bywatersolutions.com> --- I'm also pretty sure the custom event is in the wrong place right now, but this does work. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 David Cook <dcook@prosentient.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |me@paulderscheid.xyz -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #13 from David Cook <dcook@prosentient.com.au> --- (In reply to Lucas Gass (lukeg) from comment #12)
I'm also pretty sure the custom event is in the wrong place right now, but this does work.
I know what you mean. It looks like with Vue.js 3 that composables rather than mix-ins might be the way to go as I think mixins were a Vue.js 2 thing. Added Paul D via CC as he might have thoughts on this one. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 David Cook <dcook@prosentient.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |martin.renvoize@openfifth.c | |o.uk --- Comment #14 from David Cook <dcook@prosentient.com.au> --- Adding Martin too as I'm sure OpenFifth folks would have useful input -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 Michaela Sieber <michaela.sieber@kit.edu> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clemens.tubach@kit.edu, | |michael.skarupianski@gmail. | |com, | |michaela.sieber@kit.edu, | |paul.derscheid@lmscloud.de -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #15 from Paul Derscheid <paul.derscheid@lmscloud.de> --- Created attachment 196774 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=196774&action=edit Bug 40788: (follow-up) Add custom Vue events to all Vue apps and islands Extends the koha:vue-loaded event to all Vue app entry points and adds koha:island-loaded / koha:islands-ready events for Vue Islands, so that IntranetUserJS can reliably interact with Vue-rendered content across the entire staff interface. For full Vue apps (ERM, Acquisitions, Preservation, SIP2) the event fires after async initialization completes and nextTick ensures the DOM has updated. For admin/record_sources, which has no async init, the event fires right after app.mount(). For Vue Islands the koha:island-loaded event fires per island after customElements.define(), and koha:islands-ready fires once all islands on the page are hydrated. To test: - Apply patch and run: yarn build - Add the following to IntranetUserJS: document.addEventListener("koha:vue-loaded", function(e) { console.log("Vue loaded:", e.detail.module); }); document.addEventListener("koha:island-loaded", function(e) { console.log("Island loaded:", e.detail.name); }); document.addEventListener("koha:islands-ready", function() { console.log("All islands ready"); }); - Open the browser console and navigate to each of: - /cgi-bin/koha/erm/erm.pl => console shows "Vue loaded: erm" - /cgi-bin/koha/acqui/vendors.pl => console shows "Vue loaded: acquisitions" - /cgi-bin/koha/preservation/home.pl => console shows "Vue loaded: preservation" - /cgi-bin/koha/admin/sip2/servers.pl => console shows "Vue loaded: sip2" - /cgi-bin/koha/admin/record_sources => console shows "Vue loaded: admin/record_sources" - /cgi-bin/koha/acqui/acqui-home.pl (has acquisitions-menu island) => console shows "Island loaded: acquisitions-menu" and "All islands ready" - /cgi-bin/koha/admin/admin-home.pl (has admin-menu island) => console shows "Island loaded: admin-menu" and "All islands ready" - Verify that each event fires only after the page content is actually rendered (menus, tables, etc. are visible) -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #16 from Paul Derscheid <paul.derscheid@lmscloud.de> --- I tested your patch, Lucas. I think the idea is correct and I added it everywhere in a follow-up. We could probably hook into Vue's entire component lifecycle, as you said, David. I'd say it depends on what exactly needs to be made extensible, might differ between the menus and the full apps. -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 Andrew Fuerste-Henry <andrew@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |andrew@bywatersolutions.com -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 --- Comment #17 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Created attachment 199302 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=199302&action=edit Bug 40788: DRY into vueModule composable Patch from commit b1d5ea5 -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |pedro.amorim@openfifth.co.u | |k --- Comment #18 from Pedro Amorim (ammopt) <pedro.amorim@openfifth.co.uk> --- Hi guys I've added yet another follow-up here to this discussion. I feel like having a vueModule composable is long overdue, even though it doesn't solve the islands.ts and record_sources.ts. -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=40788 Michaela Sieber <michaela.sieber@kit.edu> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://bugs.koha-community | |.org/bugzilla3/show_bug.cgi | |?id=42150 -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
participants (1)
-
bugzilla-daemon@bugs.koha-community.org