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

Support for pagination on Today table #320

Merged
merged 2 commits into from
Oct 30, 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
91 changes: 91 additions & 0 deletions KWCore/Sources/UI/WidgetLibrary/WidgetLibrary.UI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1313,6 +1313,97 @@ extension WidgetLibrary {
}
}

struct Pagination: View {
@EnvironmentObject public var state: Navigation
@AppStorage("widgetlibrary.ui.pagination.perpage") public var perPage: Int = 10
public var entityCount: Int
@State private var pages: [Page] = []

var body: some View {
VStack(alignment: .leading, spacing: 0) {
if self.entityCount > 0 && self.pages.count > 1 {
Main
}
}
.onAppear(perform: self.actionOnAppear)
}

var Main: some View {
HStack(spacing: 1) {
Spacer()
ForEach(self.pages, id: \.id) { page in
page
}
}
.background(
ZStack(alignment: .top) {
self.state.session.appPage.primaryColour
LinearGradient(colors: [Theme.base, .clear], startPoint: .top, endPoint: .bottom)
.blendMode(.softLight)
.opacity(0.4)
.frame(height: 15)
}
)
}

struct Page: View, Identifiable {
@EnvironmentObject public var state: Navigation
@AppStorage("widgetlibrary.ui.pagination.perpage") public var perPage: Int = 10
public var id: UUID = UUID()
public var index: Int
public var value: String
@State private var isHighlighted: Bool = false
@State private var isCurrent: Bool = false

var body: some View {
Button {
self.state.session.pagination.currentPageOffset = self.index * self.perPage
} label: {
ZStack {
if self.isCurrent {
(self.isHighlighted ? Color.yellow.opacity(0.4) : Color.yellow.opacity(0.4))
} else {
(self.isHighlighted ? Theme.textBackground.opacity(1) : Theme.textBackground.opacity(0))
}
Text(self.value)
.padding(8)
}
.frame(maxWidth: 35)
.useDefaultHover({ hover in self.isHighlighted = hover })
}
.buttonStyle(.plain)
.onAppear(perform: self.actionOnAppear)
.onChange(of: self.state.session.pagination.currentPageOffset) { self.actionOnAppear() }
}
}
}
}
}

extension WidgetLibrary.UI.Pagination {
/// Onload handler. Sets view state
/// - Returns: Void
private func actionOnAppear() -> Void {
let numPages = self.entityCount/self.perPage

if numPages > 0 {
for page in 0..<numPages {
self.pages.append(
Page(
index: page,
value: String(page + 1)
)
)
}
}
}
}

extension WidgetLibrary.UI.Pagination.Page {
/// Onload handler. Sets view state
/// - Returns: Void
private func actionOnAppear() -> Void {
self.isCurrent = (self.state.session.pagination.currentPageOffset/self.perPage) == self.index
}
}

Expand Down
7 changes: 6 additions & 1 deletion KlockWork/Utils/Navigation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,13 @@ extension Navigation {
var toolbar: Toolbar = Toolbar()
var eventStatus: EventIndicatorStatus = .ready
var cli: CommandLineSession = CommandLineSession()
var pagination: TablePagination = TablePagination()
}


public struct TablePagination {
var currentPageOffset: Int = 0
}

