// /** // * PostSelector Extension for TaxonomySelector // * Handles post selection using the same modal system as taxonomy selection // */ // // // Extend the TaxonomySelector to handle post selection // class PostSelectorExtension { // constructor(selector) { // this.selector = selector; // this.initPostHandling(); // } // // /** // * Initialize post-specific handling // */ // initPostHandling() { // // Override specific methods for post handling // this.originalFetchTerms = this.selector.fetchTerms.bind(this.selector); // this.originalBuildRequest = this.selector.buildRequest.bind(this.selector); // this.originalCreateTermElement = this.selector.createTermElement.bind(this.selector); // this.originalUpdateModalForTaxonomy = this.selector.updateModalForTaxonomy.bind(this.selector); // // // Replace methods with post-aware versions // this.selector.fetchTerms = this.fetchPosts.bind(this); // this.selector.buildRequest = this.buildPostRequest.bind(this); // this.selector.createTermElement = this.createPostElement.bind(this); // this.selector.updateModalForTaxonomy = this.updateModalForPosts.bind(this); // } // // /** // * Check if current field is a post selector // */ // isPostSelector() { // return this.selector.currentConfig?.taxonomy === 'post_selector'; // } // // /** // * Fetch posts instead of terms // */ // async fetchPosts(fieldId, forceRefresh = false, isSearch = false) { // if (!this.isPostSelector()) { // return this.originalFetchTerms(fieldId, forceRefresh, isSearch); // } // // if (this.selector.isLoading || !fieldId) return; // // const field = this.selector.fields.get(fieldId); // if (!field) return; // // try { // this.selector.showLoading(); // // const requestUrl = `${jvbSettings.api}posts/search?${this.buildPostRequest()}`; // // const response = await this.selector.cache.fetchWithCache(requestUrl, { // method: 'GET', // headers: { // 'Content-Type': 'application/json', // 'X-WP-Nonce': window.auth.getNonce() // } // }, { // content: `posts_${this.selector.currentConfig.postType}`, // forceRefresh: forceRefresh // }); // // if (response && response.terms && response.terms.length !== 0) { // this.selector.hasMore = response.pagination?.has_more || false; // this.renderPosts(response.terms, this.selector.page > 1, isSearch); // // if (this.selector.hasMore) { // this.selector.nextPage(); // } // } else { // if (this.selector.page === 1) { // this.selector.showEmptyState('No posts found'); // } // this.selector.hasMore = false; // } // // return response.terms || []; // } catch (error) { // this.selector.handleError(error); // return []; // } finally { // this.selector.hideLoading(); // } // } // // /** // * Build request parameters for post search // */ // buildPostRequest() { // if (!this.isPostSelector()) { // return this.originalBuildRequest(); // } // // let params = new URLSearchParams({ // post_type: this.selector.currentConfig.postType || 'post', // search: this.selector.searchQuery, // page: this.selector.page // }); // // // Add shop_id if present (for excluding existing artists) // if (this.selector.currentConfig.shopId) { // params.append('shop_id', this.selector.currentConfig.shopId); // } // // return params.toString(); // } // // /** // * Render posts list (similar to renderTerms but for posts) // */ // renderPosts(posts, append = false, showPath = false) { // if (!append) { // window.removeChildren(this.selector.elements.termsList); // } // // if (posts.length === 0) { // if (!append) { // this.selector.showEmptyState('No posts found'); // } // this.selector.a11y?.announce(0, append); // return; // } // // // Posts don't have breadcrumbs, but we might show search info // this.updatePostNavigation(); // // for (const [index, post] of Object.entries(posts)) { // if (!post) continue; // // // Store post in global cache using post type as "taxonomy" // const postType = this.selector.currentConfig.postType; // if (!this.selector.terms.has(postType)) { // this.selector.terms.set(postType, new Map()); // } // this.selector.terms.get(postType).set(post.id, post); // // this.createPostElement({ // id: parseInt(post.id), // name: post.name || post.title, // title: post.title || post.name, // thumbnail: post.thumbnail, // city: post.city, // url: post.url, // hasChildren: false, // Posts don't have children // path: post.path || post.title || post.name, // show: showPath // }); // } // // this.selector.a11y?.announce(posts.length, append); // } // // /** // * Create individual post element (adapted from createTermElement) // */ // createPostElement(postData) { // if (!this.isPostSelector()) { // return this.originalCreateTermElement(postData); // } // // if (!postData || !postData.name) return; // // const listItem = window.getTemplate('postListItem') || window.getTemplate('termListItem'); // listItem.dataset.id = postData.id; // // const isSelected = this.selector.selectedTerms.has(postData.id); // const checkbox = listItem.querySelector('input'); // const label = listItem.querySelector('label'); // const nameSpan = listItem.querySelector('span, .term-name, .post-name'); // // if (checkbox && label && nameSpan) { // checkbox.id = `${this.selector.currentConfig.container.id}${postData.id}`; // checkbox.name = `${this.selector.currentConfig.container.id}post-select`; // checkbox.value = postData.id; // checkbox.disabled = !isSelected && this.selector.disabled; // checkbox.checked = isSelected; // // label.htmlFor = checkbox.id; // label.title = postData.path || postData.name; // label.dataset.path = postData.path; // // nameSpan.textContent = postData.show ? postData.path : postData.name; // } // // // Add post-specific elements (thumbnail, city, etc.) // this.enhancePostElement(listItem, postData); // // this.selector.elements.termsList.appendChild(listItem); // } // // /** // * Enhance post element with post-specific data // */ // enhancePostElement(listItem, postData) { // // Add thumbnail if available // if (postData.thumbnail) { // const label = listItem.querySelector('label'); // if (label) { // const thumbnail = document.createElement('img'); // thumbnail.src = postData.thumbnail; // thumbnail.alt = postData.name; // thumbnail.className = 'post-thumbnail'; // thumbnail.loading = 'lazy'; // label.insertBefore(thumbnail, label.firstChild); // } // } // // // Add city if available // if (postData.city) { // const nameSpan = listItem.querySelector('span, .term-name, .post-name'); // if (nameSpan) { // const citySpan = document.createElement('span'); // citySpan.className = 'post-city'; // citySpan.textContent = ` (${postData.city})`; // nameSpan.appendChild(citySpan); // } // } // // // Add post-specific CSS class // listItem.classList.add('post-item'); // } // // /** // * Update modal content for post selection // */ // updateModalForPosts() { // if (!this.isPostSelector()) { // return this.originalUpdateModalForTaxonomy(); // } // // const config = this.selector.currentConfig; // this.selector.elements.modalTitle.textContent = `Select ${config.plural || 'Posts'}`; // // // Always show search for posts (more important than for taxonomies) // const searchWrapper = this.selector.modal.querySelector('.search-wrapper'); // if (searchWrapper) { // searchWrapper.style.display = 'block'; // } // // // Never show create new for posts // if (this.selector.elements.createNewSection) { // this.selector.elements.createNewSection.style.display = 'none'; // this.selector.elements.createNewSection.hidden = true; // } // // // Hide breadcrumbs for posts (not hierarchical) // if (this.selector.elements.breadcrumbs) { // this.selector.elements.breadcrumbs.style.display = 'none'; // } // // const openMessage = `Opened ${config.singular || 'post'} selection. Search and choose from available posts.`; // this.selector.a11y?.announce(openMessage); // } // // /** // * Update navigation for posts (simpler than taxonomy breadcrumbs) // */ // updatePostNavigation() { // // Hide back button and breadcrumbs for posts // if (this.selector.elements.backButton) { // this.selector.elements.backButton.hidden = true; // } // // // Clear breadcrumbs container but keep the back button // const breadcrumbs = this.selector.elements.breadcrumbs; // if (breadcrumbs) { // // Remove all children except the back button // Array.from(breadcrumbs.children).forEach(child => { // if (!child.classList.contains('back-to-parent')) { // child.remove(); // } // }); // } // // // Show search info if searching // if (this.selector.searchQuery) { // const searchInfo = document.createElement('div'); // searchInfo.className = 'search-info'; // searchInfo.textContent = `Searching for: "${this.selector.searchQuery}"`; // this.selector.elements.termsList.insertBefore( // searchInfo, // this.selector.elements.termsList.firstChild // ); // } // } // // /** // * Clean up when destroyed // */ // destroy() { // // Restore original methods // if (this.originalFetchTerms) { // this.selector.fetchTerms = this.originalFetchTerms; // } // if (this.originalBuildRequest) { // this.selector.buildRequest = this.originalBuildRequest; // } // if (this.originalCreateTermElement) { // this.selector.createTermElement = this.originalCreateTermElement; // } // if (this.originalUpdateModalForTaxonomy) { // this.selector.updateModalForTaxonomy = this.originalUpdateModalForTaxonomy; // } // } // } // // // Extend TaxonomySelector to support post selection // document.addEventListener('DOMContentLoaded', function() { // if (window.jvbSelector) { // // Add post selector extension to the existing selector // window.jvbSelector.postExtension = new PostSelectorExtension(window.jvbSelector); // // console.log('PostSelector extension loaded'); // } // }); // // // Export for manual use // window.PostSelectorExtension = PostSelectorExtension;