feat(update): floating notif + banner saat restart diperlukan
All checks were successful
CI / test (push) Successful in 1m32s

- marker .restart-required ditulis setelah update sukses
- API /admin/api/restart-required + polling 30s di sidebar
- banner di halaman Update sampai restart
- marker dihapus saat boot proses baru
- versi 0.5.19
This commit is contained in:
oxpoe
2026-11-06 04:01:16 +07:00
parent ad62aab07d
commit 848dd49cce
9 changed files with 86 additions and 5 deletions

View File

@@ -4598,16 +4598,34 @@ router.post('/settings/regenerate-icons', requireAdminSession, async (req, res)
router.get('/update', requireAdminSession, requireSidebarMenuAccess('update'), restrictToAdmin, (req, res) => {
const repoRoot = path.resolve(__dirname, '..');
const info = getUpdateInfo(repoRoot);
let restartPending = null;
try {
const markerPath = path.join(repoRoot, '.restart-required');
if (fs.existsSync(markerPath)) restartPending = JSON.parse(fs.readFileSync(markerPath, 'utf8'));
} catch (e) { restartPending = null; }
res.render('admin/update', {
title: 'Update Aplikasi',
company: company(),
activePage: 'update',
msg: flashMsg(req),
info,
restartPending,
log: popUpdateLog(req)
});
});
router.get('/api/restart-required', requireAdminSession, (req, res) => {
const repoRoot = path.resolve(__dirname, '..');
try {
const markerPath = path.join(repoRoot, '.restart-required');
if (fs.existsSync(markerPath)) {
const d = JSON.parse(fs.readFileSync(markerPath, 'utf8'));
return res.json({ pending: true, version: d.version || '', from: d.from || '', at: d.at || '' });
}
} catch (e) {}
return res.json({ pending: false });
});
router.post('/update/run', requireAdminSession, restrictToAdmin, (req, res) => {
const repoRoot = path.resolve(__dirname, '..');
if (!runCmd('git', ['rev-parse', '--is-inside-work-tree'], repoRoot).ok) {
@@ -4753,7 +4771,17 @@ router.post('/update/run', requireAdminSession, restrictToAdmin, (req, res) => {
}
const localAfter = readTextFileSafe(versionPath) || '-';
req.session._msg = { type: 'success', text: `Update selesai. Versi: ${localBefore} → ${localAfter}. Silakan restart aplikasi.` };
try {
fs.writeFileSync(
path.join(repoRoot, '.restart-required'),
JSON.stringify({ version: localAfter, from: localBefore, at: new Date().toISOString() }),
'utf8'
);
log.push('$ restart-required marker ditulis');
} catch (markerErr) {
log.push('$ restart-required marker gagal: ' + String(markerErr?.message || markerErr));
}
req.session._msg = { type: 'success', text: `Update selesai. Versi: ${localBefore} → ${localAfter}. Restart aplikasi diperlukan agar perubahan aktif.` };
req.session._updateLog = log.join('\n');
} catch (e) {
if (repoChanged) {