diff --git a/assets/js/app.ts b/assets/js/app.ts
index f42bd115..2d03e9e0 100644
--- a/assets/js/app.ts
+++ b/assets/js/app.ts
@@ -284,7 +284,7 @@ if (!csrfToken) {
const liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500,
params: { _csrf_token: csrfToken },
- hooks: { ...colocatedHooks, SensorChart, WebAuthnRegister, WebAuthnLogin },
+ hooks: { ...colocatedHooks, SensorChart, WebAuthnRegister, WebAuthnLogin, CopyToClipboard },
})
// Show progress bar on live navigation and form submits
@@ -293,7 +293,9 @@ window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())
// Handle clipboard copy events
-window.addEventListener("phx:copy", (event) => {
+window.addEventListener("phx:copy", (event: any) => {
+ // When using JS.dispatch with 'to:', the event is dispatched to that element
+ // and event.target will be that element
const el = event.target as HTMLElement
let text = ""
@@ -304,14 +306,64 @@ window.addEventListener("phx:copy", (event) => {
text = el.innerText || el.textContent || ""
}
- navigator.clipboard.writeText(text).then(() => {
- // Optional: Show a success message or visual feedback
- console.log('Copied to clipboard')
- }).catch(err => {
- console.error('Failed to copy text: ', err)
- })
+ if (text) {
+ navigator.clipboard.writeText(text).then(() => {
+ console.log('Copied to clipboard:', text.substring(0, 50) + (text.length > 50 ? '...' : ''))
+ }).catch(err => {
+ console.error('Failed to copy text:', err)
+ })
+ } else {
+ console.warn('No text found to copy from element:', el)
+ }
})
+// LiveView hook for copying to clipboard
+const CopyToClipboard = {
+ mounted() {
+ this.el.addEventListener("click", (e) => {
+ e.preventDefault()
+ const targetId = this.el.dataset.target
+ if (!targetId) {
+ console.error("No data-target attribute found on copy button")
+ return
+ }
+
+ const targetEl = document.querySelector(targetId) as HTMLInputElement | HTMLTextAreaElement | HTMLElement
+ if (!targetEl) {
+ console.error(`Target element not found: ${targetId}`)
+ return
+ }
+
+ let text = ""
+ if (targetEl.tagName === "INPUT" || targetEl.tagName === "TEXTAREA") {
+ text = (targetEl as HTMLInputElement | HTMLTextAreaElement).value
+ } else {
+ text = targetEl.innerText || targetEl.textContent || ""
+ }
+
+ if (text) {
+ navigator.clipboard.writeText(text).then(() => {
+ console.log('Copied to clipboard successfully')
+ // Optional: Show visual feedback
+ const originalText = this.el.innerHTML
+ this.el.innerHTML = ' Copied!'
+ setTimeout(() => {
+ this.el.innerHTML = originalText
+ }, 2000)
+ }).catch(err => {
+ console.error('Failed to copy:', err)
+ })
+ } else {
+ console.error('No text found to copy')
+ }
+ })
+ }
+}
+
+const Hooks = {
+ CopyToClipboard
+}
+
// connect if there are any LiveViews on the page
liveSocket.connect()
diff --git a/lib/towerops_web/live/agent_live/index.html.heex b/lib/towerops_web/live/agent_live/index.html.heex
index f7745b8e..aac9f731 100644
--- a/lib/towerops_web/live/agent_live/index.html.heex
+++ b/lib/towerops_web/live/agent_live/index.html.heex
@@ -215,10 +215,9 @@
/>