Add quiet System Health entry points
This commit is contained in:
@@ -7,6 +7,7 @@ set -euo pipefail
|
||||
|
||||
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
settings_dir="$repo_dir/config/dot/quickshell/modules/settings"
|
||||
bar_dir="$repo_dir/config/dot/quickshell/modules/bar"
|
||||
|
||||
fail() {
|
||||
printf 'health UI contract: %s\n' "$1" >&2
|
||||
@@ -16,6 +17,21 @@ fail() {
|
||||
for file in HealthPage.qml HealthSummary.qml HealthCheckRow.qml; do
|
||||
[[ -f "$settings_dir/$file" ]] || fail "$file is missing"
|
||||
done
|
||||
[[ -f "$bar_dir/HealthIndicator.qml" ]] || fail 'HealthIndicator.qml is missing'
|
||||
|
||||
python3 - "$bar_dir/Bar.qml" <<'PY' || fail 'health indicator is not immediately before activity in the bar'
|
||||
import re
|
||||
import sys
|
||||
|
||||
source = open(sys.argv[1], encoding="utf-8").read()
|
||||
match = re.search(r'HealthIndicator\s*\{.*?\}\s*ActivityIndicator\s*\{', source, re.S)
|
||||
assert match is not None
|
||||
PY
|
||||
|
||||
! rg -n '#[0-9a-fA-F]{3,8}' "$bar_dir/HealthIndicator.qml" >/dev/null \
|
||||
|| fail 'health indicator introduced colors outside Theme'
|
||||
! rg -n 'Behavior|Animation|Transition|pulse|shimmer' "$bar_dir/HealthIndicator.qml" >/dev/null \
|
||||
|| fail 'health indicator introduced motion'
|
||||
[[ ! -e "$settings_dir/ServicesPage.qml" ]] || fail 'ServicesPage.qml still exists'
|
||||
rg -Fq 'HealthPage 1.0 HealthPage.qml' "$settings_dir/qmldir" \
|
||||
|| fail 'HealthPage is not registered in the Settings QML module'
|
||||
@@ -108,6 +124,8 @@ import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
|
||||
import "modules/bar" as BarModule
|
||||
import qs.config
|
||||
import qs.modules.settings
|
||||
import qs.services
|
||||
|
||||
@@ -130,6 +148,11 @@ ShellRoot {
|
||||
id: settingsShell
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
BarModule.HealthIndicator {
|
||||
id: healthIndicator
|
||||
objectName: "health-indicator"
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
@@ -142,6 +165,58 @@ ShellRoot {
|
||||
function request(id: string): bool {
|
||||
return settingsShell.requestHealthAction(id);
|
||||
}
|
||||
|
||||
function indicatorMode(mode: string): bool {
|
||||
const checkStatus = mode === "healthy" ? "ok" : (mode === "unconfigured" ? "unconfigured" : mode);
|
||||
const overallStatus = mode === "warning" || mode === "error" ? mode : "healthy";
|
||||
const snapshot = {
|
||||
schemaVersion: 1,
|
||||
generatedAt: "2026-08-18T12:00:00Z",
|
||||
summary: {
|
||||
status: overallStatus,
|
||||
healthy: mode === "healthy" ? 1 : 0,
|
||||
warnings: mode === "warning" ? 1 : 0,
|
||||
errors: mode === "error" ? 1 : 0,
|
||||
unconfigured: mode === "unconfigured" ? 1 : 0
|
||||
},
|
||||
context: { session: "hyprland", versions: [] },
|
||||
checks: [{
|
||||
id: "desktop.vicinae",
|
||||
group: "desktop-foundation",
|
||||
title: "Vicinae",
|
||||
status: checkStatus,
|
||||
detail: "Fixture observation."
|
||||
}]
|
||||
};
|
||||
return Health.consumeSnapshot(JSON.stringify(snapshot), Health.acceptedGeneration + 1);
|
||||
}
|
||||
|
||||
function indicatorState(): string {
|
||||
return JSON.stringify({
|
||||
visible: healthIndicator.visible,
|
||||
width: healthIndicator.width,
|
||||
implicitWidth: healthIndicator.implicitWidth,
|
||||
issueCount: healthIndicator.issueCount,
|
||||
statusText: healthIndicator.statusText,
|
||||
accessibleLabel: healthIndicator.accessibleLabel,
|
||||
tooltipText: healthIndicator.tooltipText,
|
||||
warningTone: healthIndicator.tone === Theme.warn,
|
||||
errorTone: healthIndicator.tone === Theme.danger,
|
||||
activeFocusOnTab: healthIndicator.activeFocusOnTab
|
||||
});
|
||||
}
|
||||
|
||||
function activateIndicator(): string {
|
||||
ShellState.settingsPage = "home";
|
||||
ShellState.settingsOpen = false;
|
||||
const generation = Health.generation;
|
||||
healthIndicator.activated();
|
||||
return JSON.stringify({
|
||||
page: ShellState.settingsPage,
|
||||
settingsOpen: ShellState.settingsOpen,
|
||||
refreshRequested: Health.generation > generation || Health.queuedRefresh
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
QML
|
||||
@@ -231,6 +306,54 @@ jq -e '
|
||||
' \
|
||||
>/dev/null <<<"$confirmation_state" || fail 'Quickshell restart did not open confirmation sheet'
|
||||
|
||||
for hidden_mode in healthy unconfigured; do
|
||||
[[ "$(run ipc call health-ui-test indicatorMode "$hidden_mode")" == "true" ]] \
|
||||
|| fail "$hidden_mode indicator fixture was rejected"
|
||||
hidden_state="$(run ipc call health-ui-test indicatorState)"
|
||||
jq -e '
|
||||
.visible == false
|
||||
and .width == 0
|
||||
and .implicitWidth == 0
|
||||
and .issueCount == 0
|
||||
' >/dev/null <<<"$hidden_state" \
|
||||
|| fail "$hidden_mode state reserved bar space: $hidden_state"
|
||||
done
|
||||
|
||||
[[ "$(run ipc call health-ui-test indicatorMode warning)" == "true" ]] \
|
||||
|| fail 'warning indicator fixture was rejected'
|
||||
warning_state="$(run ipc call health-ui-test indicatorState)"
|
||||
jq -e '
|
||||
.visible == true
|
||||
and .width > 0
|
||||
and .implicitWidth > 0
|
||||
and .issueCount == 1
|
||||
and .statusText == "1 system health issue"
|
||||
and .accessibleLabel == "System Health: 1 issue needs attention"
|
||||
and .tooltipText == "System Health: 1 issue needs attention"
|
||||
and .warningTone == true
|
||||
and .errorTone == false
|
||||
and .activeFocusOnTab == true
|
||||
' >/dev/null <<<"$warning_state" || fail "warning indicator is not the approved amber accessible capsule: $warning_state"
|
||||
|
||||
[[ "$(run ipc call health-ui-test indicatorMode error)" == "true" ]] \
|
||||
|| fail 'error indicator fixture was rejected'
|
||||
error_state="$(run ipc call health-ui-test indicatorState)"
|
||||
jq -e '
|
||||
.visible == true
|
||||
and .issueCount == 1
|
||||
and .accessibleLabel == "System Health: 1 issue requires action"
|
||||
and .tooltipText == "System Health: 1 issue requires action"
|
||||
and .warningTone == false
|
||||
and .errorTone == true
|
||||
' >/dev/null <<<"$error_state" || fail "error indicator is not the approved red accessible capsule: $error_state"
|
||||
|
||||
activation_state="$(run ipc call health-ui-test activateIndicator)"
|
||||
jq -e '
|
||||
.page == "services"
|
||||
and .settingsOpen == true
|
||||
and .refreshRequested == true
|
||||
' >/dev/null <<<"$activation_state" || fail "indicator activation did not open and refresh System Health: $activation_state"
|
||||
|
||||
if rg -i 'QQml|ReferenceError|TypeError|binding loop|failed to load component' "$shell_log"; then
|
||||
fail 'isolated fixture emitted QML errors or warnings'
|
||||
fi
|
||||
|
||||
@@ -148,6 +148,9 @@ assert_commands 'qs <ipc> <call> <overview> <open>'
|
||||
run_action settings
|
||||
assert_commands 'qs <ipc> <call> <settings> <open>'
|
||||
|
||||
run_action health
|
||||
assert_commands 'qs <ipc> <call> <health> <open>'
|
||||
|
||||
run_action dnd
|
||||
assert_commands $'qs <ipc> <call> <notifications> <dnd>\npanama-osd <message> <notifications-disabled-symbolic> <Do Not Disturb On>'
|
||||
|
||||
@@ -191,11 +194,13 @@ assert_commands $'qs <kill>\nquickshell <--daemonize>\nqs <ipc> <show>\npanama-o
|
||||
PANAMA_ACTION_TEST_FAIL_KILL=true run_action restart-shell
|
||||
assert_commands $'qs <kill>\nquickshell <--daemonize>\nqs <ipc> <show>\npanama-osd <message> <view-refresh-symbolic> <Panama Restarted>'
|
||||
|
||||
usage_output="$work/usage.txt"
|
||||
if HOME="$work/home" PATH="$fake_bin:$PATH" PANAMA_ACTION_HELPER_DIR="$fake_bin" \
|
||||
PANAMA_ACTION_CONFIRM_ATTEMPTS=1 PANAMA_ACTION_CONFIRM_DELAY=0 PANAMA_ACTION_TEST_LOG="$command_log" \
|
||||
"$dispatcher" definitely-not-an-action >/dev/null 2>&1; then
|
||||
"$dispatcher" definitely-not-an-action > /dev/null 2>"$usage_output"; then
|
||||
fail 'unknown action was accepted'
|
||||
fi
|
||||
rg -q '\bhealth\b' "$usage_output" || fail 'health is missing from dispatcher usage'
|
||||
|
||||
: >"$command_log"
|
||||
if PANAMA_ACTION_TEST_FAIL_QS=true HOME="$work/home" PATH="$fake_bin:$PATH" \
|
||||
|
||||
@@ -24,6 +24,7 @@ declare -A expected=(
|
||||
[open-clipboard.sh]=clipboard
|
||||
[open-mission-control.sh]=overview
|
||||
[open-settings.sh]=settings
|
||||
[check-system-health.sh]=health
|
||||
[toggle-dnd.sh]=dnd
|
||||
[toggle-caffeine.sh]=caffeine
|
||||
[toggle-night-light.sh]=night-light
|
||||
@@ -72,6 +73,17 @@ for script_name in "${!expected[@]}"; do
|
||||
grep -Fxq '# @vicinae.icon ../../icons/hicolor/scalable/apps/panama-settings.svg' "$script" \
|
||||
|| fail "$script_name does not use the Panama application identity"
|
||||
|
||||
if [[ $script_name == check-system-health.sh ]]; then
|
||||
[[ $title == 'Panama: Check System Health' ]] \
|
||||
|| fail "health command has the wrong title: $title"
|
||||
grep -Fxq '# @vicinae.schemaVersion 1' "$script" \
|
||||
|| fail 'health command does not use schema version 1'
|
||||
grep -Fxq '# @vicinae.keywords ["health", "doctor", "repair", "services"]' "$script" \
|
||||
|| fail 'health command has the wrong search vocabulary'
|
||||
grep -Fxq 'exec "$HOME/.config/quickshell/scripts/panama-action" health' "$script" \
|
||||
|| fail 'health command bypasses the stable dispatcher path'
|
||||
fi
|
||||
|
||||
: >"$dispatch_log"
|
||||
HOME="$work/home" PANAMA_COMMAND_TEST_LOG="$dispatch_log" "$script"
|
||||
dispatched="$(cat "$dispatch_log")"
|
||||
|
||||
Reference in New Issue
Block a user