use searchable to filter labels

This commit is contained in:
Satindar Dhillon 2022-04-06 21:30:38 -07:00
parent 29d10feb61
commit 287da3d939

View file

@ -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()) }
}
}