125 lines
3.8 KiB
QML
125 lines
3.8 KiB
QML
import QtQuick
|
|
import qs.config
|
|
import qs.services
|
|
|
|
Item {
|
|
id: root
|
|
|
|
required property var check
|
|
property bool issue: false
|
|
property bool divider: true
|
|
property int actionActivationCount: 0
|
|
signal actionRequested(var check)
|
|
|
|
objectName: `health-check-row:${root.issue ? "issue" : "quiet"}:${root.check.id}`
|
|
implicitHeight: 62
|
|
|
|
// The isolated contract uses the same signal path as a pointer or keyboard
|
|
// activation instead of calling HealthPage's action handler directly.
|
|
function activateAction(): bool {
|
|
if (!actionButton.visible || !actionButton.enabled)
|
|
return false;
|
|
root.actionActivationCount += 1;
|
|
actionButton.clicked();
|
|
return true;
|
|
}
|
|
|
|
function statusLabel(status: string): string {
|
|
if (status === "ok") return "Healthy";
|
|
if (status === "warning") return "Needs attention";
|
|
if (status === "error") return "Action required";
|
|
return "Not set up";
|
|
}
|
|
|
|
function statusColor(status: string): color {
|
|
if (status === "ok") return Theme.ok;
|
|
if (status === "warning") return Theme.warn;
|
|
if (status === "error") return Theme.danger;
|
|
return Theme.fgMuted;
|
|
}
|
|
|
|
Rectangle {
|
|
id: issueMark
|
|
|
|
visible: root.issue
|
|
width: 7
|
|
height: 7
|
|
radius: 4
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: 1
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
color: root.statusColor(root.check.status)
|
|
border.width: 1
|
|
border.color: Theme.alpha(Theme.bgPanel, 0.9)
|
|
}
|
|
|
|
Column {
|
|
anchors.left: parent.left
|
|
anchors.leftMargin: root.issue ? 22 : 0
|
|
anchors.right: trailing.left
|
|
anchors.rightMargin: 16
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 3
|
|
|
|
Text {
|
|
width: parent.width
|
|
text: root.check.title
|
|
color: Theme.fg
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSize
|
|
font.weight: Font.Medium
|
|
elide: Text.ElideRight
|
|
}
|
|
|
|
Text {
|
|
width: parent.width
|
|
text: root.check.detail
|
|
color: Theme.fgDim
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
elide: Text.ElideRight
|
|
}
|
|
}
|
|
|
|
Row {
|
|
id: trailing
|
|
|
|
anchors.right: parent.right
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
spacing: 12
|
|
|
|
Text {
|
|
objectName: `health-status-text:${root.issue ? "issue" : "quiet"}:${root.check.id}`
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: root.statusLabel(root.check.status)
|
|
color: root.statusColor(root.check.status)
|
|
font.family: Theme.fontFamily
|
|
font.pixelSize: Theme.fontSizeSmall
|
|
}
|
|
|
|
SettingsButton {
|
|
id: actionButton
|
|
|
|
objectName: `health-row-action:${root.issue ? "issue" : "quiet"}:${root.check.id}`
|
|
visible: root.check.action !== undefined
|
|
text: Health.repairingId === root.check.id ? "Working…" : (root.check.action?.label ?? "")
|
|
enabled: visible && Health.repairingId !== root.check.id && !Health.busy
|
|
activeFocusOnTab: enabled
|
|
border.width: activeFocus ? 2 : 1
|
|
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
|
onClicked: root.actionRequested(root.check)
|
|
Keys.onReturnPressed: if (enabled) root.actionRequested(root.check)
|
|
Keys.onSpacePressed: if (enabled) root.actionRequested(root.check)
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
visible: root.divider
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.bottom: parent.bottom
|
|
height: 1
|
|
color: Theme.alpha(Theme.fg, 0.07)
|
|
}
|
|
}
|