1import { Controller } from "@hotwired/stimulus" 2 3/** 4 * Manages save view modal interaction. 5 * 6 * Values: 7 * - context: the controller#action context string 8 */ 9export default class extends Controller { 10 static values = { 11 context: String 12 } 13 14 disconnect() {} 15 16 /** 17 * Used by the "Create View" button in the views dropdown. Opens the 18 * save-view modal when it exists on the page (filters are active and not 19 * already saved). Falls back to the legacy filter-modal event for hosts 20 * still rendering the pre-0.5 markup. 21 */ 22 openFilters(event) { 23 event.preventDefault() 24 25 if (document.getElementById("save-view-modal")) { 26 this.openModal(event) 27 return 28 } 29 30 setTimeout(() => document.dispatchEvent(new CustomEvent('filter-modal:open')), 50) 31 } 32 33 /** 34 * Opens the save view modal dialog. 35 * @param {Event} event 36 */ 37 openModal(event) { 38 event.preventDefault() 39 40 const modal = document.getElementById("save-view-modal") 41 if (modal && typeof modal.showModal === "function") { 42 // Set the context value in the hidden field (the modal already carries 43 // the right context when opened from the chips-row save button) 44 const contextInput = modal.querySelector('input[name="filter_view[context]"]') 45 if (contextInput && this.contextValue) { 46 contextInput.value = this.contextValue 47 } 48 49 // Copy current filter params into the save form 50 const filterForm = document.querySelector('[data-controller="filter-form"]') 51 if (filterForm) { 52 const filterParamsContainer = modal.querySelector("[data-view-filter-params]") 53 if (filterParamsContainer) { 54 filterParamsContainer.innerHTML = "" 55 const formData = new FormData(filterForm) 56 for (const [key, value] of formData.entries()) { 57 if (key.startsWith("filter[")) { 58 const input = document.createElement("input") 59 input.type = "hidden" 60 input.name = `filter_view[filter_params][${key.slice(7, -1)}]` 61 input.value = value 62 filterParamsContainer.appendChild(input) 63 } 64 } 65 66 // Also collect modal-injected fields 67 const modalFields = filterForm.querySelectorAll('[data-modal-field]') 68 modalFields.forEach(field => { 69 if (field.name.startsWith("filter[")) { 70 const input = document.createElement("input") 71 input.type = "hidden" 72 input.name = `filter_view[filter_params][${field.name.slice(7, -1)}]` 73 input.value = field.value 74 filterParamsContainer.appendChild(input) 75 } 76 }) 77 } 78 } 79 80 // Close the filter modal after successful save 81 const form = modal.querySelector('form') 82 if (form) { 83 form.addEventListener('turbo:submit-end', (e) => { 84 if (e.detail?.success) { 85 document.dispatchEvent(new CustomEvent('filter-modal:close')) 86 } 87 }, { once: true }) 88 } 89 90 modal.showModal() 91 } 92 } 93}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.