Jake Vanderwerf
43 mins ago 3baf3d2545ba6ece6b74a64c0def59bd0774cf54
assets/js/concise/TaxonomyCreator.js
@@ -13,9 +13,9 @@
   initElements() {
      this.selectors = {
         details: 'details.create-new',
         details: 'details.create-term',
         parent: '#select_parent',
         summary: '.create-new summary',
         summary: '.create-term summary',
         suggestion: '.term-suggestions',
         name: '#term_name',
         button: '.submit-term',
@@ -29,6 +29,23 @@
      this.ui = window.uiFromSelectors(this.selectors, this.selector.container);
   }
   handleOpen(field) {
      this.field = field;
      if (this.ui.details) {
         this.ui.details.hidden = !field.canCreate;
         if (this.ui.summary) {
            this.ui.summary.textContent = `Add new ${field.singular}`;
         }
         if (this.ui.label.name) {
            this.ui.label.name.textContent = `Name this ${field.singular}`;
         }
         if (this.ui.label.parent) {
            this.ui.label.parent.textContent = `Nest it under`;
         }
      }
   }
   /**
    * Initialize event listeners
    */
@@ -40,7 +57,7 @@
         this.ui.form.addEventListener('change', (e) => {
            e.preventDefault();
            e.stopPropagation();
         })
         });
      }
   }
@@ -54,54 +71,48 @@
            this.ui.name?.focus();
         }
         this.resetParentOptions();
      }
      // Handle term creation submission
      if (window.targetCheck(e, this.selectors.button)) {
         this.handleTermCreation(e).then(() => {});
         return;
      }
   }
   /**
    * Handle term creation from modal form
    */
   async handleTermCreation(e) {
      let field = this.selector.currentField();
      const taxonomy = field.taxonomy;
      if (!taxonomy) return;
      let data = {
         parent: 0,
         taxonomy: taxonomy
      };
      // If it's open, we can get the parent element and everything
      if (this.selector.container.open) {
         data.name = this.ui.name.value.trim();
         data.parent = parseInt(this.ui.parent?.value??0);
      } else if (this.selector.activeField) {
         //It's autocomplete, so just the term name
         data.name = this.selector.store.query;
      }
      if (!data.name || data.name.length < 2) return;
   async handleTermCreation(data) {
      if (!data.name || data.name.length < 2) return false;
      try {
         if (this.ui.button) {
            this.ui.button.disabled = true;
         }
         const response = await this.createTerm(data);
         let currentField = this.selector.currentField();
         if (!response.success) {
            // Term already exists - still add it
            if (response.term && response.term.id) {
               this.selector.setMessage(currentField,true, `Using existing "${response.term.name}"`);
               return response.term;
            }
            // Other failure
            this.selector.setMessage(currentField,true, response.message || 'Creation failed', false);
            return false;
         }
         if (response.term?.pending) {
            // Term requires approval
            this.selector.setMessage(
               currentField,
               true,
               `"${data.name}" submitted for approval`,
               false
            );
            // Don't add to selection since it's pending
            return false;
         }
         if (response.success && response.term) {
            await this.handleSuccessfulCreation(response.term, data);
            this.clearForm();
         }
         return response.term;
      } catch (error) {
         console.error('Error creating term:', error);
         this.selector.handleError(error, 'handleTermCreation');
      } finally {
         if (this.ui.button) {
            this.ui.button.disabled = false;
         }
         return false;
      }
   }
@@ -109,40 +120,32 @@
    * Handle successful term creation
    */
   async handleSuccessfulCreation(term, data) {
      const termPath = term.path || term.name;
      // Close create form
      this.ui.details.open = false;
      // Clear cache to ensure fresh data
      await this.selector.store.clearCache();
      // Add to DataStore
      this.selector.store.data.set(term.id, {
      // Add term to store immediately - don't wait for fetch
      const fullTerm = {
         id: term.id,
         name: term.name,
         path: termPath,
         path: term.path || term.name,
         slug: term.slug || term.name.toLowerCase().replace(/\s+/g, '-'),
         parent: data.parent || 0,
         taxonomy: data.taxonomy,
         parent: data.parent,
         count: 0,
         hasChildren: false,
         slug: term.slug || term.name.toLowerCase().replace(/\s+/g, '-')
      });
         hasChildren: false
      };
      // Add to modal selection
      this.selector.addSelected(term.id,this.selector.activeField);
      // Add to store data immediately so addSelected can find it
      this.selector.store.data.set(term.id, fullTerm);
      // Refresh current view if we're viewing the same parent
      if (this.selector.container.open) {
         const currentParent = this.selector.store.filters.parent || 0;
         if (currentParent === data.parent) {
            await this.selector.store.setFilters({
               taxonomy: data.taxonomy,
               parent: data.parent,
               page: 1,
               search: ''
            });
         }
      // Close create form
      if (this.ui.details) {
         this.ui.details.open = false;
      }
      // Clear cache and refetch in background for accuracy
      this.selector.store.clearCache();
      // Don't await - let it happen async
      this.selector.store.fetch().catch(err => {
         console.warn('Background fetch after term creation failed:', err);
      });
   }
   /**
@@ -233,6 +236,9 @@
      if (this.ui.name) {
         this.ui.name.value = '';
      }
      if (this.selector.ui.search.input){
         this.selector.ui.search.input.value = '';
      }
   }
   /**