added sorting to the UI and ViewModels
Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
da6e68c219
commit
bc635714b4
@ -24,6 +24,7 @@ public class MockEmployeeService: EmployeeServiceProtocol {
|
||||
return
|
||||
}
|
||||
wrapper = localData
|
||||
sortEmployees()
|
||||
}
|
||||
|
||||
public func getEmployees(_ serviceMode: EmployeeServiceMode) async throws -> Employees {
|
||||
@ -37,12 +38,9 @@ public class MockEmployeeService: EmployeeServiceProtocol {
|
||||
|
||||
//resort mock data
|
||||
if sortField != self.sortField || sortOrder != self.sortOrder {
|
||||
wrapper = .init(employees: wrapper.employees.sorted(by: sortField, with: sortOrder),
|
||||
total: wrapper.employees.count,
|
||||
page: page,
|
||||
perPage: perPage)
|
||||
self.sortField = sortField
|
||||
self.sortOrder = sortOrder
|
||||
sortEmployees()
|
||||
}
|
||||
|
||||
let totalUsers = wrapper.employees.count
|
||||
@ -57,6 +55,13 @@ public class MockEmployeeService: EmployeeServiceProtocol {
|
||||
let pagedEmployees = Array(wrapper.employees[startIndex..<endIndex])
|
||||
return .init(employees: pagedEmployees, total: totalUsers, page: page, perPage: perPage)
|
||||
}
|
||||
|
||||
private func sortEmployees() {
|
||||
wrapper = .init(employees: wrapper.employees.sorted(by: sortField, with: sortOrder),
|
||||
total: wrapper.employees.count,
|
||||
page: 1,
|
||||
perPage: 10)
|
||||
}
|
||||
}
|
||||
|
||||
extension Array where Element == Employee {
|
||||
|
||||
@ -68,6 +68,41 @@ class EmployeesViewController: UIViewController {
|
||||
modeSegmentedControl.selectedSegmentIndex = 0
|
||||
modeSegmentedControl.addTarget(self, action: #selector(onServiceModeChange), for: .valueChanged)
|
||||
navigationItem.titleView = modeSegmentedControl
|
||||
|
||||
let sortButton = UIBarButtonItem(title: "Sort", style: .plain, target: self, action: #selector(showSortOptions))
|
||||
navigationItem.rightBarButtonItem = sortButton
|
||||
}
|
||||
|
||||
private func presentSortingActionSheet() {
|
||||
let alert = UIAlertController(title: "Sort Employees", message: "Select a sort option", preferredStyle: .actionSheet)
|
||||
|
||||
alert.addAction(UIAlertAction(title: "Full Name (Asc)", style: .default) { [weak self] _ in
|
||||
self?.viewModel.sortField = .fullName
|
||||
self?.viewModel.sortOrder = .ascending
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Full Name (Desc)", style: .default) { [weak self] _ in
|
||||
self?.viewModel.sortField = .fullName
|
||||
self?.viewModel.sortOrder = .descending
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Team (Asc)", style: .default) { [weak self] _ in
|
||||
self?.viewModel.sortField = .team
|
||||
self?.viewModel.sortOrder = .ascending
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Team (Desc)", style: .default) { [weak self] _ in
|
||||
self?.viewModel.sortField = .team
|
||||
self?.viewModel.sortOrder = .descending
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Employee Type (Asc)", style: .default) { [weak self] _ in
|
||||
self?.viewModel.sortField = .employeeType
|
||||
self?.viewModel.sortOrder = .ascending
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Employee Type (Desc)", style: .default) { [weak self] _ in
|
||||
self?.viewModel.sortField = .employeeType
|
||||
self?.viewModel.sortOrder = .ascending
|
||||
})
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
|
||||
present(alert, animated: true, completion: nil)
|
||||
|
||||
}
|
||||
|
||||
/// Using the ViewModel setup combine handlers
|
||||
@ -154,6 +189,11 @@ extension EmployeesViewController: UITableViewDelegate {
|
||||
// Mark: - Objective-C Methods
|
||||
extension EmployeesViewController {
|
||||
|
||||
/// Show sort options
|
||||
@objc private func showSortOptions() {
|
||||
presentSortingActionSheet()
|
||||
}
|
||||
|
||||
/// Fetch the Employees
|
||||
@objc private func didPullToRefresh() {
|
||||
viewModel.fetchEmployees()
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
/// ViewModel that will be bound to an Employees model and used
|
||||
/// specifically with the EmployeesViewController.
|
||||
@ -18,11 +19,27 @@ public class EmployeesViewModel: ObservableObject {
|
||||
@Published public private(set) var isLoading: Bool = false
|
||||
@Published public private(set) var hasMorePages: Bool = true
|
||||
|
||||
@Published public var sortField: EmployeeSortField = .fullName
|
||||
@Published public var sortOrder: EmployeeSortOrder = .ascending
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private var currentPage = 1
|
||||
private let perPage = 10
|
||||
private var totalEmployees = 0
|
||||
|
||||
public init() {}
|
||||
public init() {
|
||||
observeSortingChanges()
|
||||
}
|
||||
|
||||
/// Observe changes to sortField and sortOrder and debounce fetch calls
|
||||
private func observeSortingChanges() {
|
||||
Publishers.CombineLatest($sortField, $sortOrder)
|
||||
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
|
||||
.sink { [weak self] _, _ in
|
||||
self?.resetAndFetchEmployees()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
/// Fetch employees for the given page
|
||||
public func fetchEmployees(page: Int = 1) {
|
||||
@ -35,8 +52,8 @@ public class EmployeesViewModel: ObservableObject {
|
||||
// Fetch employees using the paginated API
|
||||
let wrapper = try await employeeService.getEmployees(serviceMode, page: page,
|
||||
perPage: perPage,
|
||||
sortField: .employeeType,
|
||||
sortOrder: .ascending)
|
||||
sortField: sortField,
|
||||
sortOrder: sortOrder)
|
||||
|
||||
// Update published properties
|
||||
if page == 1 {
|
||||
@ -67,6 +84,11 @@ public class EmployeesViewModel: ObservableObject {
|
||||
/// Change the service mode (e.g., production, malformed, empty)
|
||||
public func changeMode(to mode: EmployeeServiceMode) {
|
||||
serviceMode = mode
|
||||
resetAndFetchEmployees()
|
||||
}
|
||||
|
||||
/// Resets the current employee list and fetches data from page 1
|
||||
private func resetAndFetchEmployees() {
|
||||
currentPage = 1
|
||||
employees = []
|
||||
hasMorePages = true
|
||||
|
||||
Loading…
Reference in New Issue
Block a user