Improve status messages

This commit is contained in:
Shadowfacts 2020-07-07 13:23:27 -04:00
parent 967a2518b4
commit 31962b43a3
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
7 changed files with 116 additions and 22 deletions

View File

@ -49,6 +49,7 @@
D6A7D096243541A400B46857 /* WindowStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A7D095243541A400B46857 /* WindowStatusView.swift */; }; D6A7D096243541A400B46857 /* WindowStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A7D095243541A400B46857 /* WindowStatusView.swift */; };
D6A7D09A243546B500B46857 /* WindowStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6A7D099243546B500B46857 /* WindowStatusView.xib */; }; D6A7D09A243546B500B46857 /* WindowStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6A7D099243546B500B46857 /* WindowStatusView.xib */; };
D6A7D0A42435885B00B46857 /* JavaScriptHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A7D0A32435885B00B46857 /* JavaScriptHighlighter.swift */; }; D6A7D0A42435885B00B46857 /* JavaScriptHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A7D0A32435885B00B46857 /* JavaScriptHighlighter.swift */; };
D6ABB01424B4DE7600F79DA8 /* StatusManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6ABB01324B4DE7600F79DA8 /* StatusManager.swift */; };
D6D13B042436C33D00493D97 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D13B032436C33D00493D97 /* main.swift */; }; D6D13B042436C33D00493D97 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D13B032436C33D00493D97 /* main.swift */; };
D6D13B082436C34200493D97 /* JavaScriptHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A7D0A32435885B00B46857 /* JavaScriptHighlighter.swift */; }; D6D13B082436C34200493D97 /* JavaScriptHighlighter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6A7D0A32435885B00B46857 /* JavaScriptHighlighter.swift */; };
D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */; }; D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */; };
@ -122,6 +123,7 @@
D6A7D095243541A400B46857 /* WindowStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowStatusView.swift; sourceTree = "<group>"; }; D6A7D095243541A400B46857 /* WindowStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowStatusView.swift; sourceTree = "<group>"; };
D6A7D099243546B500B46857 /* WindowStatusView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WindowStatusView.xib; sourceTree = "<group>"; }; D6A7D099243546B500B46857 /* WindowStatusView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WindowStatusView.xib; sourceTree = "<group>"; };
D6A7D0A32435885B00B46857 /* JavaScriptHighlighter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptHighlighter.swift; sourceTree = "<group>"; }; D6A7D0A32435885B00B46857 /* JavaScriptHighlighter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptHighlighter.swift; sourceTree = "<group>"; };
D6ABB01324B4DE7600F79DA8 /* StatusManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusManager.swift; sourceTree = "<group>"; };
D6D13B012436C33D00493D97 /* jstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jstest; sourceTree = BUILT_PRODUCTS_DIR; }; D6D13B012436C33D00493D97 /* jstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jstest; sourceTree = BUILT_PRODUCTS_DIR; };
D6D13B032436C33D00493D97 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; }; D6D13B032436C33D00493D97 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MongoEvaluator.swift; sourceTree = "<group>"; }; D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MongoEvaluator.swift; sourceTree = "<group>"; };
@ -216,6 +218,7 @@
children = ( children = (
D63CDEBD23C837DC0012D658 /* AppDelegate.swift */, D63CDEBD23C837DC0012D658 /* AppDelegate.swift */,
D63CDF3423C838190012D658 /* MongoController.swift */, D63CDF3423C838190012D658 /* MongoController.swift */,
D6ABB01324B4DE7600F79DA8 /* StatusManager.swift */,
D63CDF3323C838190012D658 /* Node.swift */, D63CDF3323C838190012D658 /* Node.swift */,
D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */, D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */,
D624090E243903E90020E09F /* ExtendedJSON.swift */, D624090E243903E90020E09F /* ExtendedJSON.swift */,
@ -376,6 +379,7 @@
D6A7D096243541A400B46857 /* WindowStatusView.swift in Sources */, D6A7D096243541A400B46857 /* WindowStatusView.swift in Sources */,
D626BF82243BD2EE0075117B /* EditDocumentWindowController.swift in Sources */, D626BF82243BD2EE0075117B /* EditDocumentWindowController.swift in Sources */,
D6A7D0A42435885B00B46857 /* JavaScriptHighlighter.swift in Sources */, D6A7D0A42435885B00B46857 /* JavaScriptHighlighter.swift in Sources */,
D6ABB01424B4DE7600F79DA8 /* StatusManager.swift in Sources */,
D62408C12438CF550020E09F /* JavaScriptEditorView.swift in Sources */, D62408C12438CF550020E09F /* JavaScriptEditorView.swift in Sources */,
D63CDF4023C839010012D658 /* QueryViewController.swift in Sources */, D63CDF4023C839010012D658 /* QueryViewController.swift in Sources */,
); );
@ -526,7 +530,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = V4WK9KR9U2; DEVELOPMENT_TEAM = HGYVAQA9FW;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = MongoView/Info.plist; INFOPLIST_FILE = MongoView/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@ -548,7 +552,7 @@
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 3; CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = V4WK9KR9U2; DEVELOPMENT_TEAM = HGYVAQA9FW;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = MongoView/Info.plist; INFOPLIST_FILE = MongoView/Info.plist;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (

View File

@ -18,10 +18,17 @@ class MongoController {
var client: MongoClient! var client: MongoClient!
@Published var status: ConnectionStatus = .connecting @Published var statusManager = StatusManager()
@Published private(set) var status: ConnectionStatus {
didSet {
statusManager.set(messageFor(status: status), for: .connection)
}
}
init(connectionString: String) { init(connectionString: String) {
self.connectionString = connectionString self.connectionString = connectionString
self.status = .connecting
self.statusManager.set(messageFor(status: .connecting), for: .connection)
} }
deinit { deinit {
@ -50,6 +57,17 @@ class MongoController {
func collection(_ collection: DatabaseCollection) -> MongoCollection<Document> { func collection(_ collection: DatabaseCollection) -> MongoCollection<Document> {
return db(for: collection).collection(collection.name) return db(for: collection).collection(collection.name)
} }
private func messageFor(status: ConnectionStatus) -> String {
switch status {
case .connecting:
return "Connecting..."
case .connected:
return "Connected to \(connectionString)"
case .failed:
return "Failed to connect"
}
}
} }

View File

@ -0,0 +1,54 @@
//
// StatusManager.swift
// MongoView
//
// Created by Shadowfacts on 7/7/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import Foundation
struct StatusManager {
private(set) var statuses = [Category: Status]()
var mostRelevant: Status? {
for category in Category.sortedByPriority {
if let status = statuses[category] {
return status
}
}
return nil
}
mutating func set(_ message: String, for category: Category, override: Bool = false) {
statuses[category] = Status(message: message, category: category)
if override {
for other in Category.allCases where other < category {
remove(for: other)
}
}
}
mutating func remove(for category: Category) {
statuses.removeValue(forKey: category)
}
enum Category: Int, Comparable, CaseIterable {
case document
case query
case connection
static let sortedByPriority = allCases.sorted()
static func < (lhs: StatusManager.Category, rhs: StatusManager.Category) -> Bool {
return lhs.rawValue < rhs.rawValue
}
}
struct Status {
let message: String
let category: Category
let timestamp = Date()
}
}

View File

@ -15,9 +15,13 @@ struct DatabaseCollections {
let collections: [String] let collections: [String]
} }
struct DatabaseCollection { struct DatabaseCollection: CustomStringConvertible {
let database: String let database: String
let name: String let name: String
var description: String {
return "\(database).\(name)"
}
} }
class DatabaseViewController: NSViewController { class DatabaseViewController: NSViewController {

View File

@ -94,6 +94,8 @@ class QueryViewController: NSViewController {
if reload { if reload {
outlineView.reloadData() outlineView.reloadData()
} }
mongoController.statusManager.set("Queried \(collection)", for: .query, override: true)
} }
func deleteRootNode(_ node: Node) { func deleteRootNode(_ node: Node) {
@ -133,6 +135,7 @@ class QueryViewController: NSViewController {
return return
} }
self.refresh() self.refresh()
self.mongoController.statusManager.set("Deleted document", for: .document)
case let .failure(error): case let .failure(error):
let alert = NSAlert(error: error) let alert = NSAlert(error: error)
alert.beginSheetModal(for: self.view.window!, completionHandler: nil) alert.beginSheetModal(for: self.view.window!, completionHandler: nil)
@ -171,6 +174,7 @@ class QueryViewController: NSViewController {
let wc = EditDocumentWindowController(mongoController: mongoController, collection: collection, document: document) let wc = EditDocumentWindowController(mongoController: mongoController, collection: collection, document: document)
wc.documentEdited = { wc.documentEdited = {
self.refresh() self.refresh()
self.mongoController.statusManager.set("Updated document", for: .document)
} }
wc.showWindow(nil) wc.showWindow(nil)
} }

View File

@ -23,6 +23,7 @@ class WindowStatusView: NSView {
super.awakeFromNib() super.awakeFromNib()
(button.cell as! NSButtonCell).imageDimsWhenDisabled = false (button.cell as! NSButtonCell).imageDimsWhenDisabled = false
button.font = .monospacedDigitSystemFont(ofSize: 13, weight: .regular)
} }
func setText(_ text: String) { func setText(_ text: String) {

View File

@ -22,7 +22,8 @@ class DatabaseWindowController: NSWindowController {
private var databaseViewController: DatabaseViewController! private var databaseViewController: DatabaseViewController!
private var statusDidChangeHandler: Cancellable? private var statusChangeHandler: Cancellable?
private var connectionStatusChangeHandler: Cancellable?
convenience init() { convenience init() {
self.init(windowNibName: "DatabaseWindowController") self.init(windowNibName: "DatabaseWindowController")
@ -35,15 +36,16 @@ class DatabaseWindowController: NSWindowController {
if setupMongo { if setupMongo {
mongoController = MongoController(connectionString: "mongodb://localhost:27017") mongoController = MongoController(connectionString: "mongodb://localhost:27017")
} }
statusDidChangeHandler = mongoController.$status
statusChangeHandler = mongoController.$statusManager
.receive(on: DispatchQueue.main) .receive(on: DispatchQueue.main)
.sink { (status) in .sink { self.updateStatusText(manager: $0) }
self.updateStatusText(status)
connectionStatusChangeHandler = mongoController.$status
if status == .connected { .receive(on: DispatchQueue.main)
self.initializeUI() .filter { $0 == .connected }
} .sink { (_) in self.initializeUI() }
}
if setupMongo { if setupMongo {
mongoController.setup() mongoController.setup()
} }
@ -66,16 +68,23 @@ class DatabaseWindowController: NSWindowController {
window?.title = databaseViewController?.title ?? "MongoView" window?.title = databaseViewController?.title ?? "MongoView"
} }
private func updateStatusText(_ status: MongoController.ConnectionStatus) { private func updateStatusText(manager: StatusManager) {
guard let statusView = self.statusView else { return } guard let statusView = self.statusView,
switch status { let mostRelevant = manager.mostRelevant else { return }
case .connecting:
statusView.setText("Connecting...") let dayComparisonResult = Calendar.current.compare(mostRelevant.timestamp, to: Date(), toGranularity: .day)
case .failed:
statusView.setText("Failed to connect") let formatter = DateFormatter()
case .connected: if dayComparisonResult == .orderedSame {
statusView.setText("Connected to \(self.mongoController.connectionString)") formatter.dateStyle = .none
} else {
formatter.dateStyle = .short
} }
formatter.timeStyle = .medium
let timestamp = formatter.string(from: mostRelevant.timestamp)
let string = "\(mostRelevant.message) | \(timestamp)"
statusView.setText(string)
} }
private func initializeUI() { private func initializeUI() {