rails_modal_manager 1.0.44 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7dec9a40ef3da3620d41315569b51f9b0a3ac6a291bdd81edf77ca6271858464
|
|
4
|
+
data.tar.gz: 719e56407709affe6b21f781ad92cc5496f3ed1c13de711b6f4cbc3769915910
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 41af209ea06bad87c813444fe5a4e7ba074d685709d9f1dbf916e5dfbd983120d2445de1436bec01ee7b9d3b675084887824010e7ffce4704df4b0c4d74b3757
|
|
7
|
+
data.tar.gz: 14ed339f8138e4e4586f4b13d4fd078e570752bd92f2e7367d2d8c3b128dde332c12f755e7343be703e8810bf5f5f73abe623fbb25ccc740452befa6fc3bca65
|
|
@@ -297,6 +297,20 @@ export default class extends Controller {
|
|
|
297
297
|
const modal = this.element.closest('.rmm-modal')
|
|
298
298
|
if (!modal) return
|
|
299
299
|
|
|
300
|
+
// Invalidate any pending AJAX responses + abort network requests
|
|
301
|
+
const contentContainer = modal.querySelector('.rmm-tab-content')
|
|
302
|
+
if (contentContainer) {
|
|
303
|
+
// Increment shared counter to invalidate all pending responses
|
|
304
|
+
contentContainer.dataset.rmmRequestId = (parseInt(contentContainer.dataset.rmmRequestId || '0', 10) + 1)
|
|
305
|
+
}
|
|
306
|
+
modal.querySelectorAll('[data-controller*="rmm-submenu"]').forEach(el => {
|
|
307
|
+
const ctrl = this.application.getControllerForElementAndIdentifier(el, 'rmm-submenu')
|
|
308
|
+
if (ctrl && ctrl.currentAbortController) {
|
|
309
|
+
ctrl.currentAbortController.abort()
|
|
310
|
+
ctrl.currentAbortController = null
|
|
311
|
+
}
|
|
312
|
+
})
|
|
313
|
+
|
|
300
314
|
// Hide all submenu groups
|
|
301
315
|
modal.querySelectorAll('.rmm-submenu-group').forEach(group => {
|
|
302
316
|
group.classList.remove('rmm-submenu-group-active')
|
|
@@ -45,7 +45,6 @@ export default class extends Controller {
|
|
|
45
45
|
this.ajaxCache = new Map()
|
|
46
46
|
this.currentItemId = null
|
|
47
47
|
this.currentAbortController = null
|
|
48
|
-
this.currentRequestId = 0
|
|
49
48
|
|
|
50
49
|
// Find initial active item
|
|
51
50
|
const activeItem = this.element.querySelector('.rmm-submenu-item.rmm-active')
|
|
@@ -54,6 +53,19 @@ export default class extends Controller {
|
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Increment the shared request counter on the content container.
|
|
58
|
+
* Called synchronously from selectItem/forceReloadActive BEFORE async loadAjaxContent.
|
|
59
|
+
* This ensures any pending async response is immediately invalidated.
|
|
60
|
+
*/
|
|
61
|
+
_incrementRequestId() {
|
|
62
|
+
const modal = this.element.closest('.rmm-modal')
|
|
63
|
+
if (!modal) return
|
|
64
|
+
const container = modal.querySelector('.rmm-tab-content')
|
|
65
|
+
if (!container) return
|
|
66
|
+
container.dataset.rmmRequestId = (parseInt(container.dataset.rmmRequestId || '0', 10) + 1)
|
|
67
|
+
}
|
|
68
|
+
|
|
57
69
|
selectItem(e) {
|
|
58
70
|
const item = e.currentTarget
|
|
59
71
|
const itemId = item.dataset.itemId
|
|
@@ -75,6 +87,8 @@ export default class extends Controller {
|
|
|
75
87
|
|
|
76
88
|
// Handle content switching based on load mode
|
|
77
89
|
if (this.loadModeValue === 'ajax') {
|
|
90
|
+
// Synchronously invalidate any pending requests BEFORE starting new one
|
|
91
|
+
this._incrementRequestId()
|
|
78
92
|
this.loadAjaxContent(item)
|
|
79
93
|
} else {
|
|
80
94
|
this.switchPanel(item)
|
|
@@ -99,6 +113,8 @@ export default class extends Controller {
|
|
|
99
113
|
const activeItem = this.element.querySelector('.rmm-submenu-item.rmm-active')
|
|
100
114
|
if (activeItem) {
|
|
101
115
|
if (this.loadModeValue === 'ajax') {
|
|
116
|
+
// Synchronously invalidate any pending requests
|
|
117
|
+
this._incrementRequestId()
|
|
102
118
|
this.loadAjaxContent(activeItem)
|
|
103
119
|
} else {
|
|
104
120
|
this.switchPanel(activeItem)
|
|
@@ -142,8 +158,8 @@ export default class extends Controller {
|
|
|
142
158
|
|
|
143
159
|
/**
|
|
144
160
|
* AJAX mode: Load content from URL
|
|
145
|
-
* Uses AbortController to cancel
|
|
146
|
-
*
|
|
161
|
+
* Uses AbortController to cancel pending network requests and
|
|
162
|
+
* a shared request counter (on the DOM) to discard stale responses.
|
|
147
163
|
*/
|
|
148
164
|
async loadAjaxContent(item) {
|
|
149
165
|
const url = item.dataset.url
|
|
@@ -159,20 +175,23 @@ export default class extends Controller {
|
|
|
159
175
|
// Check cache
|
|
160
176
|
if (this.cacheAjaxValue && this.ajaxCache.has(url)) {
|
|
161
177
|
contentContainer.innerHTML = this.ajaxCache.get(url)
|
|
178
|
+
contentContainer.classList.remove('rmm-tab-loading')
|
|
162
179
|
this.dispatch('contentLoaded', {
|
|
163
180
|
detail: { modalId: this.modalIdValue, itemId: item.dataset.itemId, fromCache: true }
|
|
164
181
|
})
|
|
165
182
|
return
|
|
166
183
|
}
|
|
167
184
|
|
|
168
|
-
// Abort previous pending request
|
|
185
|
+
// Abort previous pending request from this controller instance
|
|
169
186
|
if (this.currentAbortController) {
|
|
170
187
|
this.currentAbortController.abort()
|
|
171
188
|
}
|
|
172
189
|
|
|
173
190
|
const abortController = new AbortController()
|
|
174
191
|
this.currentAbortController = abortController
|
|
175
|
-
|
|
192
|
+
|
|
193
|
+
// Read the request ID that was set synchronously by selectItem/forceReloadActive
|
|
194
|
+
const requestId = parseInt(contentContainer.dataset.rmmRequestId || '0', 10)
|
|
176
195
|
|
|
177
196
|
// Show loading state
|
|
178
197
|
contentContainer.classList.add('rmm-tab-loading')
|
|
@@ -193,8 +212,8 @@ export default class extends Controller {
|
|
|
193
212
|
|
|
194
213
|
const html = await response.text()
|
|
195
214
|
|
|
196
|
-
// Validate:
|
|
197
|
-
if (
|
|
215
|
+
// Validate: discard if a newer request has been initiated
|
|
216
|
+
if (parseInt(contentContainer.dataset.rmmRequestId, 10) !== requestId) {
|
|
198
217
|
return
|
|
199
218
|
}
|
|
200
219
|
|
|
@@ -216,6 +235,11 @@ export default class extends Controller {
|
|
|
216
235
|
return
|
|
217
236
|
}
|
|
218
237
|
|
|
238
|
+
// Also discard errors from stale requests
|
|
239
|
+
if (parseInt(contentContainer.dataset.rmmRequestId, 10) !== requestId) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
219
243
|
console.error('RMM Submenu: Failed to load content', error)
|
|
220
244
|
contentContainer.innerHTML = `
|
|
221
245
|
<div class="rmm-tab-error">
|
|
@@ -259,6 +283,7 @@ export default class extends Controller {
|
|
|
259
283
|
if (url) {
|
|
260
284
|
this.ajaxCache.delete(url)
|
|
261
285
|
}
|
|
286
|
+
this._incrementRequestId()
|
|
262
287
|
this.loadAjaxContent(activeItem)
|
|
263
288
|
}
|
|
264
289
|
}
|