mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
use searchable to filter labels
This commit is contained in:
parent
29d10feb61
commit
287da3d939
1 changed files with 95 additions and 72 deletions
|
|
@ -10,85 +10,99 @@ struct ApplyLabelsView: View {
|
|||
@EnvironmentObject var dataService: DataService
|
||||
@Environment(\.presentationMode) private var presentationMode
|
||||
@StateObject var viewModel = LabelsViewModel()
|
||||
@State private var labelSearchFilter = ""
|
||||
|
||||
var innerBody: some View {
|
||||
List {
|
||||
Section(header: Text("Assigned Labels")) {
|
||||
if viewModel.selectedLabelsForItemInContext.isEmpty {
|
||||
Text("No labels are currently assigned.")
|
||||
}
|
||||
ForEach(viewModel.selectedLabelsForItemInContext.applySearchFilter(labelSearchFilter), id: \.self) { label in
|
||||
HStack {
|
||||
TextChip(feedItemLabel: label)
|
||||
Spacer()
|
||||
Button(
|
||||
action: {
|
||||
withAnimation {
|
||||
viewModel.removeLabelFromItem(label)
|
||||
}
|
||||
},
|
||||
label: { Image(systemName: "trash").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(header: Text("Available Labels")) {
|
||||
ForEach(viewModel.unselectedLabelsForItemInContext.applySearchFilter(labelSearchFilter), id: \.self) { label in
|
||||
HStack {
|
||||
TextChip(feedItemLabel: label)
|
||||
Spacer()
|
||||
Button(
|
||||
action: {
|
||||
withAnimation {
|
||||
viewModel.addLabelToItem(label)
|
||||
}
|
||||
},
|
||||
label: { Image(systemName: "plus").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
Button(
|
||||
action: { viewModel.showCreateEmailModal = true },
|
||||
label: {
|
||||
HStack {
|
||||
Image(systemName: "plus.circle.fill").foregroundColor(.green)
|
||||
Text("Create a new Label").foregroundColor(.appGrayTextContrast)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
)
|
||||
.disabled(viewModel.isLoading)
|
||||
}
|
||||
}
|
||||
.navigationTitle("Assign Labels")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button(
|
||||
action: { presentationMode.wrappedValue.dismiss() },
|
||||
label: { Text("Cancel").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(
|
||||
action: {
|
||||
viewModel.saveItemLabelChanges(itemID: item.id, dataService: dataService) { labels in
|
||||
commitLabelChanges(labels)
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
}
|
||||
},
|
||||
label: { Text("Save").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $viewModel.showCreateEmailModal) {
|
||||
CreateLabelView(viewModel: viewModel)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
if viewModel.isLoading {
|
||||
EmptyView()
|
||||
|
||||
} else {
|
||||
List {
|
||||
Section(header: Text("Assigned Labels")) {
|
||||
if viewModel.selectedLabelsForItemInContext.isEmpty {
|
||||
Text("No labels are currently assigned.")
|
||||
}
|
||||
ForEach(viewModel.selectedLabelsForItemInContext, id: \.self) { label in
|
||||
HStack {
|
||||
TextChip(feedItemLabel: label)
|
||||
Spacer()
|
||||
Button(
|
||||
action: {
|
||||
withAnimation {
|
||||
viewModel.removeLabelFromItem(label)
|
||||
}
|
||||
},
|
||||
label: { Image(systemName: "trash").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Section(header: Text("Available Labels")) {
|
||||
ForEach(viewModel.unselectedLabelsForItemInContext, id: \.self) { label in
|
||||
HStack {
|
||||
TextChip(feedItemLabel: label)
|
||||
Spacer()
|
||||
Button(
|
||||
action: {
|
||||
withAnimation {
|
||||
viewModel.addLabelToItem(label)
|
||||
}
|
||||
},
|
||||
label: { Image(systemName: "plus").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Section {
|
||||
Button(
|
||||
action: { viewModel.showCreateEmailModal = true },
|
||||
label: {
|
||||
HStack {
|
||||
Image(systemName: "plus.circle.fill").foregroundColor(.green)
|
||||
Text("Create a new Label").foregroundColor(.appGrayTextContrast)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
if #available(iOS 15.0, *) {
|
||||
innerBody
|
||||
.searchable(
|
||||
text: $labelSearchFilter,
|
||||
placement: .navigationBarDrawer(displayMode: .always)
|
||||
)
|
||||
.disabled(viewModel.isLoading)
|
||||
}
|
||||
}
|
||||
.navigationTitle("Assign Labels")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button(
|
||||
action: { presentationMode.wrappedValue.dismiss() },
|
||||
label: { Text("Cancel").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(
|
||||
action: {
|
||||
viewModel.saveItemLabelChanges(itemID: item.id, dataService: dataService) { labels in
|
||||
commitLabelChanges(labels)
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
}
|
||||
},
|
||||
label: { Text("Save").foregroundColor(.appGrayTextContrast) }
|
||||
)
|
||||
}
|
||||
}
|
||||
.sheet(isPresented: $viewModel.showCreateEmailModal) {
|
||||
CreateLabelView(viewModel: viewModel)
|
||||
} else {
|
||||
innerBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,3 +111,12 @@ struct ApplyLabelsView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension Sequence where Element == FeedItemLabel {
|
||||
func applySearchFilter(_ searchFilter: String) -> [FeedItemLabel] {
|
||||
if searchFilter.isEmpty {
|
||||
return map { $0 } // return the identity of the sequence
|
||||
}
|
||||
return filter { $0.name.lowercased().contains(searchFilter.lowercased()) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue