mirror of
https://github.com/we-promise/sure.git
synced 2026-04-08 23:04:49 +00:00
Add SnapTrade connection management UI for freeing up connection slots (#747)
* Add SnapTrade connection management with lazy-loading and deletion functionality. * Refactor lazy-load controller to simplify event handling and enhance loading state management; improve SnapTrade deletion logic with additional safeguards and logging. * Improve SnapTrade connection error handling and centralize unknown brokerage message using i18n. * Centralize SnapTrade connection default name and missing authorization ID messages using i18n. * Enhance SnapTrade connection deletion logic with improved error handling, i18n support for API deletion failures, and consistent Turbo Stream responses. --------- Co-authored-by: luckyPipewrench <luckypipewrench@proton.me>
This commit is contained in:
64
app/javascript/controllers/lazy_load_controller.js
Normal file
64
app/javascript/controllers/lazy_load_controller.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
// Connects to data-controller="lazy-load"
|
||||
// Used with <details> elements to lazy-load content when expanded
|
||||
// Use data-action="toggle->lazy-load#toggled" on the <details> element
|
||||
export default class extends Controller {
|
||||
static targets = ["content", "loading", "frame"];
|
||||
static values = { url: String, loaded: Boolean };
|
||||
|
||||
connect() {
|
||||
// If already open on connect (browser restored state), load immediately
|
||||
if (this.element.open && !this.loadedValue) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
|
||||
toggled() {
|
||||
if (this.element.open && !this.loadedValue) {
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
|
||||
async load() {
|
||||
if (this.loadedValue || this.loading) return;
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;
|
||||
const response = await fetch(this.urlValue, {
|
||||
headers: {
|
||||
Accept: "text/html",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
"X-CSRF-Token": csrfToken,
|
||||
},
|
||||
credentials: "same-origin",
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const html = await response.text();
|
||||
if (this.hasFrameTarget) {
|
||||
this.frameTarget.innerHTML = html;
|
||||
}
|
||||
if (this.hasLoadingTarget) {
|
||||
this.loadingTarget.classList.add("hidden");
|
||||
}
|
||||
this.loadedValue = true;
|
||||
} else {
|
||||
console.error("Lazy load failed:", response.status, response.statusText);
|
||||
this.showError(`Failed to load (${response.status})`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Lazy load error:", error);
|
||||
this.showError("Network error");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
showError(message) {
|
||||
if (this.hasLoadingTarget) {
|
||||
this.loadingTarget.innerHTML = `<p class="text-destructive text-sm">${message}</p>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user