Jake Vanderwerf
2026-01-06 2c955cebb5f1e01fbdb866b50d296fe9fbd852b8
assets/js/min/selector.min.js
@@ -1 +1 @@
(()=>{class e{constructor(){this.a11y=window.jvbA11y,this.error=window.jvbError,this.index=-1,this.isInitializing=!0,this.taxonomiesToFetch=new Set,this.subscribers=new Set;const e=window.jvbStore.register("taxonomies",{storeName:"terms",keyPath:"id",showLoading:!1,indexes:[{name:"taxonomy",keyPath:"taxonomy"},{name:"parent",keyPath:"parent"},{name:"slug",keyPath:"slug",unique:!0},{name:"count",keyPath:"count"}],endpoint:"terms",TTL:12e4,filters:{taxonomy:"",page:1,search:"",parent:0},required:"taxonomy",delayFetch:!0});this.store=e.terms,this.fields=new Map,this.selectedTerms=new Map,this.activeField=null,this.currentConfig=null,this.disabled=!1,this.searchContexts=new Map,this.init()}init(){this.initModal(),this.scanExistingFields(),this.initGlobalListeners(),this.needsCreator()&&window.jvbTaxCreator&&(this.creator=new window.jvbTaxCreator(this)),this.store.subscribe(this.handleStoreEvent.bind(this)),this.isInitializing=!1,this.batchFetchTaxonomies()}needsCreator(){return Array.from(this.fields.values()).some((e=>e.canCreate||e.hasAutocomplete))}handleStoreEvent(e,t){const i={"data-loaded":()=>this.handleDataLoaded(t),"filters-changed":()=>this.handleFiltersChanged(t),"fetch-error":()=>this.handleFetchError(t.error)};i[e]?.()}handleDataLoaded(e){const t=this.store.filters.taxonomy;if(t){(t.includes(",")?t.split(",").map((e=>e.trim())):[t]).forEach((e=>this.updateFieldsForTaxonomy(e)))}this.isInitializing&&this.fields.forEach(((e,t)=>{e.selectedTerms.size>0&&this.initFieldDisplay(t)})),this.renderSearchResults(e)}renderSearchResults(e){const t=this.getActiveSearchContext();"modal"===t?this.renderModalResults(e):"autocomplete"===t&&this.renderAutocompleteResults(e)}getActiveSearchContext(){return this.modal?.open?"modal":this.activeField&&this.searchContexts.has(this.activeField)?this.searchContexts.get(this.activeField):null}renderModalResults(e){this.hideLoading();const t=this.store.getFiltered(),i=this.store.lastResponse?.page||{},s=e.filters?.search?.length>0,o=i.page>1;this.notify("terms-loaded",{terms:t,filters:e.filters}),0===t.length?(o||this.showEmptyState(s?"No results found.":"No items available."),this.observer.unobserve(this.ui.sentinel)):(this.renderTerms(t,o,s),i.has_more?this.observer.observe(this.ui.sentinel):this.observer.unobserve(this.ui.sentinel)),this.a11y?.announce(t.length,o)}renderAutocompleteResults(e){const t=this.fields.get(this.activeField);if(!t?.autocompleteDropdown)return;const i=this.store.getFiltered(),s=e.filters?.search||"";this.showAutocompleteResults(t,i,s),this.searchContexts.delete(this.activeField)}handleFiltersChanged(e){this.modal?.open&&this.showLoading()}handleFetchError(e){this.hideLoading();"autocomplete"===this.getActiveSearchContext()?(this.showAutocompleteError(this.activeField),this.searchContexts.delete(this.activeField)):this.handleError(e,"fetch")}updateFieldsForTaxonomy(e){this.getFieldsForTaxonomy(e).forEach((e=>{this.updateFieldButtonState(e.id)}))}updateFieldButtonState(e){const t=this.fields.get(e);if(!t)return;const i=Array.from(this.store.data.values()).some((e=>e.taxonomy===t.taxonomy));t.toggle&&(t.toggle.disabled=!i&&!t.canCreate,t.toggle.title=i?`Select ${this.getLabel(t.taxonomy,"plural")}`:`No ${this.getLabel(t.taxonomy,"single")} available`)}getFieldsForTaxonomy(e){return Array.from(this.fields.values()).filter((t=>t.taxonomy===e))}scanExistingFields(e=document.body){e.querySelectorAll(".field.taxonomy, .field.post").forEach((e=>{try{this.registerField(e)}catch(t){this.handleError(t,"scanExistingFields",e.dataset.name)}}))}registerField(e){const t=e.querySelector("input[type=hidden]");if(!t)return!1;const i=this.createFieldId(e);e.dataset.fieldId=i;const s=e.querySelector("button.taxonomy-toggle"),o={id:i,input:t,container:e,taxonomy:s.dataset.taxonomy,name:e.dataset.field,maxSelection:parseInt(s.dataset.max)||0,canSearch:"search"in s.dataset,hasAutocomplete:"autocomplete"in s.dataset,autocompleteDropdown:e.querySelector(".autocomplete-dropdown")||null,canCreate:"creatable"in s.dataset,isRequired:"required"in s.dataset,selectedTerms:new Set,toggle:s,selectedContainer:e.querySelector(".selected-items")},a=t.value.trim();return a&&a.split(",").map((e=>parseInt(e.trim()))).filter((e=>!isNaN(e))).forEach((e=>o.selectedTerms.add(e))),this.fields.set(i,o),this.isInitializing&&this.taxonomiesToFetch.add(o.taxonomy),o.selectedTerms.size>0&&this.initFieldDisplay(i),i}createFieldId(e){return this.index++,"selector-"+this.index}async initFieldDisplay(e){const t=this.fields.get(e);t&&0!==t.selectedTerms.size&&Array.from(t.selectedTerms).forEach((t=>{const i=this.store.get(t);i&&this.addTermDisplay(t,i.name,i.path,"field",e)}))}initModal(){this.modal=document.querySelector("dialog#jvb-selector"),this.modal?(this.initModalElements(),this.modalInstance=new window.jvbModal(this.modal,{handleForm:!1}),this.modalInstance.subscribe((e=>{"modal-open"===e&&this.openModal(),"modal-close"===e&&this.closeModal()}))):console.warn("Taxonomy selector modal not found")}initModalElements(){this.ui=window.uiFromSelectors({search:{input:"[type=search]",container:".search-wrapper"},termsList:".items-container",termsWrap:".items-wrap",breadcrumbs:{nav:"nav.term-navigation",back:".back-to-parent"},loading:{loading:".loading",text:".loading span"},selectedTerms:".selected-items",sentinel:".scroll-sentinel",modal:{title:"#modal-title"},create:{details:".create-new-term",summary:".create-new-term summary",label:{name:"[for=term_name]",parent:"[for=select_parent]"}}}),this.observer=new IntersectionObserver((e=>{e.forEach((e=>{e.isIntersecting&&this.loadMoreTerms()}))}),{root:this.ui.termsWrap,threshold:.5})}initGlobalListeners(){document.addEventListener("click",this.handleClick.bind(this)),document.addEventListener("change",this.handleChange.bind(this)),document.addEventListener("input",this.handleInput.bind(this)),document.addEventListener("focus",this.handleFocus.bind(this),!0),document.addEventListener("blur",this.handleBlur.bind(this),!0)}handleClick(e){if(window.targetCheck(e,".taxonomy-toggle")){e.preventDefault();const t=this.getFieldId(e.target);return void(this.fields.get(t)&&this.setActiveField(t,!0))}const t=window.targetCheck(e,"button.remove-item");if(t&&e.target.closest(".jvb-selector")){const e=this.getFieldId(t),i=t.closest(".selected-item").dataset.id;this.removeSelectedTerm(e,i)}else e.target.matches(".modal-close")?this.modalInstance?.handleClose():this.modal?.contains(e.target)&&this.handleModalClick(e)}handleChange(e){if(window.targetCheck(e,".taxonomy.field, .post.field")&&"hidden"===e.target.type){const t=this.getFieldId(e.target);this.updateFieldFromInput(t)}else this.modal?.contains(e.target)&&this.handleModalChange(e)}handleInput(e){if(this.modal?.contains(e.target)&&"search"===e.target.type)this.performSearch(e.target.value.trim(),"modal");else if("autocomplete"in e.target.dataset){const t=this.getFieldId(e.target),i=this.fields.get(t);i?.hasAutocomplete&&this.performSearch(e.target.value.trim(),"autocomplete",t)}}handleFocus(e){if(!("autocomplete"in e.target.dataset))return;const t=this.getFieldId(e.target),i=this.fields.get(t);i?.hasAutocomplete&&this.preloadTaxonomy(i.taxonomy)}handleBlur(e){"autocomplete"in e.target.dataset&&setTimeout((()=>{const t=this.getFieldId(e.target),i=this.fields.get(t);i?.autocompleteDropdown&&(i.autocompleteDropdown.hidden=!0),this.searchContexts.delete(t)}),200)}performSearch(e,t="modal",i=null){const s="autocomplete"===t?this.fields.get(i):this.currentConfig;if(s){if("autocomplete"===t){if(s.currentAutocompleteQuery=e,e.length<2)return void(s.autocompleteDropdown&&(s.autocompleteDropdown.hidden=!0));this.searchContexts.set(i,"autocomplete"),this.activeField=i,s.autocompleteDropdown&&(s.autocompleteDropdown.hidden=!1)}window.debouncer.schedule(`taxonomy-search-${t}-${i||"modal"}`,(async()=>{await this.store.setFilters({taxonomy:s.taxonomy,search:e,page:1,parent:e?0:this.store.filters.parent||0}),"modal"===t&&window.removeChildren(this.ui.termsList)}),300)}}setActiveField(e,t=!1){this.activeField=e,this.currentConfig=this.fields.get(e),t&&this.modalInstance.handleOpen(),this.store.setFilter("taxonomy",this.currentConfig.taxonomy),this.selectedTerms.clear(),this.currentConfig.selectedTerms.forEach((e=>{const t=this.store.get(e);t&&this.selectedTerms.set(e,{id:e,name:t.name,path:t.path})}))}handleModalClick(e){if(window.targetCheck(e,".remove-item")){const t=window.targetCheck(e,".selected-item");t&&this.removeSelectedTermFromModal(t.dataset.id)}else if(window.targetCheck(e,".back-to-parent"))this.navigateToParent();else if(window.targetCheck(e,".toggle-children")){const t=e.target.closest("li");this.navigateToChild(parseInt(t.dataset.id),t.querySelector(".term-name").textContent)}else if(window.targetCheck(e,".path-level")){const t=window.targetCheck(e,".path-level");this.navigateToPath(parseInt(t.dataset.id)||0)}}handleModalChange(e){if("checkbox"!==e.target.type)return;e.preventDefault(),e.stopPropagation();const t=parseInt(e.target.closest("li").dataset.id),i=e.target.closest("li").querySelector("label");e.target.checked?this.addSelectedTermToModal(t,i.title,i.dataset.path):this.removeSelectedTermFromModal(t)}openModal(){this.currentConfig?(this.updateModalUI(),this.updateModalSelections(),window.removeChildren(this.ui.termsList),this.showLoading()):console.error("No active field set")}closeModal(){this.observer.unobserve(this.ui.sentinel),window.removeChildren(this.ui.termsList),this.notify("selected-terms",{terms:this.selectedTerms,taxonomy:this.currentConfig.taxonomy}),this.activeField&&this.saveSelectionsToField(this.activeField),this.activeField=null,this.currentConfig=null}updateModalUI(){const e=this.getLabel(this.currentConfig.taxonomy,"single"),t=this.getLabel(this.currentConfig.taxonomy,"plural");this.ui.modal.title.textContent=`Select ${t}`,this.ui.search.container&&(this.ui.search.container.style.display=this.currentConfig.canSearch?"block":"none"),this.ui.create.details&&(this.ui.create.details.style.display=this.currentConfig.canCreate?"block":"none",this.ui.create.details.hidden=!this.currentConfig.canCreate,this.ui.create.summary&&(this.ui.create.summary.textContent=`Add new ${e}`),this.ui.create.label.name&&(this.ui.create.label.name.textContent=`Name this ${e}`),this.ui.create.label.parent&&(this.ui.create.label.parent.textContent="Nest it under")),this.a11y?.announce(`Opened ${e} selection. Choose from checkboxes or search to filter results.`)}updateModalSelections(){window.removeChildren(this.ui.selectedTerms),this.selectedTerms.forEach(((e,t)=>{this.addTermDisplay(t,e.name,e.path,"modal")})),this.checkSelectionLimits()}addSelectedTermToModal(e,t,i){this.selectedTerms.set(e,{id:e,name:t,path:i}),this.addTermDisplay(e,t,i,"modal"),this.checkSelectionLimits();const s=this.ui.termsList.querySelector(`input[value="${e}"]`);s&&(s.checked=!0)}removeSelectedTermFromModal(e){this.selectedTerms.delete(parseInt(e));const t=this.ui.selectedTerms.querySelector(`[data-id="${e}"]`);t&&t.remove();const i=this.ui.termsList.querySelector(`input[value="${e}"]`);i&&(i.checked=!1),this.checkSelectionLimits()}checkSelectionLimits(){this.currentConfig&&0!==this.currentConfig.maxSelection&&(this.disabled=this.selectedTerms.size>=this.currentConfig.maxSelection,this.ui.termsList.querySelectorAll('input[type="checkbox"]').forEach((e=>{e.checked||(e.disabled=this.disabled)})))}saveSelectionsToField(e){const t=this.fields.get(e);t&&(t.selectedTerms.clear(),window.removeChildren(t.selectedContainer),this.selectedTerms.forEach(((i,s)=>{t.selectedTerms.add(s),this.addTermDisplay(s,i.name,i.path,"field",e)})),t.input.value=Array.from(t.selectedTerms).join(","),t.input.dispatchEvent(new Event("change",{bubbles:!0})))}addTermDisplay(e,t,i,s="field",o=null){const a="field"===s?this.fields.get(o):this.currentConfig,n="field"===s?a.selectedContainer:this.ui.selectedTerms;if(n.querySelector(`[data-id="${e}"]`))return;const r=window.getTemplate("selectedTerm");if(r.dataset.id=e,r.dataset.path=i,r.dataset.name=t,r.dataset.taxonomy=a.taxonomy,r.querySelector(".item-name").textContent=i,r.querySelector("button").title=`Remove ${t}`,n.appendChild(r),"modal"===s){const t=this.ui.termsList.querySelector(`input[value="${e}"]`);t&&(t.checked=!0)}}removeSelectedTerm(e,t){const i=this.fields.get(e);if(!i)return;i.selectedTerms.delete(parseInt(t));const s=i.selectedContainer.querySelector(`[data-id="${t}"]`);s&&s.remove(),i.input.value=Array.from(i.selectedTerms).join(","),i.input.dispatchEvent(new Event("change",{bubbles:!0}))}updateFieldFromInput(e){const t=this.fields.get(e);if(!t)return;const i=t.input.value.trim();t.selectedTerms.clear(),window.removeChildren(t.selectedContainer),i&&(i.split(",").map((e=>parseInt(e.trim()))).filter((e=>!isNaN(e))).forEach((e=>t.selectedTerms.add(e))),this.initFieldDisplay(e))}navigateToParent(){this.store.setFilters({parent:0,page:1}),window.removeChildren(this.ui.termsList),this.ui.breadcrumbs.back.hidden=!0}navigateToChild(e,t){this.store.setFilters({parent:e,page:1}),window.removeChildren(this.ui.termsList),this.updateBreadcrumbs(e,t),this.ui.breadcrumbs.back.hidden=!1}navigateToPath(e){this.store.setFilters({parent:e,page:1}),window.removeChildren(this.ui.termsList),this.ui.breadcrumbs.back.hidden=0===e}loadMoreTerms(){const e=this.store.filters.page||1;this.store.setFilter("page",e+1)}updateBreadcrumbs(e,t){const i=window.getTemplate("termBreadcrumb");i.dataset.id=e,i.textContent=t,i.title=t;const s=this.ui.breadcrumbs.nav.querySelector(`[data-id="${e}"]`);if(s)for(;s.nextElementSibling;)s.nextElementSibling.remove();else this.ui.breadcrumbs.nav.appendChild(i)}renderTerms(e=null,t=!1,i=!1){if(e||(e=this.store.getFiltered()),t||window.removeChildren(this.ui.termsList),0===e.length)return void(t||this.showEmptyState());const s=this.store.filters.parent||0;this.ui.breadcrumbs.back.hidden=0===s;const o=document.createDocumentFragment();e.forEach((e=>{const t=this.createTermElement({id:parseInt(e.id),name:e.name,hasChildren:e.hasChildren,path:e.path||null,show:i});t&&o.appendChild(t)})),this.ui.termsList.appendChild(o)}createTermElement(e){if(!e?.name)return null;const t=window.getTemplate("termListItem");t.dataset.id=e.id;const i=this.selectedTerms.has(e.id),s=t.querySelector("input"),o=t.querySelector("label"),a=t.querySelector(".term-name");if(s.id=`${this.currentConfig.container.id}${e.id}`,s.name=`${this.currentConfig.container.id}${this.currentConfig.taxonomy}-select`,s.value=e.id,s.disabled=!i&&this.disabled,s.checked=i,o.htmlFor=s.id,o.title=e.path||e.name,o.dataset.path=e.path,a.textContent=e.show?e.path:e.name,e.hasChildren){const i=window.getTemplate("termChildrenToggle");i.ariaLabel=`View sub-terms of ${e.name}`,t.appendChild(i)}return t}showAutocompleteResults(e,t,i){if(!e?.autocompleteDropdown)return;const s=e.autocompleteDropdown;if(window.removeChildren(s),0===t.length)this.showEmptyState("No items found.",s);else{const i=document.createDocumentFragment();t.forEach((t=>{const s=this.createAutocompleteItem(e,t);s&&i.appendChild(s)})),s.appendChild(i)}const o=e.currentAutocompleteQuery||i;if(e.canCreate&&o){t.find((e=>e.name.toLowerCase()===o.toLowerCase()))||s.appendChild(this.createAutocompleteCreateButton(o))}s.hidden=!1}createAutocompleteItem(e,t){const i=document.createElement("button");return i.type="button",i.className="autocomplete-item",i.dataset.id=t.id,i.dataset.name=t.name,i.dataset.path=t.path||t.name,i.textContent=t.path||t.name,i.addEventListener("click",(()=>{e.selectedTerms.add(parseInt(t.id)),this.addTermDisplay(t.id,t.name,t.path,"field",e.id),e.input.value=Array.from(e.selectedTerms).join(","),e.input.dispatchEvent(new Event("change",{bubbles:!0})),e.autocompleteDropdown.hidden=!0;const i=e.container.querySelector("input[data-autocomplete]");i&&(i.value="")})),i}createAutocompleteCreateButton(e){const t=document.createElement("button");t.type="button",t.className="autocomplete-item create-term",t.dataset.query=e;const i=document.createElement("strong");return i.textContent="Create: ",t.appendChild(i),t.appendChild(document.createTextNode(`"${e}"`)),t}showAutocompleteError(e){const t=this.fields.get(e);t?.autocompleteDropdown&&(window.removeChildren(t.autocompleteDropdown),this.showEmptyState("Hmmm... something went wrong",t.autocompleteDropdown))}showLoading(){this.ui.loading.loading.hidden=!1,this.modal.classList.add("loading");const e=this.store.filters.search||"",t=this.store.filters.parent||0,i=e?`searching for "${e}" items`:0===t?"loading items":"loading child items";window.typeLoop?this.stopTyping=window.typeLoop(this.ui.loading.text,i):this.ui.loading.text.textContent=i}hideLoading(){this.ui.loading.loading.hidden=!0,this.modal.classList.remove("loading"),this.stopTyping&&this.stopTyping()}showEmptyState(e="No items found.",t=null){t||(t=this.ui.termsList);const i=window.getTemplate("noResults"),s=i.querySelector("span");e&&s&&(s.textContent=e),t.appendChild(i)}getFieldId(e){if(e.dataset.fieldId)return e.dataset.fieldId;const t=e.closest("[data-field-id]");return t?.dataset.fieldId||null}getLabel(e,t="single"){return jvbSettings.labels[e]?.[t]||e}async batchFetchTaxonomies(){if(0===this.taxonomiesToFetch.size)return;const e=Array.from(this.taxonomiesToFetch);this.taxonomiesToFetch.clear(),this.store.setFilters({taxonomy:e.join(","),page:1,search:"",parent:0})}async preloadTaxonomy(e){await this.store.setFilters({taxonomy:e,page:1,search:"",parent:0})}handleError(e,t,i=null){console.error(`Taxonomy ${t} error:`,e,i),this.error?.log&&this.error.log(e,{component:"TaxonomySelector",action:t,detail:i}),this.modal?.open&&this.showEmptyState("Error loading. Please try again.")}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t={}){this.subscribers.forEach((i=>{try{i(e,t)}catch(e){console.error("Subscriber error:",e)}}))}destroy(){document.removeEventListener("click",this.handleClick),document.removeEventListener("change",this.handleChange),document.removeEventListener("input",this.handleInput),document.removeEventListener("focus",this.handleFocus),document.removeEventListener("blur",this.handleBlur),this.observer?.disconnect(),this.store.destroy(),this.subscribers.clear(),this.fields.clear(),this.selectedTerms.clear(),this.searchContexts.clear()}}document.addEventListener("DOMContentLoaded",(()=>{window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbSelector=new e)}))}))})();
(()=>{class e{constructor(){this.container=document.querySelector("dialog#jvb-selector"),this.container&&(this.a11y=window.jvbA11y,this.error=window.jvbError,this.subscribers=new Set,this.fields=new Map,this.selectedTerms=new Map,this.batchFetch=new Set,this.activeField=null,this.isInitializing=!0,this.messageText={},this.init())}init(){this.initStore(),this.initElements(),this.initModal(),this.scanExistingFields(),this.initListeners(),this.needsCreator()&&window.jvbTaxCreator&&(this.creator=new window.jvbTaxCreator(this)),this.isInitializing=!1,this.batchFetchTaxonomies().then((()=>{}))}initStore(){const e=window.jvbStore.register("taxonomies",{storeName:"terms",keyPath:"id",showLoading:!1,indexes:[{name:"taxonomy",keyPath:"taxonomy"},{name:"parent",keyPath:"parent"},{name:"slug",keyPath:"slug",unique:!0},{name:"count",keyPath:"count"}],endpoint:"terms",TTL:12e4,filters:{taxonomy:"",page:1,search:"",parent:0},required:"taxonomy",delayFetch:!0});this.store=e.terms,this.store.subscribe(this.handleStoreEvent.bind(this))}initElements(){this.selectors={search:{input:"[type=search]",clear:".clear-search",container:".search-wrapper",results:".search-results"},create:{button:"button.submit-term",span:".submit-term span"},terms:{list:".items-container",wrap:".items-wrap",sentinel:".scroll-sentinel"},nav:{nav:"nav.term-navigation",back:".back-to-parent",child:".toggle-children",pathLevel:".path-level"},message:{message:"p.message",text:"p.message span"},selected:".selected-items",modal:{title:"#modal-title",content:".modal-content",count:".selection-count"},favourites:".favourite-terms",field:{toggle:"button.taxonomy-toggle",value:'input[type="hidden"]',selected:".selected-items",dropdown:{list:".search-results",wrapper:".auto-wrapper"},create:{button:".auto-wrapper .submit-term",span:".auto-wrapper button span"},search:"input[data-autocomplete]",message:{message:"p.message",text:"p.message span"}}},this.ui=window.uiFromSelectors(this.selectors,this.container)}initListeners(){this.observer=new IntersectionObserver((e=>{e.forEach((e=>{e.isIntersecting&&this.nextPage()}))}),{root:this.ui.terms.sentinel,threshold:.5}),this.clickHandler=this.handleClick.bind(this),this.changeHandler=this.handleChange.bind(this),this.inputHandler=this.handleInput.bind(this),this.focusHandler=this.handleFocus.bind(this),this.blurHandler=this.handleBlur.bind(this),document.addEventListener("click",this.clickHandler),document.addEventListener("change",this.changeHandler),document.addEventListener("input",this.inputHandler),document.addEventListener("focus",this.focusHandler,!0),document.addEventListener("blur",this.blurHandler,!0)}handleClick(e){const t=this.container.open?this.activeField:this.getFieldId(e.target),s=this.fields.get(t);if(!t||!s)return;const i=window.targetCheck(e,"[data-autocomplete-select]");if(i){let e=parseInt(i.dataset.id);this.addSelected(e,t),s.ui.dropdown.wrapper&&(s.ui.dropdown.wrapper.hidden=!0),s.ui.search&&(s.ui.search.value="")}if(window.targetCheck(e,this.selectors.field.toggle))return e.preventDefault(),void this.openModal(t);const r=window.targetCheck(e,".remove-term");if(r){const e=r.closest("[data-id]").dataset.id??!1;return void(t&&e&&this.removeSelected(parseInt(e),t))}if(e.target.matches(".modal-close"))return this.updateFieldValue(t),void this.modal?.handleClose();if(window.targetCheck(e,this.selectors.nav.back))return void this.navigateToParent();if(window.targetCheck(e,this.selectors.nav.child)){const t=e.target.closest("li"),s=parseInt(t.dataset.id);return void(s&&this.navigateTo(s))}const a=window.targetCheck(e,this.selectors.nav.pathLevel);if(a){const e=parseInt(a.dataset.id)??0;this.navigateTo(e)}window.targetCheck(e,this.selectors.field.dropdown)&&this.scheduleHideDropdown(t);if(window.targetCheck(e,this.selectors.search.clear)){const e=this.currentField();e&&e.ui.search&&(e.ui.search.value="",this.store.setFilters({search:"",page:1,parent:this.store.filters.parent||0})),this.ui.search.input&&(this.ui.search.input.value="")}if(this.creator){window.targetCheck(e,this.selectors.create.button)&&this.maybeCreateTerm(e).then((()=>{}))}}handleChange(e){if(!this.container.contains(e.target))return;if("checkbox"!==e.target.type)return;e.preventDefault(),e.stopPropagation();const t=parseInt(e.target.dataset.id);let s=this.getFieldId(e.target);e.target.checked?this.addSelected(t,s):this.removeSelected(t,s)}handleInput(e){let t=this.getFieldId(e.target)??this.activeField;if(!t)return;const s=this.fields.get(t);if(!s)return;if("checkbox"===e.target.type)return;e.preventDefault(),e.stopPropagation(),this.container.open||this.setField(t);let i=e.target.value.trim();this.setMessage(!0,`Searching for "${i}" in ${s.plural??"items"}`),window.debouncer.schedule(`${t}-search`,(async()=>{this.container.open&&window.removeChildren(this.ui.terms.list),await this.store.setFilters({taxonomy:s.taxonomy,search:i,page:1,parent:i?0:this.store.filters.parent||0})}),100)}setField(e){const t=this.fields.get(e);t?(this.activeField=e,this.setMessage(!0,`Loading ${t.plural}...`),this.resetFilters({taxonomy:t.taxonomy})):console.error("No field found...")}resetFilters(e){Object.hasOwn(e,"taxonomy")&&(e={page:1,search:"",parent:0,...e},this.store.setFilters(e))}handleFocus(e){const t=this.getFieldId(e.target),s=this.fields.get(t);t&&s&&(s.hasAutocomplete||s.hasSearch)&&(window.debouncer.cancel(`${t}-search-results`),this.container.open||this.setField(t))}handleBlur(e){const t=this.getFieldId(e.target),s=this.fields.get(t);t&&s&&s.hasAutocomplete&&!this.container.open&&this.scheduleHideDropdown(t)}scheduleHideDropdown(e){const t=this.fields.get(e);t&&window.debouncer.schedule(`${e}-search-results`,(()=>{this.container.open||(this.activeField=null),t.ui.dropdown.wrapper&&(t.ui.dropdown.wrapper.hidden=!0)}),1500)}initModal(){this.modalID="dialog#jvb-selector",this.container=document.querySelector(this.modalID),this.modal=new window.jvbModal(this.container,{handleForm:!1,open:null}),this.modal.subscribe(((e,t)=>{e}))}toggleModal(e,t=!0){this.fields.get(e)&&(t?this.openModal(e):this.closeModal())}openModal(e){const t=this.fields.get(e);if(!t)return;this.setField(e),this.ui.modal.title.textContent=`Select ${t.plural}`,this.ui.search.container&&(this.ui.search.container.hidden=!t.canSearch),this.creator&&this.creator.handleOpen(t);let s=`Opened ${t.singular} selection. Choose from checkboxes, or search to filter results.`;window.removeChildren(this.ui.terms.list),this.modal.handleOpen(),this.a11y.announce(s)}closeModal(){this.modal.handleClose();const e=this.fields.get(this.activeField);if(!e)return;this.observer.unobserve(this.ui.terms.sentinel),window.removeChildren(this.ui.terms.list),this.notify("selected-terms",{terms:this.selectedTerms.get(this.activeField),taxonomy:e.taxonomy}),this.activeField=null;let t=`Closed ${e.singular} selector.`;this.a11y.announce(t)}navigateToParent(){const e=this.store.filters.parent;if(0===e)return;let t=this.store.get(parseInt(e));if(!t)return void this.navigateTo(0);let s=t.parent;this.navigateTo(parseInt(s))}navigateTo(e=0){e=parseInt(e)??0,this.store.setFilters({parent:e,page:1}),window.removeChildren(this.ui.terms.list),this.updateBreadcrumbs(e)}nextPage(){let e=this.store.filters.page,t=Math.min(e++,this.store.lastResponse.total);this.store.setFilters({page:t})}prevPage(){let e=this.store.filters.page,t=Math.max(e-1,1);this.store.setFilters({page:t})}addTermToModal(e){const t=this.store.get(e);if(!t)return;const s=this.currentField();if(!s)return;if(this.ui.selected.querySelector(`[data-id="${e}"]`))return;const i=window.getTemplate("selectedTerm");i&&(i.dataset.id=e,i.dataset.taxonomy=s.taxonomy,i.querySelector(".item-name").textContent=t.path,i.querySelector("button").title=`Remove ${t.name}`,this.ui.selected.append(i))}scanExistingFields(e=document.body){e.querySelectorAll('[data-type="selector"]').forEach((e=>{try{this.registerField(e)}catch(t){this.error.log(t,{component:"TaxonomySelector",action:"scanExistingFields",container:e.dataset.name})}}))}registerField(e,t={}){let s=e.querySelector('input[type="hidden"]');if(!s)return void console.warn("TaxonomySelector: No hidden input found for field",e);"fieldId"in e.dataset||(e.dataset.fieldId=window.generateID("selector"));const i=e.dataset.fieldId;let r=this.selectors.field,a=e.querySelector("button.taxonomy-toggle");if(0===Object.keys(t).length){if(!a)return;if(t={taxonomy:a.dataset.taxonomy,single:a.dataset.single,plural:a.dataset.plural,search:Object.hasOwn(a.dataset,"search"),autocomplete:Object.hasOwn(a.dataset,"autocomplete"),creatable:Object.hasOwn(a.dataset,"creatable")},0===Object.keys(t).length)return}else Object.hasOwn(t,"toggle")&&(a=document.querySelector(t.toggle),r.toggle=t.toggle);const n={id:i,value:s,element:e,taxonomy:t.taxonomy??!1,singular:t.single??"",plural:t.plural??"",name:e.dataset.field,canSearch:t.search??!1,limit:t.limit??0,hasAutocomplete:t.autocomplete??!1,canCreate:t.creatable??!1,isRequired:t.required??!1,toggle:a,create:{button:null,span:null},selectors:r,ui:window.uiFromSelectors(r,e),checked:!1};if(n.taxonomy)return n.singular&&n.plural||(console.warn("TaxonomySelector: Field missing singular/plural labels",e),n.singular=n.taxonomy.replace("jvb_",""),n.plural=n.singular+"s"),this.fields.set(i,n),this.setSelectedFromValue(i,s),this.isInitializing&&this.batchFetch.add(n.taxonomy),this.updateFieldUI(i),i;console.error("TaxonomySelector: Field missing taxonomy",e)}setSelectedFromValue(e,t){if(!t)return;if(!e)return;if(!this.fields.get(e))return;let s=new Set;t.value.trim().split(",").map((e=>parseInt(e.trim()))).filter((e=>!isNaN(e))).forEach((e=>s.add(e))),this.selectedTerms.set(e,s)}addSelected(e,t=null){t||(t=this.activeField);const s=this.fields.get(t),i=this.store.get(e);if(!s||!i)return;const r=this.selectedTerms.get(t);0!==s.limit&&r.size>=s.limit||(r.add(parseInt(e)),this.container.open||this.updateFieldValue(t),this.addTermToDisplay(e,t),this.checkLimits(t))}removeSelected(e,t=null){t||(t=this.activeField);const s=this.fields.get(t),i=this.store.get(e);if(!s||!i)return;this.selectedTerms.get(t).delete(parseInt(e));const r=s.ui.selected.querySelector(`[data-id="${e}"]`);if(r&&r.remove(),this.container.open){let t=this.ui.selected.querySelector(`[data-id="${e}"]`);t&&t.remove();let s=this.ui.terms.list.querySelector(`[type=checkbox][data-id="${e}"]`);s&&(s.checked=!1)}this.container.open||this.updateFieldValue(t),this.checkLimits(t)}updateFieldValue(e){const t=this.fields.get(e);if(!t)return;let s=Array.from(this.selectedTerms.get(e));t.ui.value.value=s.join(",")}checkLimits(e){if(!this.container.open)return;const t=this.fields.get(e);if(!t||0===t.limit)return;const s=this.selectedTerms.get(e).size>=t.limit;this.setCheckboxes(s)}updateFieldFromInput(e){const t=this.getFieldId(e);if(!t)return;this.fields.get(t)&&(this.setSelectedFromValue(t,e),this.updateFieldUI(t))}updateFieldUI(e){const t=this.fields.get(e);let s=this.selectedTerms.get(e)??new Set;t&&0!==s.size&&Array.from(s).forEach((t=>{this.addTermToDisplay(t,e)}))}updateFieldsForTaxonomy(e){let t=Array.from(this.fields.values()).filter((t=>!t.checked&&t.taxonomy===e));const s=Array.from(this.store.data.values()).some((t=>t.taxonomy===e));t.forEach((e=>{e.ui.toggle.disabled=!s&&!e.canCreate,e.ui.toggle.title=s?`Select ${e.plural}`:`No ${e.singular} available`,e.checked=!0}))}showModalTerms(e=!1){const t=this.currentField(),s=this.store.getFiltered();0===s.length&&((this.store.filters.page??1)&&window.removeChildren(this.ui.terms.list),this.setMessage(!0,""===this.store.filters.search?`No matching ${t.plural}.`:`No ${t.plural} found.`,!1),this.ui.terms.sentinel&&this.observer.unobserve(this.ui.terms.sentinel)),this.ui.terms.sentinel&&(this.store.lastResponse?.has_more?this.observer.observe(this.ui.terms.sentinel):this.observer.unobserve(this.ui.terms.sentinel));const i=this.store.filters.parent??0;this.ui.nav.back.hidden=0===i;const r=document.createDocumentFragment();s.forEach((t=>{const s=this.createTermElement({show:e,...t});s&&r.append(s)})),this.setMessage(!1),this.ui.terms.list.append(r)}createTermElement(e){if(!e||!e.name)return null;const t=window.getTemplate("termListItem");t.dataset.id=e.id;const s=this.selectedTerms.get(this.activeField).has(e.id);let[i,r,a]=[t.querySelector("input"),t.querySelector("label"),t.querySelector("span, .term-name")],n=this.currentField(),o=n.limit>0&&this.selectedTerms.get(this.activeField).size>=n.limit;if(i&&r&&a&&([i.dataset.id,i.id,i.name,i.value,i.disabled,i.checked,r.htmlFor,r.title,r.dataset.path,a.textContent]=[e.id,`${n.element.id}-${e.id}`,`${n.element.id}-${n.taxonomy}-select`,e.id,!s&&o,s,`${n.element.id}-${e.id}`,e.path??e.name,e.path,e.show?e.path:e.name],e.hasChildren)){const s=window.getTemplate("termChildrenToggle");s&&(s.ariaLabel=`View ${n.plural} nested under ${e.name}`,t.append(s))}return t}showAutocompleteTerms(){const e=this.currentField(),t=this.currentTerms();if(!e)return;const s=e.ui.dropdown.list;s&&(window.removeChildren(s),0===t.length?this.setMessage(!0,`No ${e.plural} found.`,!1):(t.forEach((e=>{const t=this.createAutocompleteTerm(e);t&&s.append(t)})),this.setMessage(!1)),this.setCreateButton(!0),e.ui.dropdown?.wrapper&&(e.ui.dropdown.wrapper.hidden=!1))}createAutocompleteTerm(e){const t=window.getTemplate("autocompleteItem");if(t)return t.dataset.id=e.id,t.textContent=e.path||e.name,t}addTermToDisplay(e,t){const s=this.store.get(e),i=this.fields.get(t);if(!s||!i)return;if(i.ui.selected.querySelector(`[data-id="${e}"]`))return;const r=window.getTemplate("selectedTerm");if(r&&(r.dataset.id=e,r.dataset.taxonomy=i.taxonomy,r.querySelector(".item-name").textContent=s.path,r.querySelector("button").title=`Remove ${s.name}`,i.ui.selected.append(r),this.container.open)){this.addTermToModal(e);const t=this.ui.terms.list.querySelector(`input[value="${e}"]`);t&&(t.checked=!0)}}updateBreadcrumbs(e){const t=this.ui.nav.nav;if(!t)return;const s=Array.from(t.children).find((t=>parseInt(t.dataset.id)===e));if(s){let e=s.nextElementSibling;for(;e;){const t=e;e=e.nextElementSibling,t.remove()}}else{const s=this.store.get(e);if(!s)return;const i=window.getTemplate("termBreadcrumb");if(!i)return;i.dataset.id=e,i.textContent=s.name,i.title=s.name,t.append(i)}}updateSelectionCount(){if(!this.container.open)return;const e=this.fields.get(this.activeField);if(e&&this.ui.modal.count){const t=this.selectedTerms.get(this.activeField).size;this.ui.modal.count.textContent=e.limit>0?`${t} of ${e.limit} ${e.plural} selected`:`${t} ${e.plural} selected`}}currentField(){return this.fields.get(this.activeField)??!1}currentTerms(){return this.store.getFiltered()}needsCreator(){return Array.from(this.fields.values()).some((e=>e.canCreate||e.hasAutocomplete))}getFieldId(e){if(e.dataset.fieldId)return e.dataset.fieldId;const t=e.closest("[data-field-id]");return t?.dataset.fieldId||null}setCheckboxes(e){this.ui.terms.list.querySelectorAll("input[type=checkbox]").forEach((t=>{t.checked||(t.disabled=e)}))}handleStoreEvent(e,t){const s={"data-loaded":()=>this.handleDataLoaded(),"filters-changed":()=>this.handleFiltersChanged(t),"fetch-error":()=>this.handleFetchError()};try{s[e]?.(t)}catch(t){console.error(`Error handling store event "${e}":`,t),this.setMessage(!0,"An error occurred loading data",!1)}}handleDataLoaded(){const e=this.store.filters.taxonomy;if(e?.includes(",")){e.split(",").map((e=>e.trim())).forEach((e=>this.updateFieldsForTaxonomy(e)))}this.container.open?this.showResults():this.activeField?this.showResults(!0):this.setMessage(!1)}showResults(e=!1){this.setMessage(!1);const t=this.store.getFiltered(),s=this.store.filters,i=s.search&&s.search.length>0;this.notify("terms-loaded",{terms:t,filters:s}),e?this.showAutocompleteTerms():this.showModalTerms(i),this.a11y.announce(t.length)}handleFiltersChanged(e){}handleFetchError(e){const t=this.currentField(),s=t?`Failed to load ${t.plural}`:"Failed to load data";this.setMessage(!0,s,!1),console.error("Store fetch error:",e)}async batchFetchTaxonomies(){if(0===this.batchFetch.size)return;const e=Array.from(this.batchFetch);this.batchFetch.clear();try{await this.store.setFilters({taxonomy:e.join(","),page:1,search:"",parent:0})}catch(e){console.error("Failed to batch fetch taxonomies:",e)}}preloadTaxonomy(e){this.store.setFilters({taxonomy:e,page:1,search:"",parent:0})}setCreateButton(e=!0){const t=this.currentField();if(!t||!t.canCreate||!this.creator)return;const s=this.container.open?this.ui:t.ui;if(!s.create?.button||!s.create?.span)return;const i=s.create.button,r=s.create.span,a=this.container.open?s.search.input:s.search;if(!a)return;let n=(this.currentTerms()??[]).map((e=>e.name)),o=a.value;const l=e&&o.length>=2&&!n.includes(o);i.hidden=!l,l&&(r.textContent=a.value??"")}async maybeCreateTerm(e){const t=this.currentField();if(!t)return;window.debouncer.cancel(`${t.id}-search-results`);let s={taxonomy:t.taxonomy,parent:this.store.filters.parent??0};if(this.container.open&&""===this.ui.search.input.value?(s.parent=this.creator.ui.parent.value??s.parent,s.name=this.creator.ui.name.value??!1):s.name=this.container.open?this.ui.search.input.value:t.ui.search.value,void 0!==s.parent&&s.name){this.setMessage(!0,`Creating "${s.name}"...`),this.setCreateButton(!1),this.container.open?window.removeChildren(this.ui.terms.list):(t.ui.search.disabled=!0,window.removeChildren(t.ui.dropdown.list),t.ui.dropdown.wrapper&&(t.ui.dropdown.wrapper.hidden=!1));let e=await this.creator.handleTermCreation(s);e&&this.addSelected(e.id,t.id),this.container.open||(t.ui.search.disabled=!1,t.ui.search.value=""),this.scheduleHideDropdown(t.id),this.setMessage(!1)}}setMessage(e=!0,t="",s=!0){const i=this.currentField();if(!i)return;t=""===t?`No ${i.plural??"items"} found.`:t;const r=this.container.open?this.ui:i.ui,a=r.message.message,n=r.message.text;a.hidden=!e,e?t&&n&&(s&&window.typeLoop&&n?(this.messageText[i.id]&&(this.messageText[i.id](),delete this.messageText[i.id]),this.messageText[i.id]=window.typeLoop(n,t)):n.textContent=t):this.messageText[i.id]&&(this.messageText[i.id](),delete this.messageText[i.id])}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t={}){this.subscribers.forEach((s=>{try{s(e,t)}catch(e){console.error("Subscriber error:",e)}}))}destroy(){this.fields.forEach(((e,t)=>{window.debouncer.cancel(`${t}-search`),window.debouncer.cancel(`${t}-search-results`)})),Object.keys(this.messageText).forEach((e=>{this.messageText[e]&&this.messageText[e]()})),this.messageText={},this.ui.terms?.sentinel&&this.observer?.unobserve(this.ui.terms.sentinel),this.observer?.disconnect(),document.removeEventListener("click",this.clickHandler),document.removeEventListener("change",this.changeHandler),document.removeEventListener("input",this.inputHandler),document.removeEventListener("focus",this.focusHandler,!0),document.removeEventListener("blur",this.blurHandler,!0),this.subscribers.clear(),this.fields.clear(),this.selectedTerms.clear(),this.batchFetch.clear(),this.creator&&(this.creator.destroy(),this.creator=null),this.store&&(this.store=null)}}document.addEventListener("DOMContentLoaded",(function(){window.auth.subscribe((t=>{"auth-loaded"===t&&(window.jvbSelector=new e)}))}))})();