diff --git a/phpmon/Domain/App/Base.lproj/Main.storyboard b/phpmon/Domain/App/Base.lproj/Main.storyboard
index 373b1c7..a4831dd 100644
--- a/phpmon/Domain/App/Base.lproj/Main.storyboard
+++ b/phpmon/Domain/App/Base.lproj/Main.storyboard
@@ -720,7 +720,7 @@ Gw
-
+
@@ -788,24 +788,24 @@ Gw
-
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
@@ -822,6 +822,7 @@ Gw
+
@@ -857,6 +858,7 @@ Gw
+
@@ -895,7 +897,7 @@ Gw
-
+
@@ -905,14 +907,15 @@ Gw
+
-
+
-
+
@@ -950,7 +953,7 @@ Gw
-
+
@@ -959,14 +962,15 @@ Gw
+
-
+
-
+
@@ -976,8 +980,8 @@ Gw
-
+
@@ -995,10 +999,11 @@ Gw
+
-
+
@@ -1047,20 +1052,20 @@ Gw
-
+
-
+
-
+
-
+
diff --git a/phpmon/Domain/Integrations/Valet/ValetSite.swift b/phpmon/Domain/Integrations/Valet/ValetSite.swift
index 5538d8a..ed87be0 100644
--- a/phpmon/Domain/Integrations/Valet/ValetSite.swift
+++ b/phpmon/Domain/Integrations/Valet/ValetSite.swift
@@ -53,6 +53,12 @@ class ValetSite {
/// How the PHP version was determined.
var composerPhpSource: VersionSource = .unknown
+ /// Which version of PHP is actually used to serve this site.
+ var servingPhpVersion: String {
+ return self.isolatedPhpVersion?.versionNumber.homebrewVersion
+ ?? PhpEnv.phpInstall.version.short
+ }
+
enum VersionSource: String {
case unknown = "unknown"
case require = "require"
diff --git a/phpmon/Domain/SiteList/Cells/SiteListKindCell.swift b/phpmon/Domain/SiteList/Cells/SiteListKindCell.swift
index 9ca7346..6cdb823 100644
--- a/phpmon/Domain/SiteList/Cells/SiteListKindCell.swift
+++ b/phpmon/Domain/SiteList/Cells/SiteListKindCell.swift
@@ -11,12 +11,11 @@ import AppKit
class SiteListKindCell: NSTableCellView, SiteListCellProtocol
{
+ static let reusableName = "siteListKindCell"
+
@IBOutlet weak var imageViewType: NSImageView!
func populateCell(with site: ValetSite) {
-
-
-
// If the `aliasPath` is nil, we're dealing with a parked site (otherwise: linked).
imageViewType.image = NSImage(
named: site.aliasPath == nil
diff --git a/phpmon/Domain/SiteList/Cells/SiteListNameCell.swift b/phpmon/Domain/SiteList/Cells/SiteListNameCell.swift
index f51d851..b444cd1 100644
--- a/phpmon/Domain/SiteList/Cells/SiteListNameCell.swift
+++ b/phpmon/Domain/SiteList/Cells/SiteListNameCell.swift
@@ -11,6 +11,8 @@ import AppKit
class SiteListNameCell: NSTableCellView, SiteListCellProtocol
{
+ static let reusableName = "siteListNameCell"
+
@IBOutlet weak var labelSiteName: NSTextField!
@IBOutlet weak var labelPathName: NSTextField!
diff --git a/phpmon/Domain/SiteList/Cells/SiteListPhpCell.swift b/phpmon/Domain/SiteList/Cells/SiteListPhpCell.swift
index 06d7403..f7bca68 100644
--- a/phpmon/Domain/SiteList/Cells/SiteListPhpCell.swift
+++ b/phpmon/Domain/SiteList/Cells/SiteListPhpCell.swift
@@ -11,6 +11,8 @@ import AppKit
class SiteListPhpCell: NSTableCellView, SiteListCellProtocol
{
+ static let reusableName = "siteListPhpCell"
+
var site: ValetSite? = nil
@IBOutlet weak var buttonPhpVersion: NSButton!
@@ -19,8 +21,7 @@ class SiteListPhpCell: NSTableCellView, SiteListCellProtocol
func populateCell(with site: ValetSite) {
self.site = site
- let versionInUse = site.isolatedPhpVersion?.versionNumber.homebrewVersion ?? PhpEnv.phpInstall.version.short
- buttonPhpVersion.title = " PHP \(versionInUse)"
+ buttonPhpVersion.title = " PHP \(site.servingPhpVersion)"
if site.isolatedPhpVersion != nil {
imageViewPhpVersionOK.isHidden = false
diff --git a/phpmon/Domain/SiteList/Cells/SiteListTLSCell.swift b/phpmon/Domain/SiteList/Cells/SiteListTLSCell.swift
index fd2d2f5..466d165 100644
--- a/phpmon/Domain/SiteList/Cells/SiteListTLSCell.swift
+++ b/phpmon/Domain/SiteList/Cells/SiteListTLSCell.swift
@@ -11,6 +11,8 @@ import AppKit
class SiteListTLSCell: NSTableCellView, SiteListCellProtocol
{
+ static let reusableName = "siteListTLSCell"
+
@IBOutlet weak var imageViewLock: NSImageView!
func populateCell(with site: ValetSite) {
diff --git a/phpmon/Domain/SiteList/Cells/SiteListTypeCell.swift b/phpmon/Domain/SiteList/Cells/SiteListTypeCell.swift
index 497bcb9..536d482 100644
--- a/phpmon/Domain/SiteList/Cells/SiteListTypeCell.swift
+++ b/phpmon/Domain/SiteList/Cells/SiteListTypeCell.swift
@@ -11,6 +11,8 @@ import AppKit
class SiteListTypeCell: NSTableCellView, SiteListCellProtocol
{
+ static let reusableName = "siteListTypeCell"
+
@IBOutlet weak var labelDriver: NSTextField!
@IBOutlet weak var labelPhpVersion: NSTextField!
diff --git a/phpmon/Domain/SiteList/SiteListVC.swift b/phpmon/Domain/SiteList/SiteListVC.swift
index 64834f7..cb92769 100644
--- a/phpmon/Domain/SiteList/SiteListVC.swift
+++ b/phpmon/Domain/SiteList/SiteListVC.swift
@@ -26,6 +26,9 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
return App.shared.detectedApplications
}
+ /// The last sort descriptor used.
+ var sortDescriptor: NSSortDescriptor? = nil
+
/// String that was last searched for. Empty by default.
var lastSearchedFor = ""
@@ -144,6 +147,28 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
}
}
+ func applySortDescriptor(_ descriptor: NSSortDescriptor) {
+ sortDescriptor = descriptor
+
+ var sorted = self.sites
+
+ switch descriptor.key {
+ case "Secure":
+ sorted = self.sites.sorted { $0.secured && !$1.secured }; break
+ case "Domain":
+ sorted = self.sites.sorted { $0.absolutePath < $1.absolutePath }; break
+ case "PHP":
+ sorted = self.sites.sorted { $0.servingPhpVersion < $1.servingPhpVersion }; break
+ case "Kind":
+ sorted = self.sites.sorted { ($0.aliasPath == nil) && !($1.aliasPath == nil) }; break
+ case "Type":
+ sorted = self.sites.sorted { $0.driver ?? "QQQ" < $1.driver ?? "QQQ" }; break
+ default: break;
+ }
+
+ self.sites = descriptor.ascending ? sorted.reversed() : sorted
+ }
+
func addedNewSite(name: String, secure: Bool) {
waitAndExecute {
Valet.shared.reloadSites()
@@ -172,21 +197,28 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
return sites.count
}
- func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
+ func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
+ guard let sortDescriptor = tableView.sortDescriptors.first else { return }
+ // Kinda scuffed way of applying sort descriptors here, but it works.
+ Log.info("Applying sort descriptor for column: \(sortDescriptor.key ?? "Unknown")")
+ applySortDescriptor(sortDescriptor)
+ searchedFor(text: lastSearchedFor)
+ }
+ func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let mapping: [String: String] = [
- "TLS": "siteListTLSCell",
- "DOMAIN": "siteListNameCell",
- "ENVIRONMENT": "siteListPhpCell",
- "KIND": "siteListKindCell",
- "TYPE": "siteListTypeCell",
+ "TLS": SiteListTLSCell.reusableName,
+ "DOMAIN": SiteListNameCell.reusableName,
+ "ENVIRONMENT": SiteListPhpCell.reusableName,
+ "KIND": SiteListKindCell.reusableName,
+ "TYPE": SiteListTypeCell.reusableName,
]
let columnName = tableColumn!.identifier.rawValue
+ let identifier = NSUserInterfaceItemIdentifier(rawValue: mapping[columnName]!)
- guard let userCell = tableView.makeView(
- withIdentifier: NSUserInterfaceItemIdentifier(rawValue: mapping[columnName]!), owner: self
- ) as? SiteListCellProtocol else { return nil }
+ guard let userCell = tableView.makeView(withIdentifier: identifier, owner: self)
+ as? SiteListCellProtocol else { return nil }
userCell.populateCell(with: sites[row])
@@ -215,9 +247,14 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
if searchString.isEmpty {
sites = Valet.shared.sites
+ if let sortDescriptor = sortDescriptor {
+ self.applySortDescriptor(sortDescriptor)
+ }
+
DispatchQueue.main.async {
self.tableView.reloadData()
}
+
return
}
@@ -231,6 +268,10 @@ class SiteListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
}.contains(false)
})
+ if let sortDescriptor = sortDescriptor {
+ self.applySortDescriptor(sortDescriptor)
+ }
+
DispatchQueue.main.async {
self.tableView.reloadData()
}