126 lines
2.9 KiB
Swift
126 lines
2.9 KiB
Swift
import SwiftUI
|
|
import SFSafeSymbols
|
|
|
|
enum IssueStatus {
|
|
case nominal
|
|
case warning
|
|
case error
|
|
|
|
var symbol: SFSymbol {
|
|
switch self {
|
|
case .nominal: .checkmarkCircleFill
|
|
case .warning, .error: .exclamationmarkTriangle
|
|
}
|
|
}
|
|
|
|
var color: Color {
|
|
switch self {
|
|
case .nominal: .green
|
|
case .warning: .yellow
|
|
case .error: .red
|
|
}
|
|
}
|
|
}
|
|
|
|
struct GenerationStringIssuesView<T>: View where T: Hashable {
|
|
|
|
let text: String
|
|
|
|
let statusWhenNonEmpty: IssueStatus
|
|
|
|
@Binding
|
|
var items: Set<T>
|
|
|
|
let map: (T) -> String
|
|
|
|
@State
|
|
private var showList = false
|
|
|
|
var status: IssueStatus {
|
|
items.isEmpty ? .nominal : statusWhenNonEmpty
|
|
}
|
|
|
|
init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Binding<Set<T>>, map: @escaping (T) -> String) {
|
|
self.text = text
|
|
self.statusWhenNonEmpty = statusWhenNonEmpty
|
|
self._items = items
|
|
self.map = map
|
|
}
|
|
|
|
var body: some View {
|
|
HStack {
|
|
Button(action: showListIfNonEmpty) {
|
|
Image(systemSymbol: status.symbol)
|
|
.foregroundStyle(status.color)
|
|
}.buttonStyle(.plain)
|
|
Text("\(items.count) \(text)")
|
|
}
|
|
.sheet(isPresented: $showList) {
|
|
VStack {
|
|
Text("\(items.count) \(text)")
|
|
.font(.title)
|
|
List(items.map(map).sorted(), id: \.self) { item in
|
|
Text(item)
|
|
}
|
|
.frame(minHeight: 400)
|
|
Button("Close") { showList = false }
|
|
}.padding()
|
|
}
|
|
}
|
|
|
|
private func showListIfNonEmpty() {
|
|
guard !items.isEmpty else {
|
|
return
|
|
}
|
|
showList = true
|
|
}
|
|
}
|
|
|
|
extension GenerationStringIssuesView where T == String {
|
|
|
|
init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Binding<Set<String>>) {
|
|
self.text = text
|
|
self.statusWhenNonEmpty = statusWhenNonEmpty
|
|
self._items = items
|
|
self.map = { $0 }
|
|
}
|
|
}
|
|
|
|
struct GenerationResultsIssueView: View {
|
|
|
|
@State
|
|
private var showList = false
|
|
|
|
let text: String
|
|
|
|
let status: IssueStatus
|
|
|
|
let items: () -> [String]
|
|
|
|
var body: some View {
|
|
HStack {
|
|
Button(action: showListIfNonEmpty) {
|
|
Image(systemSymbol: status.symbol)
|
|
.foregroundStyle(status.color)
|
|
}.buttonStyle(.plain)
|
|
Text(text)
|
|
}
|
|
.sheet(isPresented: $showList) {
|
|
VStack {
|
|
List(items(), id: \.self) { item in
|
|
Text(item)
|
|
}
|
|
.frame(minHeight: 400)
|
|
Button("Close") { showList = false }
|
|
}
|
|
}
|
|
}
|
|
|
|
private func showListIfNonEmpty() {
|
|
// guard !items.isEmpty else {
|
|
// return
|
|
// }
|
|
showList = true
|
|
}
|
|
}
|