Showing debug info in new report screen
This commit is contained in:
parent
c125f9ffab
commit
aa008d5443
@ -268,7 +268,7 @@ class CheckController: UIViewController, UITableViewDelegate, UISearchResultsUpd
|
||||
// }
|
||||
|
||||
Task {
|
||||
let coordinator = ReportCoordinator(splitController: splitViewController, vehicle: vehicle)
|
||||
let coordinator = ReportCoordinator(splitController: splitViewController, vehicle: vehicle, isPersistent: true)
|
||||
try? await coordinator.start()
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,13 +15,15 @@ class ReportCoordinator: Coordinator {
|
||||
|
||||
let viewController: UISplitViewController?
|
||||
let vehicle: VehicleDto
|
||||
let isPersistent: Bool
|
||||
|
||||
var navController: UINavigationController?
|
||||
|
||||
init(splitController: UISplitViewController?, vehicle: VehicleDto) {
|
||||
init(splitController: UISplitViewController?, vehicle: VehicleDto, isPersistent: Bool) {
|
||||
|
||||
self.viewController = splitController
|
||||
self.vehicle = vehicle
|
||||
self.isPersistent = isPersistent
|
||||
}
|
||||
|
||||
func start() async throws {
|
||||
@ -29,7 +31,7 @@ class ReportCoordinator: Coordinator {
|
||||
if viewController?.viewControllers.count == 2 {
|
||||
navController = viewController?.viewControllers.last as? UINavigationController
|
||||
} else {
|
||||
let viewModel = ReportViewModel(vehicle: vehicle)
|
||||
let viewModel = ReportViewModel(vehicle: vehicle, isPersistent: isPersistent)
|
||||
viewModel.coordinator = self
|
||||
let controller = UIHostingController(rootView: ReportScreen(viewModel: viewModel))
|
||||
navController = UINavigationController(rootViewController: controller)
|
||||
|
||||
@ -65,13 +65,49 @@ struct ReportScreen: View {
|
||||
LabeledContent("Notes", value: String(viewModel.vehicle.notes.count))
|
||||
.navigationLink(onTap: viewModel.openNotes)
|
||||
}
|
||||
|
||||
if viewModel.showDebugInfo {
|
||||
Section("Debug info") {
|
||||
makeDebugInfoCell(title: "Avtocod", model: viewModel.vehicle.debugInfo?.autocod)
|
||||
makeDebugInfoCell(title: "Vin01 (VIN)", model: viewModel.vehicle.debugInfo?.vin01vin)
|
||||
makeDebugInfoCell(title: "Vin01 (base)", model: viewModel.vehicle.debugInfo?.vin01base)
|
||||
makeDebugInfoCell(title: "Vin01 (history)", model: viewModel.vehicle.debugInfo?.vin01history)
|
||||
makeDebugInfoCell(title: "Nomerogram", model: viewModel.vehicle.debugInfo?.nomerogram)
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
Task { await viewModel.loadVehicle() }
|
||||
Task { await viewModel.onAppear() }
|
||||
}
|
||||
.hud($viewModel.hud)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
func makeDebugInfoCell(title: String, model: DebugInfoEntryDto?) -> some View {
|
||||
|
||||
let color: Color = switch model?.status {
|
||||
case .success: .green
|
||||
case .warning: .orange
|
||||
case .error: .red
|
||||
case .none: .gray
|
||||
}
|
||||
|
||||
let cell = LabeledContent(title) {
|
||||
Circle()
|
||||
.fill(color)
|
||||
.frame(width: 16, height: 16)
|
||||
}
|
||||
|
||||
if let model, let error = model.error {
|
||||
cell.navigationLink {
|
||||
viewModel.showAlert(text: error, status: model.status)
|
||||
}
|
||||
} else {
|
||||
cell
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ReportScreen(viewModel: .init(vehicle: .preview))
|
||||
ReportScreen(viewModel: .init(vehicle: .preview, isPersistent: false))
|
||||
}
|
||||
|
||||
@ -15,9 +15,11 @@ class ReportViewModel: ACHudContainer {
|
||||
|
||||
@ObservationIgnored @Service var api: ApiServiceProtocol
|
||||
@ObservationIgnored @Service var storageService: StorageServiceProtocol
|
||||
@ObservationIgnored @Service var settings: SettingsServiceProtocol
|
||||
|
||||
var coordinator: ReportCoordinator?
|
||||
|
||||
let isPersistent: Bool
|
||||
var vehicle: VehicleDto
|
||||
var hud: ACHud?
|
||||
|
||||
@ -41,8 +43,19 @@ class ReportViewModel: ACHudContainer {
|
||||
: NSLocalizedString("No", comment: "")
|
||||
}
|
||||
|
||||
init(vehicle: VehicleDto) {
|
||||
var showDebugInfo: Bool {
|
||||
settings.showDebugInfo
|
||||
}
|
||||
|
||||
init(vehicle: VehicleDto, isPersistent: Bool) {
|
||||
self.vehicle = vehicle
|
||||
self.isPersistent = isPersistent
|
||||
}
|
||||
|
||||
func onAppear() async {
|
||||
if isPersistent {
|
||||
await loadVehicle()
|
||||
}
|
||||
}
|
||||
|
||||
func loadVehicle() async {
|
||||
@ -53,6 +66,14 @@ class ReportViewModel: ACHudContainer {
|
||||
}
|
||||
}
|
||||
|
||||
func showAlert(text: String, status: DebugInfoStatus) {
|
||||
switch status {
|
||||
case .success: showSuccess(text: text)
|
||||
case .warning: showWarning(text: text)
|
||||
case .error: showError(text: text)
|
||||
}
|
||||
}
|
||||
|
||||
func openEvents() {
|
||||
coordinator?.openEvents(vehicle: vehicle)
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ enum ACHud: Equatable, Identifiable, Sendable {
|
||||
|
||||
case progress
|
||||
case error(Error)
|
||||
case message(String, ACMessageView.MessageType = .info)
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
@ -17,6 +18,8 @@ enum ACHud: Equatable, Identifiable, Sendable {
|
||||
"progress"
|
||||
case .error(let error):
|
||||
error.localizedDescription
|
||||
case .message(let text, _):
|
||||
text
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +29,8 @@ enum ACHud: Equatable, Identifiable, Sendable {
|
||||
true
|
||||
case (let .error(lerr), let .error(rerr)):
|
||||
lerr.localizedDescription == rerr.localizedDescription
|
||||
case (let .message(lmsg, ltype), let .message(rmsg, rtype)):
|
||||
lmsg == rmsg && ltype == rtype
|
||||
default:
|
||||
false
|
||||
}
|
||||
|
||||
@ -31,4 +31,24 @@ extension ACHudContainer where Self: AnyObject {
|
||||
hud = .error(error)
|
||||
}
|
||||
}
|
||||
|
||||
func showInfo(text: String) {
|
||||
hud = .message(text, .info)
|
||||
}
|
||||
|
||||
func showWarning(text: String) {
|
||||
hud = .message(text, .warning)
|
||||
}
|
||||
|
||||
func showSuccess(text: String) {
|
||||
hud = .message(text, .success)
|
||||
}
|
||||
|
||||
func showError(text: String) {
|
||||
hud = .message(text, .error)
|
||||
}
|
||||
|
||||
func showError(_ error: Error) {
|
||||
hud = .error(error)
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,11 @@ struct ACProgressHudModifier: ViewModifier {
|
||||
type: .error) {
|
||||
self.item = nil
|
||||
}
|
||||
case .message(let message, let type):
|
||||
ACMessageView(message: message,
|
||||
type: type) {
|
||||
self.item = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,6 +165,7 @@ extension Vehicle: DtoConvertible {
|
||||
notes.append(objectsIn: dto.notes.map(VehicleNote.init))
|
||||
self.notes = notes
|
||||
|
||||
self.debugInfo = DebugInfo(dto: dto.debugInfo)
|
||||
self.synchronized = dto.synchronized
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,21 +12,24 @@ import AutoCatCore
|
||||
@testable import AutoCat
|
||||
|
||||
@MainActor
|
||||
struct ReportTests {
|
||||
class ReportTests {
|
||||
|
||||
let existingVehicleNumber = "А123АА761"
|
||||
let nonExistingVehicleNumber = "А999АА761"
|
||||
let testColor = "testColor"
|
||||
|
||||
var storageServiceMock: MockStorageServiceProtocol
|
||||
var settingsServiceMock: MockSettingsServiceProtocol
|
||||
|
||||
var viewModel: ReportViewModel
|
||||
|
||||
init() {
|
||||
storageServiceMock = MockStorageServiceProtocol()
|
||||
settingsServiceMock = MockSettingsServiceProtocol()
|
||||
|
||||
ServiceContainer.shared.register(StorageServiceProtocol.self, instance: storageServiceMock)
|
||||
viewModel = ReportViewModel(vehicle: VehicleDto())
|
||||
ServiceContainer.shared.register(SettingsServiceProtocol.self, instance: settingsServiceMock)
|
||||
viewModel = ReportViewModel(vehicle: VehicleDto(), isPersistent: true)
|
||||
}
|
||||
|
||||
@Test("Load vehicle detail")
|
||||
@ -35,7 +38,7 @@ struct ReportTests {
|
||||
let incompleteVehicleModel = VehicleDto(number: existingVehicleNumber)
|
||||
let fullVehicleModel = VehicleDto(number: existingVehicleNumber, color: testColor)
|
||||
|
||||
viewModel.vehicle = incompleteVehicleModel
|
||||
viewModel = ReportViewModel(vehicle: incompleteVehicleModel, isPersistent: true)
|
||||
|
||||
#expect(viewModel.vehicle.color == nil)
|
||||
|
||||
@ -43,7 +46,11 @@ struct ReportTests {
|
||||
.loadVehicle(number: .value(existingVehicleNumber))
|
||||
.willReturn(fullVehicleModel)
|
||||
|
||||
await viewModel.loadVehicle()
|
||||
await viewModel.onAppear()
|
||||
|
||||
verify(storageServiceMock)
|
||||
.loadVehicle(number: .value(existingVehicleNumber))
|
||||
.called(.once)
|
||||
|
||||
#expect(viewModel.vehicle.color == testColor)
|
||||
#expect(viewModel.hud == nil)
|
||||
@ -52,12 +59,29 @@ struct ReportTests {
|
||||
@Test("Load vehicle error")
|
||||
func loadVehicleError() async throws {
|
||||
|
||||
viewModel = ReportViewModel(vehicle: VehicleDto(), isPersistent: true)
|
||||
|
||||
given(storageServiceMock)
|
||||
.loadVehicle(number: .any)
|
||||
.willThrow(StorageError.vehicleNotFound)
|
||||
|
||||
await viewModel.loadVehicle()
|
||||
await viewModel.onAppear()
|
||||
|
||||
verify(storageServiceMock)
|
||||
.loadVehicle(number: .any)
|
||||
.called(.once)
|
||||
|
||||
#expect(viewModel.hud == .error(StorageError.vehicleNotFound))
|
||||
}
|
||||
|
||||
@Test("Show debug info", arguments: [true, false])
|
||||
func showDebugInfo(value: Bool) async throws {
|
||||
|
||||
viewModel = ReportViewModel(vehicle: VehicleDto(), isPersistent: false)
|
||||
|
||||
given(settingsServiceMock)
|
||||
.showDebugInfo.willReturn(value)
|
||||
|
||||
#expect(viewModel.showDebugInfo == value)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user