forked from izu/student-web-if-development-kit
fix: embed RODA dashboard data at build
This commit is contained in:
+90
-54
@@ -75,6 +75,7 @@
|
||||
<script>
|
||||
window.APP_CONFIG = window.APP_CONFIG || {
|
||||
debugLogs: false,
|
||||
dashboardRuntimeFetch: 'local',
|
||||
dashboardTargetUrl: 'https://dashboard.informatika.untan.ac.id/index.php?penelitian',
|
||||
dashboardProxyTemplates: [
|
||||
'https://api.allorigins.win/get?url={{url}}&ts={{ts}}',
|
||||
@@ -83,6 +84,7 @@
|
||||
]
|
||||
};
|
||||
</script>
|
||||
<!-- RODA_DASHBOARD_DATA -->
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
|
||||
@@ -1484,6 +1486,7 @@
|
||||
if (error.message === 'EMPTY_RESPONSE') return 'Dashboard mengembalikan data kosong atau struktur halaman berubah.';
|
||||
if (error.message === 'NO_ROWS_FOUND') return 'Data penelitian tidak ditemukan pada halaman dashboard.';
|
||||
if (error.message === 'DASHBOARD_PROXY_NOT_CONFIGURED') return 'Proxy dashboard belum dikonfigurasi.';
|
||||
if (error.message === 'DASHBOARD_RUNTIME_FETCH_DISABLED') return 'Data publikasi belum tersedia pada build ini.';
|
||||
if (error.message?.startsWith('HTTP_ERROR_')) return `Proxy merespons gagal (${error.message.replace('HTTP_ERROR_', 'HTTP ')}).`;
|
||||
return 'Gagal mengambil data. Server dashboard mungkin sedang sibuk atau memblokir akses.';
|
||||
}
|
||||
@@ -1549,6 +1552,75 @@
|
||||
return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '';
|
||||
}
|
||||
|
||||
function isDashboardRuntimeFetchAllowed() {
|
||||
const mode = window.APP_CONFIG?.dashboardRuntimeFetch;
|
||||
return mode === true || mode === 'always' || (mode === 'local' && shouldUseLocalDashboardProxy());
|
||||
}
|
||||
|
||||
function readEmbeddedDashboardHtml() {
|
||||
const source = document.getElementById('roda-dashboard-html');
|
||||
if (!source) return '';
|
||||
|
||||
try {
|
||||
return JSON.parse(source.textContent || '""') || '';
|
||||
} catch (error) {
|
||||
return source.textContent || '';
|
||||
}
|
||||
}
|
||||
|
||||
function applyDashboardRows(rows) {
|
||||
const newData = [];
|
||||
rows.forEach((row) => {
|
||||
const cols = row.querySelectorAll('td');
|
||||
if (cols.length >= 3) {
|
||||
const indexVal = cols[0].innerText.trim();
|
||||
|
||||
// Mencari elemen judul (biasanya di dalam <a> atau <b>)
|
||||
const linkEl = cols[1].querySelector('a');
|
||||
const titleEl = linkEl || cols[1].querySelector('b') || cols[1];
|
||||
const url = linkEl ? linkEl.getAttribute('href') : '#';
|
||||
const title = titleEl.innerText.trim();
|
||||
|
||||
// Skip jika baris ini adalah header atau bukan data penelitian (berdasarkan index atau judul)
|
||||
if (isNaN(parseInt(indexVal)) || title === "Bidang Riset" || title === "Thn Jlh") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mencari elemen penulis (biasanya di dalam tag <font> dengan size 11px)
|
||||
const authorsEl = cols[1].querySelector('font');
|
||||
const authors = authorsEl ? authorsEl.innerText.trim() : 'Peneliti Informatika';
|
||||
|
||||
// Tahun biasanya ada di kolom berikutnya
|
||||
const year = cols[2]?.innerText.trim() || '2025';
|
||||
|
||||
const kbk = categorizeByKeywords(title);
|
||||
const kbkInfo = kbkMeta[kbk];
|
||||
|
||||
newData.push({
|
||||
id: parseInt(indexVal) || (newData.length + 1),
|
||||
kbk: kbk,
|
||||
title_id: title,
|
||||
title_en: title,
|
||||
authors: authors,
|
||||
year: year,
|
||||
url: url,
|
||||
venue: 'Dashboard Informatika',
|
||||
badge_id: kbkInfo.label_id,
|
||||
badge_en: kbkInfo.label_en
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!newData.length) {
|
||||
throw new Error('NO_ROWS_FOUND');
|
||||
}
|
||||
|
||||
risetData = newData;
|
||||
isLoadingData = false;
|
||||
renderRisetCards();
|
||||
updateStatPub(newData.length);
|
||||
}
|
||||
|
||||
async function fetchDashboardData() {
|
||||
const grid = document.getElementById('riset-grid');
|
||||
if (grid) {
|
||||
@@ -1560,6 +1632,22 @@
|
||||
`;
|
||||
}
|
||||
|
||||
let lastError = null;
|
||||
const embeddedHtml = readEmbeddedDashboardHtml();
|
||||
if (embeddedHtml) {
|
||||
try {
|
||||
applyDashboardRows(parseDashboardRows(embeddedHtml));
|
||||
return;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isDashboardRuntimeFetchAllowed()) {
|
||||
renderRisetFeedback('Pemuatan Data Gagal', getDashboardErrorMessage(lastError || new Error('DASHBOARD_RUNTIME_FETCH_DISABLED')), 'Coba Lagi', 'fetchDashboardData()');
|
||||
return;
|
||||
}
|
||||
|
||||
const targetUrl = window.APP_CONFIG?.dashboardTargetUrl?.trim();
|
||||
const proxyTemplates = Array.isArray(window.APP_CONFIG?.dashboardProxyTemplates)
|
||||
? window.APP_CONFIG.dashboardProxyTemplates.filter(Boolean)
|
||||
@@ -1583,8 +1671,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
let lastError = null;
|
||||
|
||||
for (const getProxyUrl of proxyServers) {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 15000);
|
||||
@@ -1600,58 +1686,8 @@
|
||||
const responseData = await response.text();
|
||||
const html = extractDashboardHtml(responseData);
|
||||
const rows = parseDashboardRows(html);
|
||||
|
||||
const newData = [];
|
||||
rows.forEach((row, index) => {
|
||||
const cols = row.querySelectorAll('td');
|
||||
if (cols.length >= 3) {
|
||||
const indexVal = cols[0].innerText.trim();
|
||||
|
||||
// Mencari elemen judul (biasanya di dalam <a> atau <b>)
|
||||
const linkEl = cols[1].querySelector('a');
|
||||
const titleEl = linkEl || cols[1].querySelector('b') || cols[1];
|
||||
const url = linkEl ? linkEl.getAttribute('href') : '#';
|
||||
const title = titleEl.innerText.trim();
|
||||
|
||||
// Skip jika baris ini adalah header atau bukan data penelitian (berdasarkan index atau judul)
|
||||
if (isNaN(parseInt(indexVal)) || title === "Bidang Riset" || title === "Thn Jlh") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Mencari elemen penulis (biasanya di dalam tag <font> dengan size 11px)
|
||||
const authorsEl = cols[1].querySelector('font');
|
||||
const authors = authorsEl ? authorsEl.innerText.trim() : 'Peneliti Informatika';
|
||||
|
||||
// Tahun biasanya ada di kolom berikutnya
|
||||
const year = cols[2]?.innerText.trim() || '2025';
|
||||
|
||||
const kbk = categorizeByKeywords(title);
|
||||
const kbkInfo = kbkMeta[kbk];
|
||||
|
||||
newData.push({
|
||||
id: parseInt(indexVal) || (newData.length + 1),
|
||||
kbk: kbk,
|
||||
title_id: title,
|
||||
title_en: title,
|
||||
authors: authors,
|
||||
year: year,
|
||||
url: url,
|
||||
venue: 'Dashboard Informatika',
|
||||
badge_id: kbkInfo.label_id,
|
||||
badge_en: kbkInfo.label_en
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (newData.length > 0) {
|
||||
risetData = newData;
|
||||
isLoadingData = false;
|
||||
renderRisetCards();
|
||||
updateStatPub(newData.length);
|
||||
return; // Berhasil! Keluar dari loop
|
||||
}
|
||||
|
||||
throw new Error('NO_ROWS_FOUND');
|
||||
applyDashboardRows(rows);
|
||||
return; // Berhasil! Keluar dari loop
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId);
|
||||
lastError = error;
|
||||
|
||||
Reference in New Issue
Block a user