## Summary - Fixes misleading “queued / running in background” message when Review Pack generation request reuses an existing ready pack (fingerprint dedupe). - Improves resilience of Filament/Livewire interactions by ensuring the Livewire intercept shim applies after Livewire initializes. - Aligns Review Pack operation notifications with Ops-UX patterns (queued + completed notifications) and removes the old ReviewPackStatusNotification. ## Key Changes - Review Pack generate action now: - Shows queued toast only when a new pack is actually created/queued. - Shows a “Review pack already available” success notification with a link when dedupe returns an existing pack. ## Tests - `vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/ReviewPackGenerationTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/ReviewPack/ReviewPackResourceTest.php` - `vendor/bin/sail artisan test --compact tests/Feature/LivewireInterceptShimTest.php` ## Notes - No global search behavior changes for ReviewPacks (still excluded). - Destructive actions remain confirmation-gated (`->requiresConfirmation()`). Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #133
99 lines
3.0 KiB
JavaScript
99 lines
3.0 KiB
JavaScript
(() => {
|
|
// TenantPilot shim: ensure Livewire interceptMessage callbacks run in a safe order.
|
|
// This prevents Filament's notifications asset (and others) from calling an undefined
|
|
// animation callback when onSuccess fires before onFinish.
|
|
if (typeof window === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
const applyShim = () => {
|
|
const Livewire = window.Livewire;
|
|
|
|
if (!Livewire || typeof Livewire.interceptMessage !== 'function') {
|
|
return false;
|
|
}
|
|
|
|
if (Livewire.__tenantpilotInterceptMessageShimApplied) {
|
|
return true;
|
|
}
|
|
|
|
const original = Livewire.interceptMessage.bind(Livewire);
|
|
|
|
Livewire.interceptMessage = (handler) => {
|
|
if (typeof handler !== 'function') {
|
|
return original(handler);
|
|
}
|
|
|
|
return original((context) => {
|
|
if (!context || typeof context !== 'object') {
|
|
return handler(context);
|
|
}
|
|
|
|
const originalOnFinish = context.onFinish;
|
|
const originalOnSuccess = context.onSuccess;
|
|
|
|
if (typeof originalOnFinish !== 'function' || typeof originalOnSuccess !== 'function') {
|
|
return handler(context);
|
|
}
|
|
|
|
const finishCallbacks = [];
|
|
|
|
const onFinish = (callback) => {
|
|
if (typeof callback === 'function') {
|
|
finishCallbacks.push(callback);
|
|
}
|
|
|
|
return originalOnFinish(callback);
|
|
};
|
|
|
|
const onSuccess = (callback) => {
|
|
return originalOnSuccess((...args) => {
|
|
// Ensure any registered finish callbacks are run before success callbacks.
|
|
// We don't swallow errors; we just stabilize ordering.
|
|
for (const finishCallback of finishCallbacks) {
|
|
finishCallback(...args);
|
|
}
|
|
|
|
if (typeof callback === 'function') {
|
|
return callback(...args);
|
|
}
|
|
});
|
|
};
|
|
|
|
return handler({
|
|
...context,
|
|
onFinish,
|
|
onSuccess,
|
|
});
|
|
});
|
|
};
|
|
|
|
Livewire.__tenantpilotInterceptMessageShimApplied = true;
|
|
|
|
return true;
|
|
};
|
|
|
|
if (applyShim()) {
|
|
return;
|
|
}
|
|
|
|
// Livewire may not be initialized yet when this script runs (depending on
|
|
// script tag order). Try again on `livewire:init` and with a short fallback poll.
|
|
const onInit = () => {
|
|
applyShim();
|
|
};
|
|
|
|
window.addEventListener('livewire:init', onInit, { once: true });
|
|
document.addEventListener('livewire:init', onInit, { once: true });
|
|
|
|
let tries = 0;
|
|
const maxTries = 50;
|
|
const timer = setInterval(() => {
|
|
tries += 1;
|
|
|
|
if (applyShim() || tries >= maxTries) {
|
|
clearInterval(timer);
|
|
}
|
|
}, 100);
|
|
})();
|