80 lines
3.4 KiB
Swift
80 lines
3.4 KiB
Swift
import SwiftUI
|
|
import TermindApplication
|
|
|
|
/// Uses the same native selection, hover, marquee and drag renderer as Hosts.
|
|
struct MetricsManagedCardPage: ManagedCardPage {
|
|
typealias SectionID = String
|
|
typealias Item = ServerMetric
|
|
|
|
@Environment(AppModel.self) private var app
|
|
@Environment(WindowModel.self) private var window
|
|
|
|
var managedMinimumCardWidth: CGFloat { 310 }
|
|
var managedMaximumCardWidth: CGFloat { .infinity }
|
|
private var filtered: [ServerMetric] {
|
|
app.serverMetrics.servers.filter { server in
|
|
window.metricsQuery.isEmpty || server.name.localizedCaseInsensitiveContains(window.metricsQuery)
|
|
|| app.hostLibrary.host(server.id)?.matches(window.metricsQuery) == true
|
|
}
|
|
}
|
|
var managedSections: [ManagedCardSection<String, ServerMetric>] {
|
|
[ManagedCardSection(id: "servers", title: "", items: filtered, showsWhenEmpty: false)]
|
|
}
|
|
var managedSelection: ManagedCardSelection<UUID> {
|
|
ManagedCardSelection(selected: { window.metricsSelection }, update: { window.metricsSelection = $0 })
|
|
}
|
|
var managedCapabilities: ManagedCardCapabilities<String, UUID> {
|
|
ManagedCardCapabilities(
|
|
selection: .multiple, marqueeSelection: true,
|
|
reordering: ManagedCardReordering(isEnabled: window.metricsQuery.isEmpty, dropPolicy: .sameSection) {
|
|
ids, _, before in
|
|
app.serverMetrics.move(ids, before: before)
|
|
}
|
|
)
|
|
}
|
|
var isManagedSourceEmpty: Bool { app.serverMetrics.servers.isEmpty }
|
|
var managedPresentation: MetricsManagedPresentation {
|
|
MetricsManagedPresentation(ids: Set(app.serverMetrics.servers.map(\.id)))
|
|
}
|
|
|
|
func managedCard(for item: ServerMetric, context: ManagedCardItemContext<ServerMetric>) -> some View {
|
|
ServerMetricsCard(
|
|
server: item, model: app.serverMetrics,
|
|
inspect: { window.metricsHostID = item.id },
|
|
openTerminal: {
|
|
if let host = app.hostLibrary.host(item.id) { app.open(host, as: .sshSession, in: window) }
|
|
},
|
|
isSelected: context.isSelected, select: context.select, extendSelection: context.extendSelection,
|
|
contextActionItems: context.actionItems
|
|
)
|
|
|
|
}
|
|
func managedHeader(for section: ManagedCardSection<String, ServerMetric>, isDropTarget: Bool) -> some View {
|
|
EmptyView()
|
|
}
|
|
func managedGhost(for item: ServerMetric) -> some View {
|
|
ServerMetricsCard(server: item, model: app.serverMetrics)
|
|
.opacity(0.45)
|
|
.overlay {
|
|
RoundedRectangle(cornerRadius: Metrics.Radius.large)
|
|
.strokeBorder(Color.accentColor, style: StrokeStyle(lineWidth: 1, dash: [4, 3]))
|
|
}
|
|
.allowsHitTesting(false)
|
|
}
|
|
func managedEmptyState() -> some View {
|
|
ContentUnavailableView(
|
|
"No monitored servers", systemImage: "waveform.path.ecg",
|
|
description: Text("Add a saved Linux server to start monitoring.")
|
|
)
|
|
}
|
|
func managedNoResultsState() -> some View { ContentUnavailableView.search(text: window.metricsQuery) }
|
|
}
|
|
|
|
struct MetricsManagedPresentation: ManagedCardPresentationModifier {
|
|
let ids: Set<UUID>
|
|
@Environment(WindowModel.self) private var window
|
|
func body(content: Content) -> some View {
|
|
content.onChange(of: ids) { window.metricsSelection.formIntersection(ids) }
|
|
}
|
|
}
|