ken_nogi/NodeSrv/apps/app-portal/public/portal.js
Kenichiro NOGI 4b14d992af feat: get-voice-mailに取得範囲フラグ追加、n8nワークフローを1件ずつループ処理化
大量ファイル処理時のn8nメモリ枯渇対策として、SplitInBatches(1件ずつ)で
SSHダウンロード→base64化→プリザンター登録を直列化(n8n側、API経由で反映済み)。
Webhookに?range=today|week|allを追加、app-portal側にも選択UIを実装。
2026-09-19 11:43:21 +09:00

52 lines
1.7 KiB
JavaScript

const logModalEl = document.getElementById('logModal');
const logModalBody = document.getElementById('logModalBody');
const logModal = logModalEl ? new bootstrap.Modal(logModalEl) : null;
const toastEl = document.getElementById('actionToast');
const toastBody = document.getElementById('actionToastBody');
const toast = toastEl ? new bootstrap.Toast(toastEl) : null;
function showToast(message, isError) {
if (!toast) {
alert(message);
return;
}
toastBody.textContent = message;
toastEl.classList.toggle('text-bg-danger', Boolean(isError));
toastEl.classList.toggle('text-bg-primary', !isError);
toast.show();
}
document.getElementById('cards').addEventListener('click', async (event) => {
const button = event.target.closest('button[data-action]');
if (!button) return;
const { action, composeId } = button.dataset;
if (action === 'logs') {
const res = await fetch(`/api/compose/${composeId}/logs`);
if (!res.ok) {
showToast(`ログ取得に失敗しました (status: ${res.status})`, true);
return;
}
const data = await res.json();
logModalBody.textContent = data.logs || 'ログなし';
logModal.show();
return;
}
let url = `/api/compose/${composeId}/${action}`;
if (action === 'trigger') {
const rangeSelect = document.querySelector(`select[data-range-select][data-compose-id="${composeId}"]`);
if (rangeSelect) {
url += `?range=${encodeURIComponent(rangeSelect.value)}`;
}
}
const res = await fetch(url, { method: 'POST' });
if (res.ok) {
showToast(`${action} を実行しました`, false);
} else {
showToast(`${action} に失敗しました (status: ${res.status})`, true);
}
});