Skip to content

Commit

Permalink
Merge pull request #335 from aapis/feature/1.18/entity-timeline
Browse files Browse the repository at this point in the history
Entity timeline
  • Loading branch information
aapis authored Nov 12, 2024
2 parents 4e19edb + 8079322 commit 3940fca
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 155 deletions.
9 changes: 3 additions & 6 deletions KWCore/Sources/Query/CDSavedSearch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ public class CDSavedSearch: ObservableObject {
/// Find all saved searches
/// - Returns: [SavedSearch]
public func all() -> [SavedSearch] {
let predicate = NSPredicate(
format: "created < %@",
Date() as CVarArg
)

return self.query(predicate)
return self.query(NSPredicate(
format: "alive == true"
))
}

/// Find all saved searches
Expand Down
4 changes: 3 additions & 1 deletion KWCore/Sources/Query/CoreDataRecords.swift
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,9 @@ public class CoreDataRecords: ObservableObject {
/// - Returns: Array<LogRecord>
public func inRange(start: Date, end: Date) -> [LogRecord] {
let predicate = NSPredicate(
format: "timestamp > %@ && timestamp <= %@",
format: "timestamp > %@ && timestamp <= %@ || lastUpdate > %@ && lastUpdate <= %@",
start as CVarArg,
end as CVarArg,
start as CVarArg,
end as CVarArg
)
Expand Down
59 changes: 40 additions & 19 deletions KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Buttons.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,21 @@ extension WidgetLibrary.UI {
public var isAlteredForReadability: Bool = false

var body: some View {
if self.state.session.job != nil || self.state.session.project != nil || self.state.session.company != nil {
FancyButtonv2(
text: "Reset interface to default state",
action: self.onActionClear != nil ? self.onActionClear : self.defaultClearAction,
icon: "arrow.clockwise.square.fill",
iconWhenHighlighted: "arrow.clockwise.square",
fgColour: self.viewModeIndex == 1 ? self.isAlteredForReadability ? Theme.base : .white : .white,
showLabel: false,
size: .small,
type: .clear,
font: .title
)
.help("Reset interface to default state")
.frame(width: 25)
} else {
EmptyView()
}
FancyButtonv2(
text: "Reset interface to default state",
action: self.onActionClear != nil ? self.onActionClear : self.defaultClearAction,
icon: "arrow.clockwise.square.fill",
iconWhenHighlighted: "arrow.clockwise.square",
fgColour: self.viewModeIndex == 1 ? self.isAlteredForReadability ? Theme.base : .white : .white,
showLabel: false,
size: .small,
type: .clear,
font: .title
)
.disabled(self.state.session.job == nil && self.state.session.project == nil && self.state.session.company == nil)
.help("Reset interface to default state")
.keyboardShortcut("r", modifiers: [.control, .shift])
.frame(width: 25)
}
}

Expand Down Expand Up @@ -440,7 +438,7 @@ extension WidgetLibrary.UI {
action: {self.isSidebarPresented.toggle()},
icon: "sidebar.left",
iconWhenHighlighted: "sidebar.left",
fgColour: self.isSidebarPresented ? .gray : .white,
iconFgColour: self.isSidebarPresented ? self.state.theme.tint : .gray,
showLabel: false,
size: .small,
type: .clear,
Expand Down Expand Up @@ -506,7 +504,8 @@ extension WidgetLibrary.UI {
Text(savedSearch.term ?? "Invalid term name")
Spacer()
if let timestamp = savedSearch.created?.formatted(date: .abbreviated, time: .shortened) {
Timestamp(text: timestamp, alignment: .trailing)
Text(timestamp)
.foregroundStyle(.gray)
}
}
.padding(8)
Expand Down Expand Up @@ -538,6 +537,28 @@ extension WidgetLibrary.UI {
}
}
}

// MARK: SmallOpen
struct SmallOpen: View {
var callback: () -> Void
@State private var isHighlighted: Bool = false

var body: some View {
Button {
self.callback()
} label: {
Text("Open")
.font(.caption)
.foregroundStyle(Theme.base)
.padding(6)
.padding([.leading, .trailing], 8)
.background(.white.opacity(self.isHighlighted ? 1 : 0.8))
.clipShape(.capsule(style: .continuous))
}
.buttonStyle(.plain)
.useDefaultHover({ hover in self.isHighlighted = hover})
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ extension WidgetLibrary.UI {
VStack {
HStack {
Spacer()
Text(DateHelper.todayShort(self.date, format: "EEE"))
Text(DateHelper.todayShort(self.date, format: "EEE dd"))
.bold(self.isToday || self.isSelected)
.padding([.top, .bottom], 4)
.opacity(self.isToday ? 1 : 0.8)
Expand All @@ -237,9 +237,6 @@ extension WidgetLibrary.UI {
}
}
}
Text(DateHelper.todayShort(self.date, format: "dd"))
.bold(self.isToday || self.isSelected)
.font(.system(size: 25))
}
}
}
Expand Down Expand Up @@ -789,8 +786,19 @@ extension WidgetLibrary.UI.EntityCalendar.Day {
let jobs = CoreDataTasks(moc: self.state.moc)
.jobsForTasksDueToday(self.date)
.sorted(by: {$0.created ?? Date() < $1.created ?? Date()})
for job in jobs {
self.colourData.insert(job.backgroundColor)
if !jobs.isEmpty {
for job in jobs {
self.colourData.insert(job.backgroundColor)
}
} else {
let records = CoreDataRecords(moc: self.state.moc).forDate(self.date)
if !records.isEmpty {
for record in records {
if let colour = record.job?.backgroundColor {
self.colourData.insert(colour)
}
}
}
}
}
}
Expand Down Expand Up @@ -830,8 +838,20 @@ extension WidgetLibrary.UI.EntityCalendar.DayBlock {
let jobs = CoreDataTasks(moc: self.state.moc)
.jobsForTasksDueToday(self.date)
.sorted(by: {$0.created ?? Date() < $1.created ?? Date()})
for job in jobs {
self.colourData.insert(job.backgroundColor)

if !jobs.isEmpty {
for job in jobs {
self.colourData.insert(job.backgroundColor)
}
} else {
let records = CoreDataRecords(moc: self.state.moc).forDate(self.date)
if !records.isEmpty {
for record in records {
if let colour = record.job?.backgroundColor {
self.colourData.insert(colour)
}
}
}
}
}
}
Expand Down Expand Up @@ -890,8 +910,10 @@ extension WidgetLibrary.UI.EntityCalendar.Year {
let jobs = CoreDataTasks(moc: self.state.moc)
.jobsForTasksDueToday(self.date)
.sorted(by: {$0.created ?? Date() < $1.created ?? Date()})
for job in jobs {
self.colourData.insert(job.backgroundColor)
if !jobs.isEmpty {
for job in jobs {
self.colourData.insert(job.backgroundColor)
}
}
}
}
Expand Down
64 changes: 56 additions & 8 deletions KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Explore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ extension WidgetLibrary.UI {
// MARK: Explore.Visualization.Timeline
struct Timeline {
enum TimelineTab: CaseIterable {
case day, week, month, year, custom
case day, week, month, year, entity, custom

var icon: String {
switch self {
case .day: "d.square.fill"
case .week: "w.square.fill"
case .month: "m.square.fill"
case .year: "y.square.fill"
case .entity: "e.square.fill"
case .custom: "c.square.fill"
}
}
Expand All @@ -33,7 +34,8 @@ extension WidgetLibrary.UI {
case .week: 1
case .month: 2
case .year: 3
case .custom: 4
case .entity: 4
case .custom: 5
}
}

Expand All @@ -43,6 +45,7 @@ extension WidgetLibrary.UI {
case .week: "Show 1 week"
case .month: "Show 1 month"
case .year: "Show 1 year"
case .entity: "Show timeline(s) for the selected entities"
case .custom: "Custom range"
}
}
Expand All @@ -53,6 +56,7 @@ extension WidgetLibrary.UI {
case .week: "Week"
case .month: "Month"
case .year: "Year"
case .entity: "Entity"
case .custom: "Custom Range"
}
}
Expand All @@ -63,6 +67,7 @@ extension WidgetLibrary.UI {
case .week: AnyView(ByWeek())
case .month: AnyView(ByMonth())
case .year: AnyView(ByYear())
case .entity: AnyView(ByEntity())
case .custom: AnyView(ByCustomRange())
}
}
Expand All @@ -78,6 +83,7 @@ extension WidgetLibrary.UI {
}
}

