${escapeHtml(item.display_name || item.tool_name || "Tool")}
${escapeHtml(item.summary || payload?.message || "Item aguardando analise do time.")}
document.documentElement.dataset.panelReady = "true"; const loginForm = document.querySelector('[data-admin-login-form="true"]'); const reviewBoard = document.querySelector('[data-admin-tool-review-board="true"]'); if (loginForm) { mountLoginForm(loginForm); } if (reviewBoard) { mountToolReviewBoard(reviewBoard); } function mountLoginForm(form) { const feedback = document.getElementById("admin-login-feedback"); const submitButton = form.querySelector('button[type="submit"]'); const submitLabel = form.querySelector("[data-submit-label]"); const submitSpinner = form.querySelector("[data-submit-spinner]"); form.addEventListener("submit", async (event) => { event.preventDefault(); toggleLoading(true); clearFeedback(); const formData = new FormData(form); const payload = { email: String(formData.get("email") || "").trim(), password: String(formData.get("password") || ""), }; try { const response = await fetch(form.dataset.authEndpoint, { method: "POST", credentials: "same-origin", headers: { "Content-Type": "application/json", Accept: "application/json", }, body: JSON.stringify(payload), }); const authBody = await readJson(response); if (!response.ok) { throw new Error(authBody?.detail || "Nao foi possivel autenticar no admin."); } showFeedback("success", authBody?.message || "Sessao administrativa web iniciada com sucesso."); form.reset(); const redirectTo = authBody?.redirect_to || form.dataset.dashboardHref; if (redirectTo) { window.setTimeout(() => { window.location.assign(redirectTo); }, 250); } } catch (error) { showFeedback("danger", error instanceof Error ? error.message : "Erro inesperado durante o login."); } finally { toggleLoading(false); } }); function toggleLoading(isLoading) { submitButton.disabled = isLoading; submitSpinner.classList.toggle("d-none", !isLoading); submitLabel.textContent = isLoading ? "Validando acesso..." : "Entrar no painel"; } function clearFeedback() { feedback.className = "alert d-none mt-4 mb-0 rounded-4"; feedback.textContent = ""; } function showFeedback(variant, message) { feedback.className = `alert alert-${variant} mt-4 mb-0 rounded-4`; feedback.textContent = message; } } function mountToolReviewBoard(board) { const refreshButton = board.querySelector("[data-admin-tool-refresh]"); const refreshLabel = board.querySelector("[data-tool-refresh-label]"); const refreshSpinner = board.querySelector("[data-tool-refresh-spinner]"); const feedback = document.getElementById("admin-tool-review-feedback"); const queueList = board.querySelector("[data-tool-review-queue-list]"); const publicationList = board.querySelector("[data-tool-publication-list]"); const lifecycleList = board.querySelector("[data-tool-contract-lifecycle]"); const parameterTypes = board.querySelector("[data-tool-parameter-types]"); if (refreshButton) { refreshButton.addEventListener("click", () => { void loadBoard(); }); } void loadBoard(); async function loadBoard() { toggleRefreshing(true); clearFeedback(); const overviewResult = await fetchPanelJson(board.dataset.overviewEndpoint); const contractsResult = await fetchPanelJson(board.dataset.contractsEndpoint); const reviewQueueResult = await fetchPanelJson(board.dataset.reviewQueueEndpoint); const publicationsResult = await fetchPanelJson(board.dataset.publicationsEndpoint); if (!overviewResult.ok && !contractsResult.ok && !reviewQueueResult.ok && !publicationsResult.ok) { showFeedback("warning", overviewResult.message || "Entre com uma sessao administrativa web para carregar esta tela."); } if (overviewResult.ok) { renderOverview(overviewResult.body); } if (contractsResult.ok) { renderContracts(contractsResult.body); } else { renderLockedLifecycle(contractsResult.message); } if (reviewQueueResult.ok) { renderReviewQueue(reviewQueueResult.body); } else { renderLockedQueue(reviewQueueResult.message); } if (publicationsResult.ok) { renderPublications(publicationsResult.body); } else { renderLockedPublications(publicationsResult.message); } setText("[data-tool-review-last-sync]", formatNow()); toggleRefreshing(false); } function toggleRefreshing(isLoading) { if (!refreshButton || !refreshLabel || !refreshSpinner) { return; } refreshButton.disabled = isLoading; refreshSpinner.classList.toggle("d-none", !isLoading); refreshLabel.textContent = isLoading ? "Atualizando..." : "Atualizar leitura"; } function clearFeedback() { feedback.className = "alert d-none rounded-4 mb-4"; feedback.textContent = ""; } function showFeedback(variant, message) { feedback.className = `alert alert-${variant} rounded-4 mb-4`; feedback.textContent = message; } function renderOverview(payload) { const workflow = Array.isArray(payload?.workflow) ? payload.workflow : []; const nextSteps = Array.isArray(payload?.next_steps) ? payload.next_steps : []; setText("[data-tool-review-lifecycle-count]", String(workflow.length || 0)); if (nextSteps.length > 0 && !feedback.textContent) { showFeedback("info", `Proximos passos: ${nextSteps[0]}`); } } function renderContracts(payload) { const lifecycle = Array.isArray(payload?.lifecycle_statuses) ? payload.lifecycle_statuses : []; const parameterTypeList = Array.isArray(payload?.parameter_types) ? payload.parameter_types : []; lifecycleList.innerHTML = lifecycle.length > 0 ? lifecycle.map((item) => `
${escapeHtml(item.summary || payload?.message || "Item aguardando analise do time.")}
${escapeHtml(payload?.message || "Nenhuma tool aguardando revisao agora.")}
${escapeHtml(message || "A sessao atual nao pode acessar a fila de revisao.")}
${escapeHtml(item.description || "Publicacao ativa no catalogo do produto.")}
Nenhuma publicacao ativa retornada pela sessao web.
${escapeHtml(message || "A sessao atual nao possui permissao para ler as publicacoes ativas.")}