| @@ -22,9 +22,62 @@ | ||
| 22 | 22 | action: "connect_products_with_basalam", |
| 23 | 23 | }, |
| 24 | 24 | ]; |
| 25 | 25 | |
| 26 | + const updateModal = document.getElementById("BasalamUpdateProductsModal"); | |
| 27 | + let updateStatusPoller = null; | |
| 28 | + let updateStatusInFlight = false; | |
| 29 | + | |
| 30 | + const showUpdatePanel = (panelId) => { | |
| 31 | + ["update-status-loading", "update-status-error", "update-type-selection", "quick-update-in-progress", "active-jobs-info"].forEach((id) => { | |
| 32 | + const panel = document.getElementById(id); | |
| 33 | + if (panel) panel.hidden = id !== panelId; | |
| 34 | + }); | |
| 35 | + }; | |
| 36 | + | |
| 37 | + const refreshUpdateStatus = () => { | |
| 38 | + if (!updateModal || !document.getElementById("update-type-selection") || updateStatusInFlight) return; | |
| 39 | + | |
| 40 | + updateStatusInFlight = true; | |
| 41 | + const formData = new FormData(); | |
| 42 | + formData.append("action", "get_update_queue_status"); | |
| 43 | + formData.append("_wpnonce", updateModal.dataset.statusNonce || ""); | |
| 44 | + | |
| 45 | + return fetch(ajaxurl, { method: "POST", body: formData, cache: "no-store" }) | |
| 46 | + .then((response) => response.json()) | |
| 47 | + .then((response) => { | |
| 48 | + if (!response.success || !response.data) throw new Error("Update status unavailable"); | |
| 49 | + | |
| 50 | + const status = response.data; | |
| 51 | + if (!status.active) { | |
| 52 | + showUpdatePanel("update-type-selection"); | |
| 53 | + } else if (status.type === "quick") { | |
| 54 | + const badge = document.getElementById("quick-update-status"); | |
| 55 | + if (badge) badge.textContent = status.status === "processing" ? "در حال پردازش" : "در انتظار"; | |
| 56 | + showUpdatePanel("quick-update-in-progress"); | |
| 57 | + } else { | |
| 58 | + const count = Number(status.count) || 0; | |
| 59 | + const countRow = document.getElementById("update-queue-count-row"); | |
| 60 | + const countBadge = document.getElementById("update-queue-count"); | |
| 61 | + if (countRow) countRow.hidden = count === 0; | |
| 62 | + if (countBadge) countBadge.textContent = `${count} محصول`; | |
| 63 | + showUpdatePanel("active-jobs-info"); | |
| 64 | + } | |
| 65 | + }) | |
| 66 | + .catch((error) => { | |
| 67 | + console.error("Error fetching product update status:", error); | |
| 68 | + showUpdatePanel("update-status-error"); | |
| 69 | + }) | |
| 70 | + .finally(() => { | |
| 71 | + updateStatusInFlight = false; | |
| 72 | + }); | |
| 73 | + }; | |
| 74 | + | |
| 26 | 75 | const closeModal = () => { |
| 76 | + if (updateStatusPoller) { | |
| 77 | + clearInterval(updateStatusPoller); | |
| 78 | + updateStatusPoller = null; | |
| 79 | + } | |
| 27 | 80 | document.querySelectorAll(".basalam-modal").forEach((modal) => { |
| 28 | 81 | modal.style.display = "none"; |
| 29 | 82 | }); |
| 30 | 83 | document.body.style.overflow = "auto"; |
| @@ -40,15 +93,14 @@ | ||
| 40 | 93 | modal.style.display = "block"; |
| 41 | 94 | document.body.style.overflow = "hidden"; |
| 42 | 95 | |
| 43 | 96 | if (modalId === "BasalamUpdateProductsModal") { |
| 44 | - const selectionDiv = document.getElementById("update-type-selection"); | |
| 45 | - const quickConfirm = document.getElementById("quick-update-confirm"); | |
| 46 | - const fullConfirm = document.getElementById("full-update-confirm"); | |
| 47 | - | |
| 48 | - if (selectionDiv) selectionDiv.style.display = "block"; | |
| 49 | - if (quickConfirm) quickConfirm.style.display = "none"; | |
| 50 | - if (fullConfirm) fullConfirm.style.display = "none"; | |
| 97 | + if (document.getElementById("update-type-selection")) { | |
| 98 | + showUpdatePanel("update-status-loading"); | |
| 99 | + refreshUpdateStatus(); | |
| 100 | + if (updateStatusPoller) clearInterval(updateStatusPoller); | |
| 101 | + updateStatusPoller = setInterval(refreshUpdateStatus, 5000); | |
| 102 | + } | |
| 51 | 103 | } |
| 52 | 104 | }); |
| 53 | 105 | } |
| 54 | 106 | |
| @@ -77,8 +129,13 @@ | ||
| 77 | 129 | }); |
| 78 | 130 | } |
| 79 | 131 | }); |
| 80 | 132 | |
| 133 | + document.getElementById("update-status-retry")?.addEventListener("click", () => { | |
| 134 | + showUpdatePanel("update-status-loading"); | |
| 135 | + refreshUpdateStatus(); | |
| 136 | + }); | |
| 137 | + | |
| 81 | 138 | setTimeout(() => { |
| 82 | 139 | const quickUpdateBtn = document.getElementById("quick-update-btn"); |
| 83 | 140 | const fullUpdateBtn = document.getElementById("full-update-btn"); |
| 84 | 141 | |
| @@ -208,14 +265,45 @@ | ||
| 208 | 265 | }); |
| 209 | 266 | |
| 210 | 267 | const select = document.getElementById("basalam-sync-type"); |
| 211 | 268 | if (select) { |
| 269 | + const customFields = document.getElementById("Basalam-custom-fields"); | |
| 270 | + const settingsForm = select.closest("form"); | |
| 271 | + const validationMessage = | |
| 272 | + "در حالت سفارشی باید حداقل یک فیلد را برای بروزرسانی انتخاب کنید."; | |
| 273 | + | |
| 212 | 274 | const toggleFields = (val) => { |
| 213 | - document.getElementById("Basalam-custom-fields").style.display = | |
| 214 | - val === "custom" ? "block" : "none"; | |
| 275 | + if (customFields) { | |
| 276 | + customFields.style.display = val === "custom" ? "block" : "none"; | |
| 277 | + } | |
| 215 | 278 | }; |
| 279 | + | |
| 280 | + const hasSelectedCustomField = () => | |
| 281 | + customFields && | |
| 282 | + Array.from( | |
| 283 | + customFields.querySelectorAll('input[type="checkbox"]') | |
| 284 | + ).some((checkbox) => checkbox.checked); | |
| 285 | + | |
| 216 | 286 | toggleFields(select.value); |
| 217 | 287 | select.addEventListener("change", (e) => toggleFields(e.target.value)); |
| 288 | + | |
| 289 | + if (settingsForm) { | |
| 290 | + settingsForm.addEventListener("submit", (event) => { | |
| 291 | + if (select.value !== "custom" || hasSelectedCustomField()) return; | |
| 292 | + | |
| 293 | + event.preventDefault(); | |
| 294 | + event.stopImmediatePropagation(); | |
| 295 | + | |
| 296 | + if (window.BasalamToast) { | |
| 297 | + window.BasalamToast.error(validationMessage); | |
| 298 | + } | |
| 299 | + | |
| 300 | + if (customFields) { | |
| 301 | + customFields.scrollIntoView({ behavior: "smooth", block: "center" }); | |
| 302 | + customFields.querySelector('input[type="checkbox"]')?.focus(); | |
| 303 | + } | |
| 304 | + }, true); | |
| 305 | + } | |
| 218 | 306 | } |
| 219 | 307 | |
| 220 | 308 | // Tab functionality for settings modal |
| 221 | 309 | const initTabs = () => { |