This commit is contained in:
timka123 committed 2026-10-18 18:02:05 +03:00
commit 17a0a3c4c9
121 files changed
+17641

No files matched your search

+180
View File
@@ -0,0 +1,180 @@
// Everything you owe, from every source, grouped by deadline.
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Layouts
import "components"
Item {
id: page
function bucketTasks(bucket) {
var out = []
for (var i = 0; i < controller.tasks.length; i++) {
var task = controller.tasks[i]
if (!task.is_done && task.bucket === bucket) out.push(task)
}
return out
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 20
spacing: 12
RowLayout {
Layout.fillWidth: true
spacing: 8
Label {
text: controller.tasks.length + " open"
font.pixelSize: 13
opacity: 0.7
}
Item { Layout.fillWidth: true }
Button { text: "+ Add"; onClicked: addDialog.open() }
PrimaryButton { text: "⟳ Refresh sources"; onClicked: controller.refreshSources() }
}
ScrollView {
Layout.fillWidth: true
Layout.fillHeight: true
contentWidth: availableWidth
clip: true
ColumnLayout {
width: parent.parent.availableWidth
spacing: 12
Repeater {
model: [
{ key: "overdue", label: "Overdue", mark: "🔴" },
{ key: "today", label: "Due today", mark: "🟡" },
{ key: "upcoming", label: "Coming up", mark: "🔵" },
{ key: "someday", label: "No deadline", mark: "⚪" }
]
delegate: Card {
required property var modelData
property var items: page.bucketTasks(modelData.key)
visible: items.length > 0
title: modelData.mark + " " + modelData.label + " (" + items.length + ")"
Repeater {
model: parent.parent.items
delegate: RowLayout {
required property var modelData
Layout.fillWidth: true
spacing: 10
CheckBox {
checked: modelData.is_done
onToggled: controller.setTaskDone(modelData.id, checked)
}
ColumnLayout {
Layout.fillWidth: true
spacing: 2
Label {
text: modelData.title
font.pixelSize: 14
elide: Text.ElideRight
Layout.fillWidth: true
}
RowLayout {
spacing: 6
Label {
text: modelData.source_label
font.pixelSize: 10
opacity: 0.65
}
Label {
visible: !!modelData.project
text: "· " + modelData.project
font.pixelSize: 10
opacity: 0.65
}
Label {
visible: modelData.days_overdue > 0
text: "· " + modelData.days_overdue + "d overdue"
font.pixelSize: 10
color: "#e34948"
}
Label {
visible: !!modelData.due_date && modelData.days_overdue === 0
text: "· " + modelData.due_date
font.pixelSize: 10
opacity: 0.65
}
Label {
visible: !!modelData.priority
text: "· " + modelData.priority
font.pixelSize: 10
opacity: 0.65
}
}
}
ToolButton {
text: "↗"
visible: !!modelData.url
onClicked: controller.openUrl(modelData.url)
ToolTip.visible: hovered
ToolTip.text: "Open in " + modelData.source_label
}
ToolButton {
text: "▶"
onClicked: { controller.attachTask(modelData.id); controller.startWork(); window.page = 0 }
ToolTip.visible: hovered
ToolTip.text: "Start a pomodoro on this"
}
}
}
}
}
Card {
visible: controller.tasks.length === 0
title: "Nothing on the list"
subtitle: "Connect Jira, Todoist or Google Tasks in Settings → Sources, "
+ "or add something here yourself."
Button {
text: "Open settings"
onClicked: window.page = 4
}
}
}
}
}
Dialog {
id: addDialog
anchors.centerIn: Overlay.overlay
width: 380
modal: true
title: "New task"
standardButtons: Dialog.Cancel
ColumnLayout {
anchors.fill: parent
spacing: 10
TextField {
id: titleField
Layout.fillWidth: true
placeholderText: "What needs doing?"
}
TextField {
id: dueField
Layout.fillWidth: true
placeholderText: "Due date (YYYY-MM-DD, optional)"
inputMask: ""
}
PrimaryButton {
text: "Add"
enabled: titleField.text.trim() !== ""
Layout.alignment: Qt.AlignRight
onClicked: {
controller.createTask(titleField.text.trim(), dueField.text.trim())
titleField.text = ""; dueField.text = ""
addDialog.close()
}
}
}
}
}