import { api } from "../lib/api.js";
import { emit, on } from "../lib/bus.js";
class ConversationsCrud extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.items = [];
this.selected = null;
this.loading = false;
this.searchQuery = "";
this.statusFilter = "";
this.stateFilter = "";
this.shadowRoot.innerHTML = `
Detalle
Selecciona una conversacion
`;
}
connectedCallback() {
this.shadowRoot.getElementById("search").oninput = (e) => {
this.searchQuery = e.target.value;
clearTimeout(this._searchTimer);
this._searchTimer = setTimeout(() => this.load(), 300);
};
this.shadowRoot.getElementById("status").onchange = (e) => {
this.statusFilter = e.target.value;
this.load();
};
this.shadowRoot.getElementById("state").onchange = (e) => {
this.stateFilter = e.target.value;
this.load();
};
this._unsubUpsert = on("conversation:upsert", (conv) => {
const idx = this.items.findIndex(x => x.chat_id === conv.chat_id);
if (idx >= 0) this.items[idx] = conv;
else this.items.unshift(conv);
this.renderList();
});
this.load();
}
disconnectedCallback() {
this._unsubUpsert?.();
}
async load() {
this.loading = true;
this.renderList();
try {
const data = await api.conversations({
q: this.searchQuery,
status: this.statusFilter,
state: this.stateFilter
});
this.items = data.items || [];
this.loading = false;
this.renderList();
} catch (e) {
console.error("Error loading conversations:", e);
this.items = [];
this.loading = false;
this.renderList();
}
}
renderList() {
const list = this.shadowRoot.getElementById("list");
if (this.loading) {
list.innerHTML = `Cargando...
`;
return;
}
if (!this.items.length) {
list.innerHTML = `No se encontraron conversaciones
`;
return;
}
list.innerHTML = "";
for (const item of this.items) {
const el = document.createElement("div");
el.className = "item" + (this.selected?.chat_id === item.chat_id ? " active" : "");
const dotClass = item.status === "ok" ? "ok" : (item.status === "warn" ? "warn" : "err");
const time = item.last_activity ? new Date(item.last_activity).toLocaleString() : "—";
el.innerHTML = `
${item.chat_id}
state: ${item.state || "—"}
intent: ${item.intent || "—"}
${time}
`;
el.onclick = () => {
this.selected = item;
this.renderList();
this.renderDetail();
};
list.appendChild(el);
}
}
renderDetail() {
const detail = this.shadowRoot.getElementById("detail");
const title = this.shadowRoot.getElementById("detailTitle");
if (!this.selected) {
title.textContent = "Detalle";
detail.innerHTML = `Selecciona una conversacion
`;
return;
}
const c = this.selected;
title.textContent = c.from || c.chat_id;
detail.innerHTML = `
${c.intent || "—"}
${c.status || "—"}
${c.last_activity ? new Date(c.last_activity).toLocaleString() : "—"}
${c.last_run_id || "—"}
`;
detail.scrollTop = 0;
this.shadowRoot.getElementById("openChat").onclick = () => {
emit("ui:selectedChat", { chat_id: c.chat_id });
emit("ui:switchView", { view: "chat" });
};
this.shadowRoot.getElementById("retryLast").onclick = async () => {
try {
await api.retryLast(c.chat_id);
alert("Retry ejecutado");
} catch (e) {
alert("Error: " + (e.message || e));
}
};
this.shadowRoot.getElementById("deleteConv").onclick = async () => {
if (!confirm(`¿Eliminar la conversacion de "${c.chat_id}"?`)) return;
try {
await api.deleteConversation(c.chat_id);
this.selected = null;
await this.load();
this.renderDetail();
} catch (e) {
alert("Error: " + (e.message || e));
}
};
}
}
customElements.define("conversations-crud", ConversationsCrud);