k8s-widget: add KubernetesPopout and complete bar wiring
This commit is contained in:
@@ -144,7 +144,7 @@ Scope {
|
||||
required property var modelData
|
||||
screen: modelData
|
||||
|
||||
visible: modelData.name === Shared.Config.monitor && (popoutOpen || notifSlot.animating || mediaSlot.animating || weatherSlot.animating || datetimeSlot.animating || systemSlot.animating)
|
||||
visible: modelData.name === Shared.Config.monitor && (popoutOpen || notifSlot.animating || mediaSlot.animating || weatherSlot.animating || datetimeSlot.animating || systemSlot.animating || kubernetesSlot.animating)
|
||||
WlrLayershell.namespace: "quickshell:popout"
|
||||
surfaceFormat { opaque: false }
|
||||
|
||||
@@ -212,6 +212,13 @@ Scope {
|
||||
verticalAnchor: "bottom"
|
||||
sourceComponent: Popouts.SystemPopout { panelWindow: popoutWindow }
|
||||
}
|
||||
|
||||
PopoutSlot {
|
||||
id: kubernetesSlot
|
||||
name: "kubernetes"
|
||||
verticalAnchor: "bottom"
|
||||
sourceComponent: Popouts.KubernetesPopout {}
|
||||
}
|
||||
}
|
||||
|
||||
// PopoutSlot — anchored to triggering icon, MD3 animation
|
||||
|
||||
275
dot_config/quickshell/bar/popouts/KubernetesPopout.qml
Normal file
275
dot_config/quickshell/bar/popouts/KubernetesPopout.qml
Normal file
@@ -0,0 +1,275 @@
|
||||
import Quickshell
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import "../../shared" as Shared
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitWidth: Shared.Theme.popoutWidth
|
||||
implicitHeight: col.implicitHeight + Shared.Theme.popoutPadding * 2
|
||||
|
||||
PopoutBackground { anchors.fill: parent }
|
||||
MouseArea { anchors.fill: parent }
|
||||
|
||||
component QuotaBar: Column {
|
||||
property string rowLabel: ""
|
||||
property string valueLabel: ""
|
||||
property real fill: 0
|
||||
property color barColor: Shared.Theme.green
|
||||
property real barOpacity: 1.0
|
||||
|
||||
Layout.fillWidth: true
|
||||
width: parent.width
|
||||
spacing: 3
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
Text {
|
||||
text: rowLabel
|
||||
color: Shared.Theme.overlay0
|
||||
font.pixelSize: 9
|
||||
font.family: Shared.Theme.fontFamily
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
Text {
|
||||
text: valueLabel
|
||||
color: Shared.Theme.subtext0
|
||||
font.pixelSize: 9
|
||||
font.family: Shared.Theme.fontFamily
|
||||
}
|
||||
Text {
|
||||
text: Math.round(fill * 100) + "%"
|
||||
color: barColor
|
||||
font.pixelSize: 9
|
||||
font.family: Shared.Theme.fontFamily
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 4
|
||||
color: Shared.Theme.surface1
|
||||
radius: 2
|
||||
Rectangle {
|
||||
width: Math.max(0, Math.min(1, parent.parent.fill)) * parent.width
|
||||
height: parent.height
|
||||
color: parent.parent.barColor
|
||||
opacity: parent.parent.barOpacity
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.margins: Shared.Theme.popoutPadding
|
||||
spacing: 8
|
||||
|
||||
// ── Header ────────────────────────────────────────────
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Text {
|
||||
text: "K8s — " + Shared.Config.kubeNamespace
|
||||
color: Shared.Theme.text
|
||||
font.pixelSize: 16
|
||||
font.family: Shared.Theme.fontFamily
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Text {
|
||||
text: "\u{f03be}"
|
||||
color: {
|
||||
let s = Shared.Kubernetes.status;
|
||||
if (s === "ok") return Shared.Theme.green;
|
||||
if (s === "degraded") return Shared.Theme.yellow;
|
||||
if (s === "error") return Shared.Theme.red;
|
||||
if (s === "stale") return Shared.Theme.overlay0;
|
||||
return Shared.Theme.blue;
|
||||
}
|
||||
font.pixelSize: 20
|
||||
font.family: Shared.Theme.iconFont
|
||||
}
|
||||
}
|
||||
|
||||
// ── Pods section ──────────────────────────────────────
|
||||
Text {
|
||||
text: "PODS"
|
||||
color: Shared.Theme.overlay0
|
||||
font.pixelSize: 9
|
||||
font.family: Shared.Theme.fontFamily
|
||||
font.letterSpacing: 1
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 4
|
||||
Item { Layout.fillWidth: true }
|
||||
Text { text: "CPU"; color: Shared.Theme.overlay0; font.pixelSize: 8; font.family: Shared.Theme.fontFamily; Layout.preferredWidth: 44; horizontalAlignment: Text.AlignRight }
|
||||
Text { text: "MEM"; color: Shared.Theme.overlay0; font.pixelSize: 8; font.family: Shared.Theme.fontFamily; Layout.preferredWidth: 52; horizontalAlignment: Text.AlignRight }
|
||||
Text { text: "STATUS"; color: Shared.Theme.overlay0; font.pixelSize: 8; font.family: Shared.Theme.fontFamily; Layout.preferredWidth: 62; horizontalAlignment: Text.AlignRight }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Shared.Kubernetes.pods
|
||||
delegate: Rectangle {
|
||||
required property var modelData
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 28
|
||||
color: Shared.Theme.surface0
|
||||
radius: Shared.Theme.radiusSmall
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
spacing: 4
|
||||
|
||||
Text {
|
||||
text: modelData.app
|
||||
color: Shared.Theme.text
|
||||
font.pixelSize: 11
|
||||
font.family: Shared.Theme.fontFamily
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Text {
|
||||
text: modelData.cpuM === -1 ? "—" : modelData.cpuM + "m"
|
||||
color: Shared.Theme.sky
|
||||
font.pixelSize: 11
|
||||
font.family: Shared.Theme.fontFamily
|
||||
Layout.preferredWidth: 44
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
Text {
|
||||
text: modelData.memMi === -1 ? "—" : modelData.memMi + "Mi"
|
||||
color: Shared.Theme.mauve
|
||||
font.pixelSize: 11
|
||||
font.family: Shared.Theme.fontFamily
|
||||
Layout.preferredWidth: 52
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 3
|
||||
Layout.preferredWidth: 62
|
||||
layoutDirection: Qt.RightToLeft
|
||||
Text {
|
||||
text: modelData.ready ? "Ready" : "NotReady"
|
||||
color: modelData.ready ? Shared.Theme.green : Shared.Theme.red
|
||||
font.pixelSize: 10
|
||||
font.family: Shared.Theme.fontFamily
|
||||
}
|
||||
Text {
|
||||
text: "●"
|
||||
color: modelData.ready ? Shared.Theme.green : Shared.Theme.red
|
||||
font.pixelSize: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Quota section ─────────────────────────────────────
|
||||
Text {
|
||||
text: "QUOTA"
|
||||
color: Shared.Theme.overlay0
|
||||
font.pixelSize: 9
|
||||
font.family: Shared.Theme.fontFamily
|
||||
font.letterSpacing: 1
|
||||
topPadding: 4
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
color: Shared.Theme.surface0
|
||||
radius: Shared.Theme.radiusSmall
|
||||
implicitHeight: cpuCardCol.implicitHeight + 20
|
||||
|
||||
Column {
|
||||
id: cpuCardCol
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 6
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
Text { text: "CPU"; color: Shared.Theme.sky; font.pixelSize: 10; font.family: Shared.Theme.fontFamily; font.bold: true }
|
||||
Item { Layout.fillWidth: true }
|
||||
Text {
|
||||
text: Shared.Kubernetes.quota ? Shared.Kubernetes.quota.cpuActualM + "m actual" : "—"
|
||||
color: Shared.Theme.text
|
||||
font.pixelSize: 10
|
||||
font.family: Shared.Theme.fontFamily
|
||||
}
|
||||
}
|
||||
QuotaBar {
|
||||
rowLabel: "%REQ"
|
||||
valueLabel: Shared.Kubernetes.quota?.cpuReqLabel ?? ""
|
||||
fill: Shared.Kubernetes.quota?.cpuReqPct ?? 0
|
||||
barColor: Shared.Theme.green
|
||||
}
|
||||
QuotaBar {
|
||||
rowLabel: "%LIM"
|
||||
valueLabel: Shared.Kubernetes.quota?.cpuLimLabel ?? ""
|
||||
fill: Shared.Kubernetes.quota?.cpuLimPct ?? 0
|
||||
barColor: Shared.Theme.yellow
|
||||
barOpacity: 0.6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
color: Shared.Theme.surface0
|
||||
radius: Shared.Theme.radiusSmall
|
||||
implicitHeight: memCardCol.implicitHeight + 20
|
||||
|
||||
Column {
|
||||
id: memCardCol
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.margins: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 6
|
||||
|
||||
RowLayout {
|
||||
width: parent.width
|
||||
Text { text: "MEM"; color: Shared.Theme.mauve; font.pixelSize: 10; font.family: Shared.Theme.fontFamily; font.bold: true }
|
||||
Item { Layout.fillWidth: true }
|
||||
Text {
|
||||
text: Shared.Kubernetes.quota ? Shared.Kubernetes.quota.memActualMi + "Mi actual" : "—"
|
||||
color: Shared.Theme.text
|
||||
font.pixelSize: 10
|
||||
font.family: Shared.Theme.fontFamily
|
||||
}
|
||||
}
|
||||
QuotaBar {
|
||||
rowLabel: "%REQ"
|
||||
valueLabel: Shared.Kubernetes.quota?.memReqLabel ?? ""
|
||||
fill: Shared.Kubernetes.quota?.memReqPct ?? 0
|
||||
barColor: Shared.Theme.mauve
|
||||
}
|
||||
QuotaBar {
|
||||
rowLabel: "%LIM"
|
||||
valueLabel: Shared.Kubernetes.quota?.memLimLabel ?? ""
|
||||
fill: Shared.Kubernetes.quota?.memLimPct ?? 0
|
||||
barColor: Shared.Theme.mauve
|
||||
barOpacity: 0.6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── Footer ────────────────────────────────────────────
|
||||
Text {
|
||||
text: "Updated " + Shared.Kubernetes.lastUpdatedSecs + "s ago"
|
||||
color: Shared.Theme.overlay0
|
||||
font.pixelSize: 9
|
||||
font.family: Shared.Theme.fontFamily
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user