mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
- Introduced `LanguageSelector.qml` for selecting application languages with a user-friendly interface. - Created `NerdPanel.qml` to display API logs, session information, and keyboard shortcuts in a dedicated panel. - Implemented `PatchDialog.qml` for viewing and managing Git patches, including copy and save functionalities. - Developed `SendPromptDialog.qml` for sending prompts to Codex, featuring environment selection and input validation. - Added `TaskListItem.qml` to represent individual tasks with detailed information and PR indicators. - Introduced `ThemeSelector.qml` for selecting application themes with visual indicators.
403 lines
16 KiB
QML
403 lines
16 KiB
QML
import QtQuick
|
|
import QtQuick.Controls
|
|
import QtQuick.Layouts
|
|
|
|
Item {
|
|
id: root
|
|
|
|
property int taskIndex: -1
|
|
property string taskJson: ""
|
|
property var taskData: taskJson ? JSON.parse(taskJson) : null
|
|
property bool nerdMode: false
|
|
property var themeColors: ({})
|
|
|
|
signal archiveClicked()
|
|
signal prClicked()
|
|
signal patchClicked()
|
|
|
|
ColumnLayout {
|
|
anchors.fill: parent
|
|
spacing: 12
|
|
|
|
// Header with actions
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 8
|
|
|
|
Label {
|
|
text: taskIndex >= 0 ? "Task #" + (taskIndex + 1) : "Select a task"
|
|
font.bold: true
|
|
font.pixelSize: 18
|
|
color: themeColors.windowText || "#ffffff"
|
|
}
|
|
|
|
Item { Layout.fillWidth: true }
|
|
|
|
Button {
|
|
text: "📋 Patch"
|
|
enabled: taskIndex >= 0
|
|
onClicked: root.patchClicked()
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: "Extract git patch (Ctrl+P)"
|
|
|
|
background: Rectangle {
|
|
color: parent.hovered ? (themeColors.alternateBase || "#242424") : (themeColors.base || "#1a1a1a")
|
|
radius: 4
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: themeColors.windowText || "#ffffff"
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "🔀 Create PR"
|
|
enabled: taskIndex >= 0 && taskData && !taskData.pull_request
|
|
onClicked: root.prClicked()
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: "Create pull request"
|
|
|
|
background: Rectangle {
|
|
color: parent.enabled ? (themeColors.accent || "#10a37f") : (themeColors.mid || "#333333")
|
|
radius: 4
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: "#ffffff"
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
|
|
Button {
|
|
text: "✓ Archive"
|
|
enabled: taskIndex >= 0
|
|
onClicked: root.archiveClicked()
|
|
ToolTip.visible: hovered
|
|
ToolTip.text: "Archive this task"
|
|
|
|
background: Rectangle {
|
|
color: parent.hovered ? (themeColors.alternateBase || "#242424") : (themeColors.base || "#1a1a1a")
|
|
radius: 4
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: themeColors.windowText || "#ffffff"
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
}
|
|
}
|
|
}
|
|
|
|
// Task summary card
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: summaryColumn.implicitHeight + 24
|
|
color: themeColors.alternateBase || "#242424"
|
|
radius: 8
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
visible: taskIndex >= 0 && taskData
|
|
|
|
ColumnLayout {
|
|
id: summaryColumn
|
|
anchors.fill: parent
|
|
anchors.margins: 12
|
|
spacing: 8
|
|
|
|
// Title
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: taskData ? (taskData.title || "Untitled Task") : ""
|
|
font.bold: true
|
|
font.pixelSize: 16
|
|
wrapMode: Text.Wrap
|
|
color: themeColors.windowText || "#ffffff"
|
|
}
|
|
|
|
// Repository & Branch
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 16
|
|
|
|
Label {
|
|
text: "📁 " + (taskData && taskData.repository ? taskData.repository.full_name : "")
|
|
opacity: 0.8
|
|
visible: taskData && taskData.repository
|
|
color: themeColors.windowText || "#ffffff"
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
cursorShape: Qt.PointingHandCursor
|
|
onClicked: {
|
|
if (taskData && taskData.repository) {
|
|
app.openUrl("https://github.com/" + taskData.repository.full_name)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
text: "🌿 " + (taskData ? (taskData.head_branch || taskData.branch || "") : "")
|
|
opacity: 0.8
|
|
visible: taskData && (taskData.head_branch || taskData.branch)
|
|
color: themeColors.windowText || "#ffffff"
|
|
}
|
|
}
|
|
|
|
// Status & PR
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 16
|
|
|
|
// Status badge
|
|
Label {
|
|
text: taskData ? (taskData.status || "unknown") : ""
|
|
font.pixelSize: 12
|
|
padding: 4
|
|
leftPadding: 10
|
|
rightPadding: 10
|
|
background: Rectangle {
|
|
radius: 4
|
|
color: {
|
|
if (!taskData) return themeColors.mid || "#333333"
|
|
switch(taskData.status) {
|
|
case "completed": return themeColors.success || "#22c55e"
|
|
case "running": return themeColors.info || "#3b82f6"
|
|
case "failed": return themeColors.error || "#ef4444"
|
|
case "queued": return themeColors.warning || "#f59e0b"
|
|
default: return themeColors.mid || "#333333"
|
|
}
|
|
}
|
|
}
|
|
color: "white"
|
|
}
|
|
|
|
// PR link
|
|
Label {
|
|
text: "🔀 View Pull Request"
|
|
visible: taskData && taskData.pull_request
|
|
color: themeColors.accent || "#10a37f"
|
|
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
cursorShape: Qt.PointingHandCursor
|
|
hoverEnabled: true
|
|
onClicked: {
|
|
var pr = taskData.pull_request
|
|
var url = pr.html_url || pr.url || ""
|
|
if (url) app.openUrl(url)
|
|
}
|
|
onEntered: parent.font.underline = true
|
|
onExited: parent.font.underline = false
|
|
}
|
|
}
|
|
|
|
Item { Layout.fillWidth: true }
|
|
|
|
// Created date
|
|
Label {
|
|
text: taskData && taskData.created_at ? ("Created: " + taskData.created_at.substring(0, 10)) : ""
|
|
opacity: 0.6
|
|
font.pixelSize: 12
|
|
color: themeColors.textSecondary || themeColors.windowText || "#a0a0a0"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tabs for different views
|
|
TabBar {
|
|
id: tabBar
|
|
Layout.fillWidth: true
|
|
visible: taskIndex >= 0
|
|
|
|
background: Rectangle {
|
|
color: themeColors.base || "#1a1a1a"
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
radius: 4
|
|
}
|
|
|
|
TabButton {
|
|
text: "📝 Details"
|
|
background: Rectangle {
|
|
color: tabBar.currentIndex === 0 ? (themeColors.alternateBase || "#242424") : "transparent"
|
|
radius: 4
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: tabBar.currentIndex === 0 ? (themeColors.accent || "#10a37f") : (themeColors.textSecondary || "#a0a0a0")
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.pixelSize: 13
|
|
}
|
|
}
|
|
TabButton {
|
|
text: "💬 Prompt"
|
|
background: Rectangle {
|
|
color: tabBar.currentIndex === 1 ? (themeColors.alternateBase || "#242424") : "transparent"
|
|
radius: 4
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: tabBar.currentIndex === 1 ? (themeColors.accent || "#10a37f") : (themeColors.textSecondary || "#a0a0a0")
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.pixelSize: 13
|
|
}
|
|
}
|
|
TabButton {
|
|
text: "🔧 Raw JSON"
|
|
background: Rectangle {
|
|
color: tabBar.currentIndex === 2 ? (themeColors.alternateBase || "#242424") : "transparent"
|
|
radius: 4
|
|
}
|
|
contentItem: Text {
|
|
text: parent.text
|
|
color: tabBar.currentIndex === 2 ? (themeColors.accent || "#10a37f") : (themeColors.textSecondary || "#a0a0a0")
|
|
horizontalAlignment: Text.AlignHCenter
|
|
verticalAlignment: Text.AlignVCenter
|
|
font.pixelSize: 13
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tab content
|
|
StackLayout {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
currentIndex: tabBar.currentIndex
|
|
visible: taskIndex >= 0
|
|
|
|
// Details tab
|
|
ScrollView {
|
|
clip: true
|
|
|
|
ColumnLayout {
|
|
width: parent.width
|
|
spacing: 12
|
|
|
|
// Turn info if available
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: turnsColumn.implicitHeight + 16
|
|
color: themeColors.base || "#1a1a1a"
|
|
radius: 4
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
visible: taskData && taskData.turns && taskData.turns.length > 0
|
|
|
|
ColumnLayout {
|
|
id: turnsColumn
|
|
anchors.fill: parent
|
|
anchors.margins: 8
|
|
spacing: 4
|
|
|
|
Label {
|
|
text: "Turns: " + (taskData && taskData.turns ? taskData.turns.length : 0)
|
|
font.bold: true
|
|
}
|
|
|
|
Label {
|
|
text: taskData && taskData.current_turn_id ? ("Current: " + taskData.current_turn_id.substring(0, 8) + "...") : ""
|
|
opacity: 0.7
|
|
font.pixelSize: 12
|
|
}
|
|
}
|
|
}
|
|
|
|
// Placeholder for more structured details
|
|
Label {
|
|
Layout.fillWidth: true
|
|
text: "Select 'Raw JSON' tab to see full task details"
|
|
opacity: 0.5
|
|
horizontalAlignment: Text.AlignHCenter
|
|
visible: !(taskData && taskData.turns && taskData.turns.length > 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Prompt tab
|
|
ScrollView {
|
|
clip: true
|
|
|
|
TextArea {
|
|
text: {
|
|
if (!taskData) return ""
|
|
// Try to find the prompt in various locations
|
|
if (taskData.prompt) return taskData.prompt
|
|
if (taskData.input_items) {
|
|
for (var i = 0; i < taskData.input_items.length; i++) {
|
|
var item = taskData.input_items[i]
|
|
if (item.content) {
|
|
for (var j = 0; j < item.content.length; j++) {
|
|
if (item.content[j].text) {
|
|
return item.content[j].text
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return taskData.title || "No prompt found"
|
|
}
|
|
readOnly: true
|
|
font.pixelSize: 14
|
|
wrapMode: Text.Wrap
|
|
selectByMouse: true
|
|
color: themeColors.windowText || "#ffffff"
|
|
background: Rectangle {
|
|
color: themeColors.base || "#1a1a1a"
|
|
radius: 4
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
}
|
|
}
|
|
}
|
|
|
|
// Raw JSON tab
|
|
ScrollView {
|
|
clip: true
|
|
|
|
TextArea {
|
|
id: detailText
|
|
text: taskJson || "No task selected"
|
|
readOnly: true
|
|
font.family: "SF Mono, Monaco, Consolas, monospace"
|
|
font.pixelSize: 12
|
|
wrapMode: Text.Wrap
|
|
selectByMouse: true
|
|
background: Rectangle {
|
|
color: themeColors.codeBackground || "#1a1a1a"
|
|
radius: 4
|
|
border.color: themeColors.border || "#333333"
|
|
border.width: 1
|
|
}
|
|
color: themeColors.codeText || "#e0e0e0"
|
|
}
|
|
}
|
|
}
|
|
|
|
// Empty state
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
visible: taskIndex < 0
|
|
|
|
Label {
|
|
anchors.centerIn: parent
|
|
text: "← Select a task to view details"
|
|
opacity: 0.5
|
|
font.pixelSize: 16
|
|
color: themeColors.windowText || "#ffffff"
|
|
}
|
|
}
|
|
}
|
|
}
|