First actions for generation view
This commit is contained in:
@ -86,10 +86,16 @@ struct GenerationContentView: View {
|
||||
text: "draft posts",
|
||||
statusWhenNonEmpty: .warning,
|
||||
items: draftPosts) { $0.id }
|
||||
GenerationStringIssuesView(
|
||||
GenerationIssuesView(
|
||||
text: "additional output files",
|
||||
statusWhenNonEmpty: .warning,
|
||||
items: content.results.unusedFilesInOutput)
|
||||
items: $content.results.unusedFilesInOutput) { filePath in
|
||||
HStack {
|
||||
Text(filePath)
|
||||
Spacer()
|
||||
Button("Delete", action: { delete(unusedFile: filePath) })
|
||||
}
|
||||
}
|
||||
GenerationStringIssuesView(
|
||||
text: "inaccessible files",
|
||||
items: content.results.inaccessibleFiles) { $0.id }
|
||||
@ -134,6 +140,13 @@ struct GenerationContentView: View {
|
||||
}
|
||||
}.padding()
|
||||
}
|
||||
|
||||
private func delete(unusedFile: String) {
|
||||
guard content.storage.deleteInOutputFolder(unusedFile) else {
|
||||
return
|
||||
}
|
||||
content.results.unusedFilesInOutput.remove(unusedFile)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
|
65
CHDataManagement/Views/Generation/GenerationIssuesView.swift
Normal file
65
CHDataManagement/Views/Generation/GenerationIssuesView.swift
Normal file
@ -0,0 +1,65 @@
|
||||
import SwiftUI
|
||||
|
||||
struct GenerationIssuesView<S, T, V>: View where S: Collection, T: Hashable & Comparable, V: View, S.Element == T {
|
||||
|
||||
let text: String
|
||||
|
||||
let statusWhenNonEmpty: IssueStatus
|
||||
|
||||
@Binding
|
||||
var items: S
|
||||
|
||||
let map: (T) -> V
|
||||
|
||||
@State
|
||||
private var showList = false
|
||||
|
||||
var status: IssueStatus {
|
||||
items.isEmpty ? .nominal : statusWhenNonEmpty
|
||||
}
|
||||
|
||||
init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Binding<S>, map: @escaping (T) -> V) {
|
||||
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.sorted(), id: \.self) { item in
|
||||
map(item)
|
||||
}
|
||||
.frame(minHeight: 400)
|
||||
Button("Close") { showList = false }
|
||||
}.padding()
|
||||
}
|
||||
}
|
||||
|
||||
private func showListIfNonEmpty() {
|
||||
guard !items.isEmpty else {
|
||||
return
|
||||
}
|
||||
showList = true
|
||||
}
|
||||
}
|
||||
|
||||
extension GenerationIssuesView where S == Set<String>, V == Text {
|
||||
|
||||
init(text: String, statusWhenNonEmpty: IssueStatus = .error, items: Binding<Set<String>>) {
|
||||
self.text = text
|
||||
self.statusWhenNonEmpty = statusWhenNonEmpty
|
||||
self._items = items
|
||||
self.map = { Text($0) }
|
||||
}
|
||||
}
|
45
CHDataManagement/Views/Generic/ColoredButton.swift
Normal file
45
CHDataManagement/Views/Generic/ColoredButton.swift
Normal file
@ -0,0 +1,45 @@
|
||||
import SwiftUI
|
||||
import SFSafeSymbols
|
||||
|
||||
struct ColoredButton: View {
|
||||
|
||||
let icon: SFSymbol
|
||||
|
||||
let text: LocalizedStringKey
|
||||
|
||||
let fillColor: Color
|
||||
|
||||
let textColor: Color
|
||||
|
||||
let action: () -> Void
|
||||
|
||||
init(icon: SFSymbol, text: LocalizedStringKey, fillColor: Color = .blue, textColor: Color = .white, action: @escaping () -> Void) {
|
||||
self.icon = icon
|
||||
self.text = text
|
||||
self.fillColor = fillColor
|
||||
self.textColor = textColor
|
||||
self.action = action
|
||||
}
|
||||
|
||||
init(delete: @escaping () -> Void) {
|
||||
self.icon = .trash
|
||||
self.text = "Delete"
|
||||
self.fillColor = .red
|
||||
self.textColor = .white
|
||||
self.action = delete
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Button(action: action) {
|
||||
HStack {
|
||||
Spacer()
|
||||
Image(systemSymbol: icon)
|
||||
Text(text)
|
||||
.padding(.vertical, 8)
|
||||
Spacer()
|
||||
}
|
||||
.foregroundStyle(textColor)
|
||||
.background(RoundedRectangle(cornerRadius: 8).fill(fillColor))
|
||||
}.buttonStyle(.plain)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user