admin-menu.js
3 months ago
documentation.js
3 months ago
import.js
3 months ago
settings.js
3 months ago
support.js
3 months ago
import.js
298 lines
| 1 | jQuery( document ).ready( function( $ ) { |
| 2 | |
| 3 | // Dirty state tracking |
| 4 | const saveReminder = $( '#helpdocs-save-reminder' ); |
| 5 | let isDirty = false; |
| 6 | |
| 7 | function markDirty() { |
| 8 | if ( ! isDirty ) { |
| 9 | isDirty = true; |
| 10 | saveReminder.fadeIn( 150 ); |
| 11 | } |
| 12 | } |
| 13 | |
| 14 | $( window ).on( 'beforeunload', function( e ) { |
| 15 | if( isDirty ){ |
| 16 | e.preventDefault(); |
| 17 | e.returnValue = ''; |
| 18 | return ''; |
| 19 | } |
| 20 | }); |
| 21 | |
| 22 | $( document ).on( 'change input', '#helpdocs_import_active, #helpdocs_import_title, #helpdocs_website_url, #helpdocs_imports_table input[type="checkbox"]', function() { |
| 23 | markDirty(); |
| 24 | }); |
| 25 | |
| 26 | // Hide the "Don't forget to activate" notice when the toggle is changed |
| 27 | $( '#helpdocs_import_active' ).on( 'change', function() { |
| 28 | const isActive = $( this ).is( ':checked' ); |
| 29 | $( '#helpdocs-inactive-notice' ).toggle( ! isActive ); |
| 30 | } ); |
| 31 | |
| 32 | // Saving |
| 33 | const saveButton = $( '#header_btn_save_import_settings' ); |
| 34 | const urlInput = $( '#helpdocs_website_url' ); |
| 35 | |
| 36 | function validateSave() { |
| 37 | if ( urlInput.val().trim() === '' ) { |
| 38 | saveButton.prop( 'disabled', true ); |
| 39 | } else { |
| 40 | saveButton.prop( 'disabled', false ); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | validateSave(); |
| 45 | |
| 46 | urlInput.on( 'input change', function() { |
| 47 | validateSave(); |
| 48 | }); |
| 49 | |
| 50 | function startSavingTitle() { |
| 51 | let dots = 0; |
| 52 | |
| 53 | document.title = helpdocs_import.saving_text; // immediate first update |
| 54 | |
| 55 | setInterval( function() { |
| 56 | dots = (dots + 1) % 4; // cycles 0 → 3 |
| 57 | document.title = helpdocs_import.saving_text + '.'.repeat(dots); |
| 58 | }, 500 ); |
| 59 | } |
| 60 | |
| 61 | function showSaving() { |
| 62 | saveButton.prop( 'disabled', true ).html( '<span class="dashicons dashicons-update spin"></span> ' + helpdocs_import.saving_text + '...' ); |
| 63 | } |
| 64 | |
| 65 | function saveSettings() { |
| 66 | if ( saveButton.prop( 'disabled' ) ) { |
| 67 | return; |
| 68 | } |
| 69 | |
| 70 | startSavingTitle(); |
| 71 | showSaving(); |
| 72 | isDirty = false; |
| 73 | $( '#helpdocs_import_form' ).submit(); |
| 74 | } |
| 75 | |
| 76 | saveButton.on( 'click', saveSettings ); |
| 77 | |
| 78 | $( document ).on( 'keydown', function( e ) { |
| 79 | if ( ( e.ctrlKey || e.metaKey ) && e.key.toLowerCase() === 's' ) { |
| 80 | e.preventDefault(); |
| 81 | saveSettings(); |
| 82 | } |
| 83 | } ); |
| 84 | |
| 85 | const successMsg = $( '#helpdocs-saved-success' ); |
| 86 | if ( successMsg.is( ':visible' ) ) { |
| 87 | setTimeout( function() { |
| 88 | successMsg.fadeOut( 500 ); |
| 89 | }, 5000 ); |
| 90 | |
| 91 | const url = new URL( window.location.href ); |
| 92 | if ( url.searchParams.has( 'import-updated' ) ) { |
| 93 | url.searchParams.delete( 'import-updated' ); |
| 94 | window.history.replaceState( {}, document.title, url.pathname + url.search + url.hash ); |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | // Select All Buttons |
| 99 | $( '.helpdocs-select-all-toggle' ).on( 'click', function( e ) { |
| 100 | e.preventDefault(); |
| 101 | const type = $( this ).data( 'type' ); // 'feed' or 'toc' |
| 102 | const checkboxes = $( '.' + type + '-checkbox' ); |
| 103 | |
| 104 | // Determine if we should check all or uncheck all |
| 105 | const anyUnchecked = checkboxes.filter( ':not(:checked)' ).length > 0; |
| 106 | |
| 107 | checkboxes.prop( 'checked', anyUnchecked ); |
| 108 | markDirty(); |
| 109 | } ); |
| 110 | |
| 111 | // "Feed All" and "TOC All" Logic |
| 112 | const feedAll = $( '#helpdocs_all' ); |
| 113 | const tocAll = $( '#helpdocs_all_tocs' ); |
| 114 | const tocAllWrap = $( '#helpdocs_all_tocs_container' ); |
| 115 | const table = $( '#helpdocs_imports_table' ); |
| 116 | |
| 117 | function syncTableState() { |
| 118 | const isFeedAllChecked = feedAll.is( ':checked' ); |
| 119 | const isTocAllChecked = tocAll.is( ':checked' ); |
| 120 | const feedCheckboxes = table.find( '.feed-checkbox' ); |
| 121 | const tocCheckboxes = table.find( '.toc-checkbox' ); |
| 122 | |
| 123 | if ( isFeedAllChecked ) { |
| 124 | feedCheckboxes.each( function() { |
| 125 | const cb = $( this ); |
| 126 | if ( undefined === cb.data( 'prev-state' ) ) { |
| 127 | cb.data( 'prev-state', cb.is( ':checked' ) ); |
| 128 | } |
| 129 | } ); |
| 130 | |
| 131 | tocAllWrap.css( 'display', 'inline-flex' ); |
| 132 | feedCheckboxes.prop( 'checked', true ).prop( 'disabled', true ); |
| 133 | $( '.helpdocs-select-all-toggle' ).prop( 'disabled', true ).css( 'opacity', '0.5' ); |
| 134 | |
| 135 | if ( isTocAllChecked ) { |
| 136 | tocCheckboxes.prop( 'checked', true ).prop( 'disabled', true ); |
| 137 | } else { |
| 138 | tocCheckboxes.prop( 'disabled', true ); |
| 139 | } |
| 140 | } else { |
| 141 | tocAllWrap.hide(); |
| 142 | $( '.helpdocs-select-all-toggle' ).prop( 'disabled', false ).css( 'opacity', '1' ); |
| 143 | |
| 144 | feedCheckboxes.each( function() { |
| 145 | const cb = $( this ); |
| 146 | const prev = cb.data( 'prev-state' ); |
| 147 | if ( undefined !== prev ) { |
| 148 | cb.prop( 'checked', prev ); |
| 149 | } |
| 150 | cb.prop( 'disabled', false ); |
| 151 | } ); |
| 152 | |
| 153 | feedCheckboxes.removeData( 'prev-state' ); |
| 154 | tocCheckboxes.prop( 'disabled', false ); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | syncTableState(); |
| 159 | |
| 160 | feedAll.on( 'change', function() { |
| 161 | syncTableState(); |
| 162 | } ); |
| 163 | |
| 164 | tocAll.on( 'change', function() { |
| 165 | if ( ! $( this ).is( ':checked' ) && feedAll.is( ':checked' ) ) { |
| 166 | table.find( '.toc-checkbox' ).prop( 'checked', false ); |
| 167 | } |
| 168 | syncTableState(); |
| 169 | } ); |
| 170 | |
| 171 | // Trigger "Fetch" on Enter key in the URL field |
| 172 | $( '#helpdocs_website_url' ).on( 'keydown', function( e ) { |
| 173 | if ( e.key === 'Enter' ) { |
| 174 | e.preventDefault(); // Stop the form from saving |
| 175 | $( '#helpdocs_fetch_remote_docs' ).trigger( 'click' ); |
| 176 | } |
| 177 | } ); |
| 178 | |
| 179 | // Toggle API Key Visibility |
| 180 | $( document ).on( 'click', '.helpdocs-toggle-visibility', function() { |
| 181 | const $input = $( '#helpdocs_api_key' ); |
| 182 | const type = $input.attr( 'type' ) === 'password' ? 'text' : 'password'; |
| 183 | $input.attr( 'type', type ); |
| 184 | $( this ).toggleClass( 'dashicons-visibility dashicons-hidden' ); |
| 185 | } ); |
| 186 | |
| 187 | // Fetch Remote Docs |
| 188 | $( '#helpdocs_fetch_remote_docs' ).on( 'click', function( e ) { |
| 189 | e.preventDefault(); |
| 190 | |
| 191 | const $btn = $( this ); |
| 192 | const originalText = $btn.text(); |
| 193 | let url = $( '#helpdocs_website_url' ).val().trim(); |
| 194 | const apiKey = $( '#helpdocs_api_key' ).val().trim(); |
| 195 | |
| 196 | if ( ! url ) { |
| 197 | alert( 'Please enter a URL first.' ); |
| 198 | return; |
| 199 | } |
| 200 | |
| 201 | if ( ! /^https?:\/\//i.test( url ) ) { |
| 202 | url = 'https://' + url; |
| 203 | $( '#helpdocs_website_url' ).val( url ); |
| 204 | } |
| 205 | |
| 206 | // Reset UI state before fetching |
| 207 | $btn.addClass( 'disabled thinking' ).text( helpdocs_import.fetching_text ); |
| 208 | $( '#helpdocs_api_error, #helpdocs_connection_error, #helpdocs_no_docs_found' ).hide(); |
| 209 | |
| 210 | $.post( ajaxurl, { |
| 211 | action: 'helpdocs_fetch_remote_docs', |
| 212 | nonce: helpdocs_import.fetch_nonce, |
| 213 | url: url, |
| 214 | api_key: apiKey // Pass the key to PHP |
| 215 | }, function( response ) { |
| 216 | if ( response.success ) { |
| 217 | // Handle specific error codes returned in response.data |
| 218 | if ( response.data.error === 'unauthorized' ) { |
| 219 | $( '#helpdocs_api_error' ).fadeIn(); |
| 220 | $( '#helpdocs_remote_docs_wrapper' ).hide(); |
| 221 | } else if ( response.data.error === 'connection_failed' ) { |
| 222 | $( '#helpdocs_connection_error' ).fadeIn(); |
| 223 | $( '#helpdocs_remote_docs_wrapper' ).hide(); |
| 224 | } else { |
| 225 | // Success: Update the table |
| 226 | $( '#helpdocs_imports_table tbody' ).html( response.data.html ); |
| 227 | |
| 228 | const count = response.data.count; |
| 229 | const itemText = count === 1 ? ' item' : ' items'; |
| 230 | $( '.displaying-num' ).text( count + itemText ); |
| 231 | |
| 232 | const $notice = $( '#helpdocs_version_notice' ); |
| 233 | if ( response.data.version === 'v1' ) { |
| 234 | $notice.fadeIn(); |
| 235 | } else { |
| 236 | $notice.hide(); |
| 237 | } |
| 238 | |
| 239 | $( '#helpdocs_remote_docs_wrapper' ).fadeIn(); |
| 240 | } |
| 241 | } else { |
| 242 | // General failure (no docs or server error) |
| 243 | $( '#helpdocs_remote_docs_wrapper' ).hide(); |
| 244 | $( '#helpdocs_no_docs_found' ).fadeIn(); |
| 245 | |
| 246 | if ( response.data !== 'No documents found at this URL.' && ! response.data.error ) { |
| 247 | alert( response.data ); |
| 248 | } |
| 249 | } |
| 250 | $btn.removeClass( 'disabled thinking' ).text( originalText ); |
| 251 | } ); |
| 252 | } ); |
| 253 | |
| 254 | // Import Individual Docs |
| 255 | $( document ).on( 'click', '.helpdocs-clone-individual', function( e ) { |
| 256 | e.preventDefault(); |
| 257 | const $btn = $( this ); |
| 258 | const originalText = $btn.text(); |
| 259 | const docId = $btn.data( 'id' ); |
| 260 | const importId = $( '#helpdocs_imports_table' ).data( 'import-id' ); |
| 261 | const websiteUrl = $( '#helpdocs_website_url' ).val(); |
| 262 | const apiKey = $( '#helpdocs_api_key' ).val().trim(); |
| 263 | |
| 264 | if ( $btn.hasClass( 'updating-message' ) ) return; |
| 265 | |
| 266 | $btn.addClass( 'updating-message' ).addClass( 'thinking' ).text( helpdocs_import.importing_text ); |
| 267 | |
| 268 | $.ajax( { |
| 269 | url: ajaxurl, |
| 270 | type: 'POST', |
| 271 | data: { |
| 272 | action: 'helpdocs_import_individual_doc', |
| 273 | nonce: helpdocs_import.clone_nonce, |
| 274 | doc_id: docId, |
| 275 | import_id: importId, |
| 276 | website_url: websiteUrl, |
| 277 | api_key: apiKey |
| 278 | }, |
| 279 | success: function( response ) { |
| 280 | if ( response.success ) { |
| 281 | $btn.removeClass( 'button-secondary updating-message thinking' ) |
| 282 | .addClass( 'button-disabled' ) |
| 283 | .text( helpdocs_import.imported_text ) |
| 284 | .prop( 'disabled', true ); |
| 285 | } else { |
| 286 | alert( response.data || helpdocs_import.error_text ); |
| 287 | $btn.removeClass( 'updating-message thinking' ).text( originalText ); |
| 288 | } |
| 289 | }, |
| 290 | error: function( xhr, status, error ) { |
| 291 | console.error( xhr.responseText ); |
| 292 | alert( helpdocs_import.error_text + ' (Status: ' + status + ')' ); |
| 293 | $btn.removeClass( 'updating-message thinking' ).text( originalText ); |
| 294 | } |
| 295 | } ); |
| 296 | } ); |
| 297 | |
| 298 | } ); |