Let a non-blocking checklist item be dismissed with a recorded decision, and run discovery on the mirror once there is something to discover
This commit is contained in:
@@ -232,6 +232,42 @@ if (!empty($host2)) {
|
||||
];
|
||||
}
|
||||
|
||||
$allOk = !in_array(false, array_column($items, 'ok'), true);
|
||||
// ── Blocking vs deferrable ────────────────────────────────────────────────────
|
||||
// Setup used to be complete only when every item was green, which made a media-server API key a
|
||||
// gate on finishing onboarding. A mirror that runs no Emby, or runs one the operator has not got
|
||||
// round to configuring, could never reach "complete" — and the checklist is what tells them
|
||||
// whether they are done.
|
||||
//
|
||||
// Blocking items are the ones the mesh genuinely cannot work without: who this host is, its conf,
|
||||
// its SSH key, the owner's master.conf, and the partnership itself. Everything else improves the
|
||||
// install without being load-bearing, and can be dismissed with a recorded decision.
|
||||
//
|
||||
// Deferring is per item and reversible, stored in the setup state so it survives a reload. The
|
||||
// item still shows — amber, "deferred" — rather than disappearing, because a dismissed item is a
|
||||
// decision to revisit, not a thing that stopped being true.
|
||||
$deferrable = ['api_key' => true, 'populated' => true, 'emby_key' => true, 'jellyfin_key' => true];
|
||||
$state = vv_setup_state_read();
|
||||
|
||||
foreach ($items as &$item) {
|
||||
$canDefer = !empty($deferrable[$item['id']]);
|
||||
$item['blocking'] = !$canDefer;
|
||||
$item['deferred'] = $canDefer && !$item['ok']
|
||||
&& !empty($state['DEFER_' . strtoupper($item['id'])]);
|
||||
if ($item['deferred']) {
|
||||
$item['detail'] = ($item['detail'] ?? '') . ' — deferred';
|
||||
$item['action'] = 'undefer';
|
||||
} elseif ($canDefer && !$item['ok']) {
|
||||
// Keep the item's real action as the primary; the UI offers defer alongside it.
|
||||
$item['can_defer'] = true;
|
||||
}
|
||||
}
|
||||
unset($item);
|
||||
|
||||
// Complete when every blocking item is green and every deferrable one is green or dismissed.
|
||||
$allOk = true;
|
||||
foreach ($items as $i) {
|
||||
if ($i['ok']) continue;
|
||||
if ($i['blocking'] || empty($i['deferred'])) { $allOk = false; break; }
|
||||
}
|
||||
|
||||
echo json_encode(['ok' => true, 'complete' => $allOk, 'host_id' => $hostId, 'items' => $items]);
|
||||
|
||||
@@ -195,6 +195,39 @@ if ($action === 'populate') {
|
||||
exit;
|
||||
}
|
||||
|
||||
// ── POST: defer / undefer a non-blocking checklist item ───────────────────────────────────────
|
||||
// Records the operator's "not now" so the checklist can reach complete without the item being
|
||||
// green. Only the ids api/checklist.php marks deferrable are accepted — a blocking item cannot be
|
||||
// dismissed, because dismissing it would report a mesh as ready when it cannot function.
|
||||
if ($action === 'defer' || $action === 'undefer') {
|
||||
// POST only, and not merely by convention: $action is taken from GET too, and Unraid's CSRF
|
||||
// guard checks POST alone. A GET-reachable mutation here would let any page the operator
|
||||
// visits silently dismiss a checklist item.
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['ok' => false, 'error' => 'Method not allowed']);
|
||||
exit;
|
||||
}
|
||||
$allowed = ['api_key', 'populated', 'emby_key', 'jellyfin_key'];
|
||||
$item = trim($_POST['item'] ?? '');
|
||||
if (!in_array($item, $allowed, true)) {
|
||||
echo json_encode(['ok' => false, 'error' => 'Not a deferrable item: ' . $item]);
|
||||
exit;
|
||||
}
|
||||
$state = vv_setup_state_read();
|
||||
$key = 'DEFER_' . strtoupper($item);
|
||||
if ($action === 'defer') {
|
||||
$state[$key] = (string)time(); // when, not just whether — a stale decision shows its age
|
||||
} else {
|
||||
unset($state[$key]);
|
||||
}
|
||||
if (!vv_setup_state_write($state)) {
|
||||
echo json_encode(['ok' => false, 'error' => 'Failed to write setup state']);
|
||||
exit;
|
||||
}
|
||||
echo json_encode(['ok' => true, 'item' => $item, 'deferred' => $action === 'defer']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['ok' => false, 'error' => 'Method not allowed']);
|
||||
exit;
|
||||
|
||||
Reference in New Issue
Block a user