public struct CommandLineSession {
typealias CLIApp = CommandLineInterface.App
typealias CLIAppType = CommandLineInterface.App.AppType
Expand Down
83 changes: 69 additions & 14 deletions KlockWork/Views/Entities/Today/LogTable/LogTable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,21 @@ extension Today.LogTable {
@AppStorage("today.showColumnTimestamp") public var showColumnTimestamp: Bool = true
@AppStorage("today.showColumnExtendedTimestamp") public var showColumnExtendedTimestamp: Bool = true
@AppStorage("today.showColumnJobId") public var showColumnJobId: Bool = true

public var records: [LogRecord]
@State private var offset: Int = 0

var body: some View {
ScrollView(showsIndicators: false) {
VStack(spacing: 0) {
if records.count > 0 {
ForEach(records, id: \.objectID) { record in
ForEach(self.records, id: \.objectID) { record in
if record.job != nil {
let entry = Entry(
timestamp: DateHelper.longDate(record.timestamp!),
job: record.job!,
message: record.message!
)

LogRow(
entry: entry,
index: records.firstIndex(of: record),
Expand All @@ -147,6 +147,7 @@ extension Today.LogTable {
}
}
}
.onAppear(perform: self.actionOnAppear)
}
}

Expand All @@ -156,11 +157,14 @@ extension Today.LogTable {
typealias UI = WidgetLibrary.UI
@EnvironmentObject public var nav: Navigation
@AppStorage("today.tableSortOrder") private var tableSortOrder: Int = 0
@AppStorage("widgetlibrary.ui.pagination.perpage") public var perPage: Int = 10
public var date: Date? = Date()
private let page: PageConfiguration.AppPage = .today
@State private var searchText: String = ""
// @State private var loading: Bool = false
@State private var records: [LogRecord] = []
@State private var recordsOnCurrentPage: [LogRecord] = []
@State private var id: UUID = UUID()

var body: some View {
VStack(alignment: .leading, spacing: 0) {
Expand All @@ -171,8 +175,10 @@ extension Today.LogTable {
Content
// }
}
.onAppear(perform: self.findRecords)
.onChange(of: nav.session.date) { self.findRecords() }
.onAppear(perform: self.actionOnAppear)
.onChange(of: self.recordsOnCurrentPage) { self.refreshView() }
.onChange(of: self.nav.session.pagination.currentPageOffset) { self.findRecords() }
.onChange(of: self.nav.session.date) { self.actionOnAppear() }
.onChange(of: self.tableSortOrder) { self.findRecords() }
.onChange(of: nav.saved) {
if nav.saved {
Expand All @@ -186,18 +192,20 @@ extension Today.LogTable {
ToolbarButtons()
.background(self.page.primaryColour)
Divider().foregroundStyle(.white)
// TODO: fix search
// @TODO: fix search
// if nav.session.toolbar.showSearch {
// UI.BoundSearchBar(text: $searchText, disabled: (records.count == 0))
// }

if nav.session.toolbar.mode == .plain {
Plain(records: records)
Plain(records: self.recordsOnCurrentPage)
} else {
Headers(page: self.page)
Full(records: records)
Full(records: self.recordsOnCurrentPage)
}
UI.Pagination(entityCount: records.count)
}
.id(self.id)
}
}

Expand Down Expand Up @@ -289,11 +297,37 @@ extension Today.LogTable.Headers {
}

extension Today.LogTable.TabContent.Chronologic {
/// Onload handler. Sets view state
/// - Returns: Void
private func actionOnAppear() -> Void {
self.nav.session.pagination.currentPageOffset = 0
self.findRecords()
}

/// Fires when the record window shifts
/// - Returns: Void
private func refreshView() -> Void {
self.id = UUID()
}

/// Find today's records
/// - Returns: Void
private func findRecords() -> Void {
DispatchQueue.with(background: {
return CoreDataRecords(moc: self.nav.moc).forDate(nav.session.date, sort: NSSortDescriptor(keyPath: \LogRecord.timestamp, ascending: self.tableSortOrder == 1 ? true : false))
return CoreDataRecords(moc: self.nav.moc).forDate(self.nav.session.date, sort: NSSortDescriptor(keyPath: \LogRecord.timestamp, ascending: self.tableSortOrder == 1 ? true : false))
}, completion: { recordsForToday in
self.records = recordsForToday!
if let recordsForToday = recordsForToday {
let lBound = self.nav.session.pagination.currentPageOffset
let uBound = lBound + self.perPage

if lBound < recordsForToday.count && uBound <= recordsForToday.count {
self.recordsOnCurrentPage = Array(recordsForToday[lBound..<uBound])
} else {
self.recordsOnCurrentPage = recordsForToday
}

self.records = recordsForToday
}
})
}
}
Expand All @@ -303,8 +337,10 @@ extension Today.LogTable.TabContent.Grouped {
DispatchQueue.with(background: {
return CoreDataRecords(moc: self.nav.moc).forDate(nav.session.date, sort: NSSortDescriptor(keyPath: \LogRecord.timestamp, ascending: self.tableSortOrder == 1 ? true : false))
}, completion: { recordsForToday in
self.records = recordsForToday!
grouped = CoreDataRecords(moc: self.nav.moc).createExportableGroupedRecordsAsViews(self.records)
if let recordsForToday = recordsForToday {
self.records = recordsForToday
grouped = CoreDataRecords(moc: self.nav.moc).createExportableGroupedRecordsAsViews(self.records)
}
})
}
}
Expand All @@ -314,7 +350,9 @@ extension Today.LogTable.TabContent.Summarized {
DispatchQueue.with(background: {
return CoreDataRecords(moc: self.nav.moc).forDate(nav.session.date, sort: NSSortDescriptor(keyPath: \LogRecord.timestamp, ascending: self.tableSortOrder == 1 ? true : false))
}, completion: { recordsForToday in
self.records = recordsForToday!
if let recordsForToday = recordsForToday {
self.records = recordsForToday
}
})
}
}
Expand All @@ -327,3 +365,20 @@ extension Today.LogTable.Plain {
grouped = model.createExportableGroupedRecordsAsViews(records)
}
}

extension Today.LogTable.Full {
/// Onload handler. Sets view state
/// - Returns: Void
private func actionOnAppear() -> Void {
// if self.offset == 0 {
// self.records = Array(self.records.prefix(10))
// }
}

/// Fires when you navigate to another page of records
/// - Returns: Void
private func actionOnChangeOffset() -> Void {
// self.nav.session.pagination.currentPageOffset += self.perPage

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct LogRow: View, Identifiable {
)
}
.contextMenu { contextMenu }
.useDefaultHover({ hover in self.isHighlighted = hover })
.useDefaultHoverNoCursor({ hover in self.isHighlighted = hover })
}
.onAppear(perform: self.actionOnAppear)
.onChange(of: timestamp) {
Expand Down
3 changes: 1 addition & 2 deletions KlockWork/Views/Entities/Today/PostingInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extension Today {

FancyTextField(
placeholder: "What are you working on?",
lineLimit: 11,
lineLimit: 8,
onSubmit: submitAction,
fgColour: self.nav.session.job?.backgroundColor.isBright() ?? false ? Theme.base : .white,
text: $text
Expand All @@ -43,7 +43,6 @@ extension Today {
.alert("You need to write a message too. What are you working on?", isPresented: $errorNoContent) {
Button("Ok", role: .cancel) {}
}
.frame(height: 215)

FancyHelpText(
text: "Choose a job from the sidebar, type into the field below. Enter/Return/+ to create records.",
Expand Down
4 changes: 2 additions & 2 deletions KlockWork/Views/Find/FindDashboard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ struct FindDashboard: View {
self.nav.parent?.appPage.primaryColour.opacity(0.6) ?? Theme.subHeaderColour
LinearGradient(colors: [Theme.base, .clear], startPoint: .top, endPoint: .bottom)
.blendMode(.softLight)
.opacity(0.3)
.frame(height: 20)
.opacity(0.4)
.frame(height: 15)

HStack(alignment: .center) {
UI.Toggle(isOn: $showRecords, eType: .records)
Expand Down
3 changes: 2 additions & 1 deletion KlockWork/Views/Shared/Fancy/FancyTextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct FancyTextField: View {

private var multiLine: some View {
TextEditor(text: $text)
.font(Theme.fontSubTitle)
.font(font)
.textFieldStyle(.plain)
.disableAutocorrection(!enableAutoCorrection)
.padding(padding)
Expand All @@ -108,5 +108,6 @@ struct FancyTextField: View {
extension FancyTextField {
private func reset() -> Void {
text = ""
self.hasFocus = false
}
}