mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
✨ Allow sorting of site list
This commit is contained in:
@ -720,7 +720,7 @@ Gw
|
||||
<rect key="frame" x="20" y="185" width="440" height="22"/>
|
||||
<pathCell key="cell" selectable="YES" refusesFirstResponder="YES" alignment="left" id="m8d-XF-kh9">
|
||||
<font key="font" metaFont="system"/>
|
||||
<url key="url" string="file:///Users/nicoverbruggen/Code/nicoverbruggen.be/"/>
|
||||
<url key="url" string="file:///Users/"/>
|
||||
</pathCell>
|
||||
</pathControl>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P0B-Ht-R8n">
|
||||
@ -788,24 +788,24 @@ Gw
|
||||
</viewController>
|
||||
<customObject id="6XV-bG-0N1" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="191" y="1099"/>
|
||||
<point key="canvasLocation" x="191" y="1098.5"/>
|
||||
</scene>
|
||||
<!--Site ListVC-->
|
||||
<scene sceneID="aZt-6w-TFl">
|
||||
<objects>
|
||||
<viewController identifier="siteList" storyboardIdentifier="siteList" id="JZI-Vd-9oq" customClass="SiteListVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" misplaced="YES" id="rIZ-4U-bhj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="634" height="309"/>
|
||||
<view key="view" id="rIZ-4U-bhj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="626" height="309"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<scrollView horizontalLineScroll="54" horizontalPageScroll="10" verticalLineScroll="54" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p0j-eB-I2i">
|
||||
<rect key="frame" x="0.0" y="0.0" width="634" height="309"/>
|
||||
<clipView key="contentView" drawsBackground="NO" id="6IL-DW-37w">
|
||||
<rect key="frame" x="1" y="1" width="617" height="292"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="626" height="309"/>
|
||||
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="6IL-DW-37w">
|
||||
<rect key="frame" x="1" y="1" width="624" height="307"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" multipleSelection="NO" autosaveName="phpmon-sitelist-columns" rowHeight="54" headerView="xUg-Mq-OSh" viewBased="YES" id="cp3-34-pQj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="652" height="264"/>
|
||||
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" multipleSelection="NO" autosaveName="phpmon-sitelist-columns" rowHeight="54" headerView="xUg-Mq-OSh" viewBased="YES" id="cp3-34-pQj">
|
||||
<rect key="frame" x="0.0" y="0.0" width="642" height="279"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<size key="intercellSpacing" width="17" height="0.0"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
@ -822,6 +822,7 @@ Gw
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="Secure"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="siteListTLSCell" id="hft-M4-nWb" customClass="SiteListTLSCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
@ -857,6 +858,7 @@ Gw
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="Domain"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="siteListNameCell" wantsLayer="YES" id="5GY-nN-BWd" customClass="SiteListNameCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
@ -895,7 +897,7 @@ Gw
|
||||
</tableCellView>
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="ENVIRONMENT" width="110" minWidth="100" maxWidth="150" id="hzb-XI-Out">
|
||||
<tableColumn identifier="ENVIRONMENT" width="100" minWidth="100" maxWidth="150" id="hzb-XI-Out">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Active">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
@ -905,14 +907,15 @@ Gw
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="PHP"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="siteListPhpCell" wantsLayer="YES" id="T49-0U-d58" customClass="SiteListPhpCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
<rect key="frame" x="366" y="0.0" width="110" height="54"/>
|
||||
<rect key="frame" x="366" y="0.0" width="100" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZXQ-bg-Xba">
|
||||
<rect key="frame" x="32" y="18" width="70" height="18"/>
|
||||
<rect key="frame" x="27" y="18" width="70" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="70" id="MBa-bB-DTB"/>
|
||||
</constraints>
|
||||
@ -925,7 +928,7 @@ Gw
|
||||
</connections>
|
||||
</button>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Yq0-qk-bFt">
|
||||
<rect key="frame" x="6" y="18" width="18" height="18"/>
|
||||
<rect key="frame" x="1" y="18" width="18" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="18" id="5fd-EQ-BgV"/>
|
||||
<constraint firstAttribute="height" constant="18" id="nP7-13-SSn"/>
|
||||
@ -950,7 +953,7 @@ Gw
|
||||
</prototypeCellViews>
|
||||
</tableColumn>
|
||||
<tableColumn identifier="KIND" width="36" minWidth="36" maxWidth="36" id="7EV-ZL-92u">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="center" title="Kind">
|
||||
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Kind">
|
||||
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</tableHeaderCell>
|
||||
@ -959,14 +962,15 @@ Gw
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="Kind"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="siteListKindCell" wantsLayer="YES" id="AhT-xR-16a" customClass="SiteListKindCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
<rect key="frame" x="493" y="0.0" width="36" height="54"/>
|
||||
<rect key="frame" x="483" y="0.0" width="48" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="sYR-vb-OW1">
|
||||
<rect key="frame" x="10" y="18" width="18" height="18"/>
|
||||
<rect key="frame" x="15" y="18" width="18" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="18" id="XcB-uw-szU"/>
|
||||
<constraint firstAttribute="height" constant="18" id="bGN-Vh-Sh0"/>
|
||||
@ -976,8 +980,8 @@ Gw
|
||||
</imageView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="sYR-vb-OW1" firstAttribute="leading" secondItem="AhT-xR-16a" secondAttribute="leading" constant="10" id="2wl-PC-AYn"/>
|
||||
<constraint firstItem="sYR-vb-OW1" firstAttribute="centerY" secondItem="AhT-xR-16a" secondAttribute="centerY" id="4mB-oS-T6I"/>
|
||||
<constraint firstItem="sYR-vb-OW1" firstAttribute="centerX" secondItem="AhT-xR-16a" secondAttribute="centerX" id="LyQ-XZ-J3u"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="imageViewType" destination="sYR-vb-OW1" id="txH-es-roq"/>
|
||||
@ -995,10 +999,11 @@ Gw
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
<sortDescriptor key="sortDescriptorPrototype" selector="compare:" sortKey="Type"/>
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="siteListTypeCell" wantsLayer="YES" id="ntU-Rl-ciP" customClass="SiteListTypeCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
<rect key="frame" x="546" y="0.0" width="97" height="54"/>
|
||||
<rect key="frame" x="536" y="0.0" width="97" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ljl-8B-key">
|
||||
@ -1047,20 +1052,20 @@ Gw
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="620" id="iRQ-sz-oyv"/>
|
||||
</constraints>
|
||||
<scroller key="horizontalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="TDE-ff-DQT">
|
||||
<rect key="frame" x="1" y="293" width="617" height="15"/>
|
||||
<rect key="frame" x="1" y="292" width="624" height="16"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="wFn-93-f10">
|
||||
<rect key="frame" x="618" y="29" width="15" height="264"/>
|
||||
<rect key="frame" x="609" y="29" width="16" height="279"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<tableHeaderView key="headerView" wantsLayer="YES" id="xUg-Mq-OSh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="652" height="28"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="642" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableHeaderView>
|
||||
</scrollView>
|
||||
<progressIndicator maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="ZiS-Gq-TLQ">
|
||||
<rect key="frame" x="302" y="150" width="30" height="30"/>
|
||||
<rect key="frame" x="298" y="150" width="30" height="30"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="30" id="XK3-AR-Oc0"/>
|
||||
<constraint firstAttribute="height" constant="30" id="lfW-dB-Eu3"/>
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -11,6 +11,8 @@ import AppKit
|
||||
|
||||
class SiteListNameCell: NSTableCellView, SiteListCellProtocol
|
||||
{
|
||||
static let reusableName = "siteListNameCell"
|
||||
|
||||
@IBOutlet weak var labelSiteName: NSTextField!
|
||||
@IBOutlet weak var labelPathName: NSTextField!
|
||||
|
||||
|
@ -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
|
||||
|
@ -11,6 +11,8 @@ import AppKit
|
||||
|
||||
class SiteListTLSCell: NSTableCellView, SiteListCellProtocol
|
||||
{
|
||||
static let reusableName = "siteListTLSCell"
|
||||
|
||||
@IBOutlet weak var imageViewLock: NSImageView!
|
||||
|
||||
func populateCell(with site: ValetSite) {
|
||||
|
@ -11,6 +11,8 @@ import AppKit
|
||||
|
||||
class SiteListTypeCell: NSTableCellView, SiteListCellProtocol
|
||||
{
|
||||
static let reusableName = "siteListTypeCell"
|
||||
|
||||
@IBOutlet weak var labelDriver: NSTextField!
|
||||
@IBOutlet weak var labelPhpVersion: NSTextField!
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
Reference in New Issue
Block a user