Skip to content

Instantly share code, notes, and snippets.

@zentrope
Created December 30, 2020 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zentrope/113d8b4b9e101b40cafab0656205dd45 to your computer and use it in GitHub Desktop.
Save zentrope/113d8b4b9e101b40cafab0656205dd45 to your computer and use it in GitHub Desktop.
//
// UserData.swift
//
import Cocoa
import Combine
import ForumsKit
class UserData: NSObject, ObservableObject, NSFetchedResultsControllerDelegate {
@Published var users = [FKUser]()
@Published var showQueryEditor = false
var onChange: ((Event) -> ())?
enum Event {
case count(Int)
}
var sortFields = [
("id", "ID"),
("points", "Points"),
("name", "Name"),
("domain", "Domain"),
("dateInserted", "Joined"),
("dateLastActive", "Active")
]
var csv: Data? {
get {
let columns = ["ID", "Type", "Points", "Name", "Rank", "Email", "Domain", "Inserted", "Updated", "Last active", "Roles"].joined(separator: ",")
func row(_ user: FKUser) -> String {
let row: [Quotable] = [
Int(user.id),
user.type ?? "",
Int(user.points),
user.name ?? "",
user.rank?.name ?? "",
user.email ?? "",
user.domain ?? "",
user.dateInserted.preferredDateString(),
user.dateUpdated.preferredDateString(),
user.dateLastActive.preferredDateString(),
user.roleDescription
]
return row.map { $0.quote() }
.joined(separator: ",")
}
let csvText = ([columns] + users.map { row($0) }).joined(separator: "\n")
return csvText.data(using: .utf8)
}
}
var predicateTemplates = TemplateBuilder()
.template(path: \FKUser.name)
.template(path: \FKUser.domain)
.template(path: \FKUser.dateInserted)
.template(path: \FKUser.dateUpdated)
.template(path: \FKUser.dateLastActive)
.template(path: \FKUser.rank?.name, modifier: .any)
.template(path: "roles.name", modifier: .any)
.template(path: \FKUser.points)
.template(path: \FKUser.id)
.all()
var predicateChanges = PassthroughSubject<NSPredicate?, Never>()
private var fetchController: NSFetchedResultsController<FKUser>?
override init() {
super.init()
fetchController = ForumsKit.usersFetchedResultsController()
fetchController?.delegate = self
reload()
}
private func reload() {
do {
try fetchController?.performFetch()
users = fetchController?.fetchedObjects ?? []
onChange?(.count(users.count))
}
catch {
print("ERROR: \(error)")
}
}
func update(predicate: NSPredicate?) {
showQueryEditor = predicate != nil
fetchController?.fetchRequest.predicate = predicate
reload()
}
func update(sort: NSSortDescriptor) {
fetchController?.fetchRequest.sortDescriptors = [sort]
reload()
}
func update(filter: String) {
let value = filter.trim()
var predicate: NSPredicate? = nil
if !value.isEmpty {
let query = """
(name contains[cd] %@) or
(any roles.name contains[cd] %@) or
(any rank.name contains[cd] %@) or
(points contains[cd] %@) or
(id contains[cd] %@)
"""
predicate = NSPredicate(format: query, value, value, value, value, value, value)
}
fetchController?.fetchRequest.predicate = predicate
reload()
}
// MARK: NSFetchedResultsControllerDelegate
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
reload()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment