Skip to content

Commit

Permalink
Merge pull request #299 from aapis/feature/1.12/soften-ui
Browse files Browse the repository at this point in the history
Soften edges in UI
  • Loading branch information
aapis authored Oct 15, 2024
2 parents 0e272d6 + c834d66 commit 44e6bad
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 3 deletions.
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

0 comments on commit 44e6bad

Please sign in to comment.