// MARK: Timeline.Widget
struct Widget: View {
@EnvironmentObject public var nav: Navigation
private var tabs: [ToolbarButton] = []
Expand All @@ -104,7 +110,7 @@ extension WidgetLibrary.UI {
}
}

// MARK: ByDay
// MARK: Timeline.ByDay
struct ByDay: View {
@EnvironmentObject public var state: Navigation
@AppStorage("settings.accessibility.showUIHints") private var showUIHints: Bool = true
Expand Down Expand Up @@ -156,7 +162,7 @@ extension WidgetLibrary.UI {
}
}

// MARK: ByWeek
// MARK: Timeline.ByWeek
struct ByWeek: View {
@EnvironmentObject public var state: Navigation
@AppStorage("settings.accessibility.showUIHints") private var showUIHints: Bool = true
Expand Down Expand Up @@ -190,14 +196,13 @@ extension WidgetLibrary.UI {
period: .week,
format: "w"
)
.frame(maxHeight: 200)
}
}
}
}
}

// MARK: ByMonth
// MARK: Timeline.ByMonth
struct ByMonth: View {
@EnvironmentObject public var state: Navigation
@AppStorage("settings.accessibility.showUIHints") private var showUIHints: Bool = true
Expand All @@ -218,24 +223,30 @@ extension WidgetLibrary.UI {
GridRow {
UI.SuggestedLinksInRange(
period: .month,
start: self.state.session.date.startOfMonth,
end: self.state.session.date.endOfMonth,
format: "MMMM"
)
UI.SavedSearchTermsInRange(
period: .month,
start: self.state.session.date.startOfMonth,
end: self.state.session.date.endOfMonth,
format: "MMMM"
)
}
}
FancyDivider()
UI.InteractionsInRange(
period: .month,
start: self.state.session.date.startOfMonth,
end: self.state.session.date.endOfMonth,
format: "MMMM"
)
}
}
}

