upaas/static/js/components.js
user 5fe11f24d4
All checks were successful
Check / check (pull_request) Successful in 11m29s
refactor: break up app.js into smaller modules
Split static/js/app.js (581 lines) into 5 focused modules:
- utils.js: global utilities store + legacy compat
- components.js: reusable Alpine.js components (copy, confirm, dismiss, time)
- app-detail.js: app detail page logic (status polling, logs)
- deployment.js: deployment card + deployments history page
- dashboard.js: dashboard relative time updates

Closes #128
2026-02-23 11:52:41 -08:00

72 lines
1.9 KiB
JavaScript

/**
* upaas - Reusable Alpine.js Components
*
* Small, self-contained components: copy button, confirm dialog,
* auto-dismiss alerts, and relative time display.
*/
document.addEventListener("alpine:init", () => {
// ============================================
// Copy Button Component
// ============================================
Alpine.data("copyButton", (targetId) => ({
copied: false,
async copy() {
const target = document.getElementById(targetId);
if (!target) return;
const text = target.textContent || target.value;
const success = await Alpine.store("utils").copyToClipboard(text);
if (success) {
this.copied = true;
setTimeout(() => {
this.copied = false;
}, 2000);
}
},
}));
// ============================================
// Confirm Action Component
// ============================================
Alpine.data("confirmAction", (message) => ({
confirm(event) {
if (!window.confirm(message)) {
event.preventDefault();
}
},
}));
// ============================================
// Auto-dismiss Alert Component
// ============================================
Alpine.data("autoDismiss", (delay = 5000) => ({
show: true,
init() {
setTimeout(() => {
this.dismiss();
}, delay);
},
dismiss() {
this.show = false;
setTimeout(() => {
this.$el.remove();
}, 300);
},
}));
// ============================================
// Relative Time Component
// ============================================
Alpine.data("relativeTime", (isoTime) => ({
display: "",
init() {
this.update();
// Update every minute
setInterval(() => this.update(), 60000);
},
update() {
this.display = Alpine.store("utils").formatRelativeTime(isoTime);
},
}));
});