The public tree and its history contain only the listed paths. Earlier projection history remains preserved internally. Source-Sha: 913fde029b935671833254797f0f20f1eb9fabba Policy-Sha: 913fde029b935671833254797f0f20f1eb9fabba Tree-Digest: 180ae530c1058a2a5c89837bdce2d323ae83e669e38590ca72e75b8d92b7262f
92 lines
3.6 KiB
QML
92 lines
3.6 KiB
QML
import QtQuick
|
|
import QtQuick.Controls.Basic
|
|
import QtQuick.Layouts
|
|
|
|
Rectangle {
|
|
id: root
|
|
property var snapshot: ({})
|
|
property bool running: false
|
|
readonly property var scanners: Object.keys(snapshot.scanners || {}).sort().map(key => snapshot.scanners[key])
|
|
implicitHeight: body.implicitHeight + 24
|
|
color: Theme.surface
|
|
border.color: Theme.divider
|
|
radius: Theme.radius
|
|
|
|
function stamp(value) {
|
|
return !value || String(value).indexOf("0001-") === 0 ? "Not scanned yet" : new Date(value).toLocaleString();
|
|
}
|
|
|
|
ColumnLayout {
|
|
id: body
|
|
anchors { left: parent.left; right: parent.right; top: parent.top; margins: 12 }
|
|
spacing: 8
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Rectangle { width: 7; height: 7; color: root.running ? Theme.warn : Theme.blue }
|
|
Text {
|
|
Layout.fillWidth: true
|
|
text: root.running ? "SCANNING THIS MACHINE" : "SCAN STATUS"
|
|
color: Theme.blue
|
|
font { pixelSize: Theme.fontMeta; bold: true; letterSpacing: 1 }
|
|
}
|
|
Text {
|
|
text: root.stamp(root.snapshot.last_scan_time)
|
|
color: Theme.dim
|
|
font.pixelSize: Theme.fontMeta
|
|
}
|
|
}
|
|
Text {
|
|
visible: !root.scanners.length
|
|
Layout.fillWidth: true
|
|
text: root.running ? "The Agent is checking available package sources." : "No scanner results yet. Run a scan to establish update coverage."
|
|
color: Theme.dim
|
|
wrapMode: Text.Wrap
|
|
font.pixelSize: Theme.fontBody
|
|
}
|
|
Repeater {
|
|
model: root.scanners
|
|
ColumnLayout {
|
|
required property var modelData
|
|
Layout.fillWidth: true
|
|
spacing: 3
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Text {
|
|
text: String(modelData.name).toUpperCase()
|
|
Layout.preferredWidth: 90
|
|
color: Theme.text
|
|
font { family: Theme.mono; pixelSize: Theme.fontMeta; bold: true }
|
|
}
|
|
Text {
|
|
Layout.fillWidth: true
|
|
text: modelData.status === "success" ? modelData.update_count + " available" : String(modelData.status || "unknown")
|
|
color: modelData.status === "success" ? Theme.good : Theme.warn
|
|
font.pixelSize: Theme.fontMeta
|
|
}
|
|
Text {
|
|
text: (Number(modelData.last_duration_ms || 0) / 1000).toFixed(1) + "s · " + root.stamp(modelData.last_scan_time)
|
|
color: Theme.faint
|
|
font.pixelSize: Theme.fontMeta
|
|
}
|
|
}
|
|
Text {
|
|
Layout.fillWidth: true
|
|
visible: Boolean(modelData.last_error)
|
|
text: modelData.last_error || ""
|
|
textFormat: Text.PlainText
|
|
color: Theme.bad
|
|
wrapMode: Text.Wrap
|
|
font.pixelSize: Theme.fontMeta
|
|
}
|
|
}
|
|
}
|
|
Text {
|
|
visible: root.scanners.some(s => s.status !== "success")
|
|
Layout.fillWidth: true
|
|
text: "A source did not complete. Its previous update observations may still be listed below."
|
|
color: Theme.warn
|
|
wrapMode: Text.Wrap
|
|
font.pixelSize: Theme.fontMeta
|
|
}
|
|
}
|
|
}
|