// MARK: ByYear
// MARK: Timeline.ByYear
struct ByYear: View {
@EnvironmentObject public var state: Navigation
@AppStorage("settings.accessibility.showUIHints") private var showUIHints: Bool = true
Expand Down Expand Up @@ -279,7 +290,7 @@ extension WidgetLibrary.UI {
}
}

// MARK: ByCustomRange
// MARK: Timeline.ByCustomRange
struct ByCustomRange: View {
@EnvironmentObject public var state: Navigation
@AppStorage("settings.accessibility.showUIHints") private var showUIHints: Bool = true
Expand Down Expand Up @@ -329,6 +340,43 @@ extension WidgetLibrary.UI {
}
}
}

// MARK: Timeline.ByEntity
struct ByEntity: View {
@EnvironmentObject public var state: Navigation
@AppStorage("settings.accessibility.showUIHints") private var showUIHints: Bool = true
@State private var start: Date = Date()
@State private var end: Date = Date() + 86400
private var twoCol: [GridItem] { Array(repeating: .init(.flexible(minimum: 100)), count: 2) }

var body: some View {
VStack(alignment: .leading, spacing: 0) {
VStack(alignment: .leading) {
UI.SearchTypeFilter()
}
.background(self.state.session.appPage.primaryColour)
.clipShape(.rect(topTrailingRadius: 5))
.clipShape(.rect(bottomLeadingRadius: self.showUIHints ? 0 : 5, bottomTrailingRadius: self.showUIHints ? 0 : 5))
FancyHelpText(
text: "Show dates and times for the selected entities",
page: self.state.session.appPage
)
FancyDivider()
LazyVGrid(columns: self.twoCol, alignment: .leading) {
GridRow {
UI.DaysWhereMentioned()
UI.SuggestedLinksInRange(
period: .custom,
start: self.state.session.date.startOfDay,
end: self.state.session.date.endOfDay
)
}
}
FancyDivider()
ActivityFeed()
}
}
}
}
}

Expand Down
Loading

0 comments on commit 3940fca

Please sign in to comment.