Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soften edges in UI #299

Merged
merged 3 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions KWCore/Sources/Query/CoreDataTasks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,19 @@ public class CoreDataTasks {
return query(predicate, sort)
}

/// Find tasks that have no due date
/// - Returns: Array<LogTask>
public func noDueDate() -> [LogTask] {
let predicate = NSPredicate(
format: "due == nil && (completedDate == nil && cancelledDate == nil && owner.project.company.hidden == false)"
)
let sort = [
NSSortDescriptor(keyPath: \LogTask.owner?.title, ascending: true)
]

return query(predicate, sort)
}

/// Find upcoming tasks
/// - Returns: Array<LogTask>
public func upcoming(_ date: Date = Date()) -> [LogTask] {
Expand Down
4 changes: 4 additions & 0 deletions KlockWork.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
5360429D2CBA35050030D72D /* RecordDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5360429C2CBA35020030D72D /* RecordDetail.swift */; };
536043CA2CBE06A60030D72D /* LogTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536043C92CBE06A40030D72D /* LogTask.swift */; };
536043CC2CBE0E6C0030D72D /* NotificationSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536043CB2CBE0E670030D72D /* NotificationSettings.swift */; };
536044332CBE1B1F0030D72D /* Planning.NoDueDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536044322CBE1B170030D72D /* Planning.NoDueDate.swift */; };
5363B6782A6BB2CC00C2FBB8 /* CompanyDashboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5363B6772A6BB2CC00C2FBB8 /* CompanyDashboard.swift */; };
5363B67A2A6BB75F00C2FBB8 /* CompanyBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5363B6792A6BB75F00C2FBB8 /* CompanyBlock.swift */; };
5363B67C2A6BB78900C2FBB8 /* CompanyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5363B67B2A6BB78900C2FBB8 /* CompanyView.swift */; };
Expand Down Expand Up @@ -410,6 +411,7 @@
5360429C2CBA35020030D72D /* RecordDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordDetail.swift; sourceTree = "<group>"; };
536043C92CBE06A40030D72D /* LogTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogTask.swift; sourceTree = "<group>"; };
536043CB2CBE0E670030D72D /* NotificationSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettings.swift; sourceTree = "<group>"; };
536044322CBE1B170030D72D /* Planning.NoDueDate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Planning.NoDueDate.swift; sourceTree = "<group>"; };
5363B6772A6BB2CC00C2FBB8 /* CompanyDashboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyDashboard.swift; sourceTree = "<group>"; };
5363B6792A6BB75F00C2FBB8 /* CompanyBlock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyBlock.swift; sourceTree = "<group>"; };
5363B67B2A6BB78900C2FBB8 /* CompanyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompanyView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -865,6 +867,7 @@
5354C8F42AA045C2001C1779 /* Tabs */ = {
isa = PBXGroup;
children = (
536044322CBE1B170030D72D /* Planning.NoDueDate.swift */,
533544812CB19C450067A944 /* Planning.Overdue.swift */,
5335447F2CB19C3F0067A944 /* Planning.Upcoming.swift */,
5354C8F52AA045CA001C1779 /* Planning.Today.swift */,
Expand Down Expand Up @@ -1759,6 +1762,7 @@
535DDE5E2A7982F3008350D4 /* SidebarItem.swift in Sources */,
53E202702A80984400B4DF70 /* DateSelectorWidget.swift in Sources */,
53EDDFA02963487A008D34C7 /* CustomPickerItem.swift in Sources */,
536044332CBE1B1F0030D72D /* Planning.NoDueDate.swift in Sources */,
53E2026C2A80457400B4DF70 /* JobProjectGroup.swift in Sources */,
535C1AE329F48F6800CD95FD /* Widgets.swift in Sources */,
53C000942B38E5C500D5EC04 /* TodayViewTab.swift in Sources */,
Expand Down
11 changes: 9 additions & 2 deletions KlockWork/Views/Planning/Planning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,24 @@ struct Planning: View {
// )
ToolbarButton(
id: 1,
helpText: "Upcoming",
helpText: "Incomplete tasks",
icon: "hourglass",
labelText: "Upcoming",
contents: AnyView(Planning.Upcoming())
),
ToolbarButton(
id: 2,
helpText: "Overdue",
helpText: "Overdue tasks",
icon: "alarm",
labelText: "Overdue",
contents: AnyView(Planning.Overdue())
),
ToolbarButton(
id: 3,
helpText: "Tasks that have no due date",
icon: "exclamationmark.triangle",
labelText: "No Due Date",
contents: AnyView(Planning.NoDueDate())
)
]

Expand Down
97 changes: 97 additions & 0 deletions KlockWork/Views/Planning/Tabs/Planning.NoDueDate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//
// Planning.NoDueDate.swift
// KlockWork
//
// Created by Ryan Priebe on 2024-10-14.
// Copyright © 2024 YegCollective. All rights reserved.
//

import SwiftUI
import KWCore

extension Planning {
struct NoDueDate: View {
@EnvironmentObject public var nav: Navigation
@State private var tasks: [LogTask] = []
@State private var overdue: [UpcomingRow] = []
@State private var id: UUID = UUID()
private let page: PageConfiguration.AppPage = .planning

var body: some View {
VStack(alignment: .leading, spacing: 1) {
if !self.overdue.isEmpty {
ForEach(self.overdue, id: \.id) { row in
Section {
ForEach(row.tasks) { task in
TaskItem(task: task, callback: self.actionTaskActionTap)
}
} header: {
Timestamp(text: "\(row.tasks.count) on \(row.date)", fullWidth: true, alignment: .leading, clear: true)
.background(Theme.base.opacity(0.6))
}
}
} else {
VStack(alignment: .center) {
HStack(alignment: .center) {
Text("All tasks have due dates, well done.")
.foregroundColor(.gray)
Spacer()
}
}

.padding()
.background(Theme.rowColour)
}

Spacer()
}
.id(self.id)
.onAppear(perform: self.actionOnAppear)
}
}
}

extension Planning.NoDueDate {
/// Fires when the Forecast callback is fired
/// - Returns: Void
private func actionForecastCallback() -> Void {
self.actionTaskActionTap()
}

/// Fires when a task is interacted with
/// - Returns: Void
private func actionTaskActionTap() -> Void {
self.tasks = []
self.actionOnAppear()
}

/// Onload handler
/// - Returns: Void
private func actionOnAppear() -> Void {
self.id = UUID()
self.tasks = CoreDataTasks(moc: self.nav.moc).noDueDate()
self.overdue = []
let grouped = Dictionary(grouping: self.tasks, by: {$0.due!.formatted(date: .abbreviated, time: .omitted)})
let sorted = Array(grouped)
.sorted(by: {
let df = DateFormatter()
df.dateStyle = .medium
df.timeStyle = .none
if let d1 = df.date(from: $0.key) {
if let d2 = df.date(from: $1.key) {
return d1 < d2
}
}
return false
})

for group in sorted {
self.overdue.append(
UpcomingRow(
date: group.key,
tasks: group.value.sorted(by: {$0.due! < $1.due!})
)
)
}
}
}
1 change: 1 addition & 0 deletions KlockWork/Views/Planning/Tabs/Planning.Overdue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ extension Planning {
HStack(alignment: .center) {
Text("No overdue tasks!")
.foregroundColor(.gray)
Spacer()
}
}

Expand Down
3 changes: 2 additions & 1 deletion KlockWork/Views/Planning/Tabs/Planning.Upcoming.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ extension Planning {
} else {
VStack(alignment: .center) {
HStack(alignment: .center) {
Text("No upcoming due dates")
Text("No tasks with upcoming due dates")
.foregroundColor(.gray)
Spacer()
}
}
.padding()
Expand Down
2 changes: 2 additions & 0 deletions KlockWork/Views/Shared/Fancy/FancyGenericToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ struct FancyGenericToolbar: View {
}
}
}
.clipShape(.rect(topLeadingRadius: 5, topTrailingRadius: 5))
}
}
}
Expand All @@ -118,6 +119,7 @@ struct FancyGenericToolbar: View {
ForEach(buttons, id: \ToolbarButton.id) { button in
if button.id == selected && button.contents != nil {
button.contents
.clipShape(.rect(bottomLeadingRadius: 5, bottomTrailingRadius: 5))
}
}
}
Expand Down