大量ファイル処理時のn8nメモリ枯渇対策として、SplitInBatches(1件ずつ)で SSHダウンロード→base64化→プリザンター登録を直列化(n8n側、API経由で反映済み)。 Webhookに?range=today|week|allを追加、app-portal側にも選択UIを実装。
52 lines
1.7 KiB
JavaScript
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);
|
|
}
|
|
});
|