5.1 KiB · text History 49b9ecf
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls as QQC2
import org.kde.plasma.components as PlasmaComponents3
import org.kde.kirigami as Kirigami

import "Status.js" as Status

// What a run shows once it's open: the approval notice, its actions, its
// jobs (each with steps and logs) and its artifacts. Shared by the
// popup's accordion and the standalone run window, so both read the same
// `store` state and stay in step.
ColumnLayout {
    id: runBody

    required property var store
    required property string fullName
    required property int runNumber
    // The freshest copy of the run: the detail's once it's loaded.
    required property var run
    required property var detail
    // The run window has its own header with these; don't repeat them.
    property bool inWindow: false

    readonly property bool active: Status.isActive(run.status)

    // The JobItem showing job row `id`, if it's there yet.
    function jobItem(id) {
        for (var i = 0; i < jobRepeater.count; i++) {
            var item = jobRepeater.itemAt(i) as JobItem
            if (item && String(item.job.id) === String(id)) return item
        }
        return null
    }

    spacing: Kirigami.Units.smallSpacing

    PlasmaComponents3.BusyIndicator {
        visible: !runBody.detail
        Layout.alignment: Qt.AlignHCenter
        Layout.preferredHeight: Kirigami.Units.iconSizes.medium
    }

    // A fork's run waits for someone with write access to approve
    // it, and that happens on the pull request — say so, link there.
    ColumnLayout {
        visible: !!runBody.run.awaiting_approval
        Layout.fillWidth: true
        spacing: 0

        PlasmaComponents3.Label {
            Layout.fillWidth: true
            color: Kirigami.Theme.neutralTextColor
            text: i18n("Waiting for approval")
        }

        PlasmaComponents3.Label {
            Layout.fillWidth: true
            wrapMode: Text.WordWrap
            font: Kirigami.Theme.smallFont
            opacity: 0.7
            text: Status.approvalNotice(runBody.run)
        }

        PlasmaComponents3.ToolButton {
            visible: !!runBody.run.pull_request_number
            icon.name: "internet-web-browser"
            text: i18n("Open pull request #%1", runBody.run.pull_request_number)
            display: QQC2.AbstractButton.TextBesideIcon
            onClicked: Qt.openUrlExternally(runBody.store.api.pullUrl(runBody.fullName, runBody.run.pull_request_number))
        }
    }

    RowLayout {
        visible: !!runBody.detail
        Layout.fillWidth: true
        spacing: Kirigami.Units.smallSpacing

        PlasmaComponents3.ToolButton {
            visible: !!runBody.detail && runBody.detail.can_manage
            enabled: !runBody.store.busy
            icon.name: "view-refresh"
            text: i18n("Re-run all")
            display: QQC2.AbstractButton.TextBesideIcon
            onClicked: runBody.store.rerunRun(runBody.fullName, runBody.runNumber)
        }

        PlasmaComponents3.ToolButton {
            visible: !!runBody.detail && runBody.detail.can_manage && runBody.active
            enabled: !runBody.store.busy
            icon.name: "dialog-cancel"
            text: i18n("Cancel")
            display: QQC2.AbstractButton.TextBesideIcon
            onClicked: runBody.store.cancelRun(runBody.fullName, runBody.runNumber)
        }

        Item { Layout.fillWidth: true }

        PlasmaComponents3.ToolButton {
            visible: !runBody.inWindow
            icon.name: "window-new"
            text: i18n("Open in Window")
            display: QQC2.AbstractButton.IconOnly
            onClicked: runBody.store.openRunWindow(runBody.fullName, runBody.runNumber)
            PlasmaComponents3.ToolTip { text: i18n("Open in Window") }
        }

        PlasmaComponents3.ToolButton {
            visible: !runBody.inWindow
            icon.name: "internet-web-browser"
            text: i18n("Open")
            display: QQC2.AbstractButton.TextBesideIcon
            onClicked: Qt.openUrlExternally(runBody.store.api.webUrl(runBody.fullName, runBody.runNumber))
        }
    }

    Repeater {
        id: jobRepeater
        model: runBody.detail ? runBody.detail.jobs : []

        delegate: JobItem {
            required property var modelData
            Layout.fillWidth: true
            store: runBody.store
            fullName: runBody.fullName
            runNumber: runBody.runNumber
            job: modelData
            canManage: !!runBody.detail && runBody.detail.can_manage
        }
    }

    PlasmaComponents3.Label {
        visible: !!runBody.detail && runBody.detail.jobs.length === 0
        text: i18n("No jobs")
        opacity: 0.7
    }

    Repeater {
        model: runBody.detail ? runBody.detail.artifacts : []

        delegate: PlasmaComponents3.Label {
            required property var modelData
            Layout.fillWidth: true
            elide: Text.ElideRight
            font: Kirigami.Theme.smallFont
            opacity: 0.7
            text: "📦 " + (modelData.name || "artifact")
                  + (modelData.size ? " · " + Math.round(modelData.size / 1024) + " KiB" : "")
        }
    }
}