diff --git a/KWCore/Sources/Query/CDSavedSearch.swift b/KWCore/Sources/Query/CDSavedSearch.swift index f77d0c48..8c322a51 100644 --- a/KWCore/Sources/Query/CDSavedSearch.swift +++ b/KWCore/Sources/Query/CDSavedSearch.swift @@ -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 diff --git a/KWCore/Sources/Query/CoreDataRecords.swift b/KWCore/Sources/Query/CoreDataRecords.swift index 70393b1b..11e19c27 100644 --- a/KWCore/Sources/Query/CoreDataRecords.swift +++ b/KWCore/Sources/Query/CoreDataRecords.swift @@ -592,7 +592,9 @@ public class CoreDataRecords: ObservableObject { /// - Returns: Array 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 ) diff --git a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Buttons.swift b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Buttons.swift index 9a73f36b..7b270aef 100644 --- a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Buttons.swift +++ b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Buttons.swift @@ -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) } } @@ -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, @@ -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) @@ -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}) + } + } } } diff --git a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.EntityCalendar.swift b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.EntityCalendar.swift index b807d3b1..6764647d 100644 --- a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.EntityCalendar.swift +++ b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.EntityCalendar.swift @@ -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) @@ -237,9 +237,6 @@ extension WidgetLibrary.UI { } } } - Text(DateHelper.todayShort(self.date, format: "dd")) - .bold(self.isToday || self.isSelected) - .font(.system(size: 25)) } } } @@ -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) + } + } + } } } } @@ -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) + } + } + } } } } @@ -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) + } } } } diff --git a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Explore.swift b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Explore.swift index 51b1b695..7d2b1a76 100644 --- a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Explore.swift +++ b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.Explore.swift @@ -15,7 +15,7 @@ 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 { @@ -23,6 +23,7 @@ extension WidgetLibrary.UI { 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" } } @@ -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 } } @@ -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" } } @@ -53,6 +56,7 @@ extension WidgetLibrary.UI { case .week: "Week" case .month: "Month" case .year: "Year" + case .entity: "Entity" case .custom: "Custom Range" } } @@ -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()) } } @@ -78,6 +83,7 @@ extension WidgetLibrary.UI { } } + // MARK: Timeline.Widget struct Widget: View { @EnvironmentObject public var nav: Navigation private var tabs: [ToolbarButton] = [] @@ -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 @@ -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 @@ -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 @@ -218,10 +223,14 @@ 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" ) } @@ -229,13 +238,15 @@ extension WidgetLibrary.UI { 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 @@ -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 @@ -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() + } + } + } } } diff --git a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.swift b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.swift index 5d01aae2..e8e61362 100644 --- a/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.swift +++ b/KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.swift @@ -309,27 +309,30 @@ extension WidgetLibrary { } if !self.isMinimized { if self.activity.source != nil { - HStack { + HStack(alignment: .top) { switch self.activity.source { case is NoteVersion: Text("Found in note \"\((self.activity.source as? NoteVersion)?.note?.title ?? "Error: Note not found")\"") .foregroundStyle(.gray) Spacer() - Button { + UI.Buttons.SmallOpen(callback: { if let entity = self.activity.source as? NoteVersion { - self.state.session.note = entity.note self.state.to(.noteDetail) + self.state.session.note = entity.note } - } label: { - Text("Open") - .font(.caption) - .foregroundStyle(Theme.base) - .padding(6) - .padding([.leading, .trailing], 8) - .background(.white) - .clipShape(.capsule(style: .continuous)) - } - .buttonStyle(.plain) + }) + case is LogRecord: + Text("Found in record \"\((self.activity.source as? LogRecord)?.message ?? "Error: Record not found")\"") + .foregroundStyle(.gray) + Spacer() + UI.Buttons.SmallOpen(callback: { + if let entity = self.activity.source as? LogRecord { + if let created = entity.timestamp { + self.state.to(.today) + self.state.session.date = created + } + } + }) default: Text("No source found") } @@ -557,9 +560,8 @@ extension WidgetLibrary { .disabled(true) } } - .padding(.top, 8) } - .frame(maxHeight: 200) + .frame(height: 200) } } @@ -901,12 +903,9 @@ extension WidgetLibrary { Spacer() } .id(self.vid) - .frame(minHeight: 200) .onAppear(perform: self.actionOnAppear) .onChange(of: self.state.session.date) { self.actionOnAppear() } .onChange(of: self.state.session.timeline.date) { self.actionOnAppear() } - .onChange(of: self.start) { self.actionOnAppear() } - .onChange(of: self.end) { self.actionOnAppear() } } } @@ -932,7 +931,6 @@ extension WidgetLibrary { Spacer() } .id(self.vid) - .frame(minHeight: 200) .onAppear(perform: self.actionOnAppear) .onChange(of: self.state.session.date) { self.actionOnAppear() } .onChange(of: self.state.session.timeline.date) { self.actionOnAppear() } @@ -976,7 +974,7 @@ extension WidgetLibrary { var body: some View { ScrollView(showsIndicators: false) { - VStack(alignment: .leading, spacing: 1) { + VStack(alignment: .leading, spacing: 5) { if self.terms.count > 0 { ForEach(self.terms, id: \.id) { savedSearch in UI.Buttons.SavedSearchTerm(savedSearch: savedSearch) @@ -989,50 +987,15 @@ extension WidgetLibrary { .disabled(true) } } - .padding(.top, 8) } .id(self.vid) - .frame(minHeight: 200) + .frame(height: 200) .onAppear(perform: self.actionOnAppear) .onChange(of: self.state.session.date) { self.actionOnAppear() } .onChange(of: self.state.session.timeline.date) { self.actionOnAppear() } } } - // MARK: EntityInteractionsForDate - struct EntityInteractionsForDate: View { - @EnvironmentObject private var state: Navigation - @AppStorage("widgetlibrary.ui.pagination.perpage") public var perPage: Int = 10 - @AppStorage("widgetlibrary.ui.searchTypeFilter.showProjects") public var showProjects: Bool = true - @AppStorage("widgetlibrary.ui.searchTypeFilter.showJobs") public var showJobs: Bool = true - @AppStorage("widgetlibrary.ui.searchTypeFilter.showCompanies") public var showCompanies: Bool = true - @State private var activities: [Activity] = [] - @State private var tabs: [ToolbarButton] = [] - @State private var vid: UUID = UUID() - - var body: some View { - VStack { - UI.ListLinkTitle(text: "Interactions from \(self.state.session.timeline.formatted())") - FancyGenericToolbar( - buttons: self.tabs, - standalone: true, - location: .content, - mode: .compact, - page: .explore, - alwaysShowTab: true - ) - .frame(height: 200) - } - .id(self.vid) - .onAppear(perform: self.actionOnAppear) - .onChange(of: self.state.session.date) { self.vid = UUID() } - .onChange(of: self.state.session.timeline.date) { self.vid = UUID() ; self.actionOnAppear() } - .onChange(of: self.showCompanies) { self.actionOnAppear() } - .onChange(of: self.showProjects) { self.actionOnAppear() } - .onChange(of: self.showJobs) { self.actionOnAppear() } - } - } - // MARK: InteractionsInRange struct InteractionsInRange: View { @EnvironmentObject private var state: Navigation @@ -1061,7 +1024,6 @@ extension WidgetLibrary { ) Spacer() } - .frame(minHeight: 200) .id(self.vid) .onAppear(perform: self.actionOnAppear) .onChange(of: self.state.session.date) { self.vid = UUID() } @@ -1069,8 +1031,6 @@ extension WidgetLibrary { .onChange(of: self.showCompanies) { self.actionOnAppear() } .onChange(of: self.showProjects) { self.actionOnAppear() } .onChange(of: self.showJobs) { self.actionOnAppear() } - .onChange(of: self.start) { self.actionOnAppear() } - .onChange(of: self.end) { self.actionOnAppear() } } } @@ -1954,6 +1914,122 @@ extension WidgetLibrary { .padding() } } + + // MARK: DaysWhereMentioned + struct DaysWhereMentioned: View { + @EnvironmentObject private var state: Navigation + @AppStorage("widgetlibrary.ui.searchTypeFilter.showRecords") public var showRecords: Bool = true + @AppStorage("widgetlibrary.ui.searchTypeFilter.showTasks") public var showTasks: Bool = true + @State private var vid: UUID = UUID() + @State private var days: [Day] = [] + + var body: some View { + VStack { + UI.ListLinkTitle(text: "Interactions with \(self.state.session.job?.title ?? self.state.session.job?.jid.string ?? "job")") + if self.state.session.job != nil || self.state.session.project != nil || self.state.session.company != nil { + if !self.days.isEmpty { + ScrollView(showsIndicators: false) { + VStack(alignment: .leading, spacing: 5) { + ForEach(self.days, id: \.id) { entity in + UI.ListButtonItem( + callback: { _ in + self.state.session.date = entity.date + }, + name: DateHelper.todayShort(entity.date, format: "MMMM dd, yyyy"), + iconAsImage: entity.type.icon, + actionIcon: "chevron.right" + ) + } + } + } + } else { + UI.ListButtonItem( + callback: {_ in}, + name: "None found for \(DateHelper.todayShort(self.state.session.date, format: "yyyy"))" + ) + .disabled(true) + } + } else { + UI.ListButtonItem( + callback: {_ in}, + name: "Select an entity from the sidebar" + ) + .disabled(true) + } + Spacer() + } + .id(self.vid) + .frame(height: 250) + .onAppear(perform: self.actionOnAppear) + .onChange(of: self.state.session.job) { self.actionOnAppear() } + .onChange(of: self.state.session.project) { self.actionOnAppear() } + .onChange(of: self.state.session.company) { self.actionOnAppear() } + .onChange(of: self.showRecords) { self.actionOnAppear() } + } + + struct Day: Identifiable { + var id: UUID = UUID() + var type: EType + var date: Date + } + } + } +} + +extension WidgetLibrary.UI.DaysWhereMentioned { + /// Onload handler. Sets view state + /// - Returns: Void + private func actionOnAppear() -> Void { + self.days = [] + + Task { + await self.findInteractions() + self.vid = UUID() + } + } + + /// Finds all interactions for the start/end or selected date + /// - Returns: Void + private func findInteractions() async -> Void { + let calendar = Calendar.autoupdatingCurrent + + if self.showRecords { + if let records = self.state.session.job?.records?.allObjects as? [LogRecord] { + for record in records { + if let timestamp = record.timestamp { + let components = calendar.dateComponents([.day], from: timestamp) + if !self.days.contains(where: { + let co = calendar.dateComponents([.day], from: $0.date) + return co.day == components.day + }) { + self.days.append( + Day(type: .records, date: timestamp) + ) + } + } + } + } + } + + if self.showTasks { + if let tasks = self.state.session.job?.tasks?.allObjects as? [LogTask] { + for task in tasks { + if let date = task.completedDate { + let components = calendar.dateComponents([.day], from: date) + if !self.days.contains(where: { + let co = calendar.dateComponents([.day], from: $0.date) + return co.day == components.day + }) { + self.days.append( + Day(type: .tasks, date: date) + ) + } + } + } + } + } + + self.days = self.days.sorted(by: {$0.date > $1.date}) } } @@ -2021,51 +2097,6 @@ extension WidgetLibrary.UI.SimpleEntityList { } } -extension WidgetLibrary.UI.EntityInteractionsForDate { - /// Onload handler. Sets view state - /// - Returns: Void - private func actionOnAppear() -> Void { - self.tabs = [] - self.tabs.append( - ToolbarButton( - id: 0, - helpText: "Jobs interacted with on this day in \(self.state.session.timeline.formatted())", - icon: "hammer", - labelText: "Jobs", - contents: AnyView( - UI.SimpleEntityList(type: .jobs) - ) - ) - ) - if self.showProjects { - self.tabs.append( - ToolbarButton( - id: 1, - helpText: "Projects interacted with on this day in \(self.state.session.timeline.formatted())", - icon: "folder", - labelText: "Projects", - contents: AnyView( - UI.SimpleEntityList(type: .projects) - ) - ) - ) - } - if self.showCompanies { - self.tabs.append( - ToolbarButton( - id: 2, - helpText: "Companies interacted with on this day in \(self.state.session.timeline.formatted())", - icon: "building.2", - labelText: "Companies", - contents: AnyView( - UI.SimpleEntityList(type: .companies) - ) - ) - ) - } - } -} - extension WidgetLibrary.UI.InteractionsInRange { /// Onload handler. Sets view state /// - Returns: Void @@ -2121,10 +2152,55 @@ extension WidgetLibrary.UI.SuggestedLinksInRange { Task { await self.getLinksFromJobs() await self.getLinksFromNotes() + await self.getLinksFromRecords() self.vid = UUID() } } + /// Get links from records created or updated on a given day + /// @TODO: move to LogRecord + /// - Returns: Void + private func getLinksFromRecords() async -> Void { + if let start = self.start { + if let end = self.end { + let linkLength = 40 + let records = CoreDataRecords(moc: self.state.moc).inRange( + start: start, + end: end + ) + + for record in records { + if let message = record.message { + if message.contains("https://") { + let linkRegex = /https:\/\/([^ \n]+)/ + if let match = message.firstMatch(of: linkRegex) { + let sMatch = String(match.0) + var label: String = sMatch + + if sMatch.count > linkLength { + label = label.prefix(linkLength) + "..." + } + if !self.activities.contains(where: {$0.name == label}) { + self.activities.append( + Activity( + name: label, + help: sMatch, + page: self.state.parent ?? .dashboard, + type: .activity, + job: record.job, + source: record, + url: URL(string: sMatch) ?? nil + ) + ) + } + } + } + } + } + } + } + } + /// Get links from jobs created or updated on a given day /// @TODO: move to Job /// - Returns: Void @@ -2245,7 +2321,7 @@ extension WidgetLibrary.UI.SavedSearchTermLinks { await self.findSavedTermsForPeriod(self.state.session.date.startOfMonth, self.state.session.date.endOfMonth) case .year: await self.findSavedTermsForPeriod(self.state.session.date.startOfYear, self.state.session.date.endOfYear) - case .custom: + default: await self.findSavedTermsForPeriod(self.start, self.end) } self.vid = UUID() diff --git a/KlockWork/CoreData/Data.xcdatamodeld/Note.xcdatamodel/contents b/KlockWork/CoreData/Data.xcdatamodeld/Note.xcdatamodel/contents index 3466bfe3..819cbb89 100644 --- a/KlockWork/CoreData/Data.xcdatamodeld/Note.xcdatamodel/contents +++ b/KlockWork/CoreData/Data.xcdatamodeld/Note.xcdatamodel/contents @@ -84,6 +84,7 @@ + diff --git a/KlockWork/Enums/ButtonType.swift b/KlockWork/Enums/ButtonType.swift index a2a58223..b34f8a1e 100644 --- a/KlockWork/Enums/ButtonType.swift +++ b/KlockWork/Enums/ButtonType.swift @@ -21,7 +21,7 @@ public enum ButtonType { case .star: return [Color.yellow, Color.orange] case .standard: - return [Theme.headerColour, Theme.base] + return [Theme.cPurple, Theme.base] case .secondary: return [Theme.secondary, Theme.base] case .white, .tsWhite: diff --git a/KlockWork/Views/Entities/Today/LogTable/RowTypes/LogRow.swift b/KlockWork/Views/Entities/Today/LogTable/RowTypes/LogRow.swift index 6cb6297d..16882ee9 100644 --- a/KlockWork/Views/Entities/Today/LogTable/RowTypes/LogRow.swift +++ b/KlockWork/Views/Entities/Today/LogTable/RowTypes/LogRow.swift @@ -401,7 +401,8 @@ struct LogRow: View, Identifiable { rec.timestamp = newDate() rec.message = message rec.id = entry.id - + rec.lastUpdate = Date() + if let jid = Double(job) { if let match = CoreDataJob(moc: self.nav.moc).byId(jid) { rec.job = match diff --git a/KlockWork/Views/Shared/AppSidebar/Widgets/GlobalSidebarWidgets.swift b/KlockWork/Views/Shared/AppSidebar/Widgets/GlobalSidebarWidgets.swift index 63b1719d..45badcab 100644 --- a/KlockWork/Views/Shared/AppSidebar/Widgets/GlobalSidebarWidgets.swift +++ b/KlockWork/Views/Shared/AppSidebar/Widgets/GlobalSidebarWidgets.swift @@ -173,7 +173,7 @@ struct GlobalSidebarWidgets: View { action: {active.toggle() ; isSearchStackShowing = false; self.isUpcomingTaskStackShowing = false}, icon: "doc", fgColour: nav.session.job?.colour_from_stored().isBright() ?? false ? .black : .white, - bgColour: nav.session.job?.colour_from_stored() ?? nil, + bgColour: nav.session.job?.backgroundColor ?? nil, showLabel: false, size: .small, type: active ? .secondary : .standard, @@ -215,8 +215,8 @@ struct GlobalSidebarWidgets: View { self.nav.session.search.reset() }, icon: "magnifyingglass", - fgColour: nav.session.job?.colour_from_stored().isBright() ?? false ? .black : .white, - bgColour: nav.session.job?.colour_from_stored() ?? nil, + fgColour: self.nav.session.job?.backgroundColor.isBright() ?? false ? .black : .white, + bgColour: self.nav.session.job?.backgroundColor ?? nil, showLabel: false, size: .small, type: active ? .secondary : .standard, @@ -526,7 +526,7 @@ extension GlobalSidebarWidgets.ScoreButton { private func actionOnAppear() -> Void { if let assessment = self.state.activities.assessed.filter({$0.isToday == true && $0.dayNumber > 0}).first { self.score = assessment.score - self.bgColour = .blue + self.bgColour = Theme.cPurple } } }