Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,33 +22,44 @@ struct POSInformationCardFieldRow: View {
case primary
}

enum LabelStyle {
case regular
case bold
}

let label: String
let value: String
let showSeparator: Bool
let labelStyle: LabelStyle
let buttonTitle: String?
let buttonAction: (() -> Void)?
let buttonStyle: ButtonStyle
let isLoading: Bool

init(label: String,
value: String,
showSeparator: Bool = true,
labelStyle: LabelStyle = .regular,
buttonTitle: String? = nil,
buttonAction: (() -> Void)? = nil,
buttonStyle: ButtonStyle = .default) {
buttonStyle: ButtonStyle = .default,
isLoading: Bool = false) {
self.label = label
self.value = value
self.showSeparator = showSeparator
self.labelStyle = labelStyle
self.buttonTitle = buttonTitle
self.buttonAction = buttonAction
self.buttonStyle = buttonStyle
self.isLoading = isLoading
}

var body: some View {
VStack(alignment: .leading, spacing: POSPadding.small) {
HStack(alignment: .center, spacing: POSSpacing.medium) {
VStack(alignment: .leading, spacing: POSPadding.small) {
Text(label)
.font(.posBodyMediumRegular())
.font(labelStyle == .bold ? .posBodyMediumBold : .posBodyMediumRegular())
Text(value)
.font(.posBodyMediumRegular())
.foregroundStyle(.secondary)
Expand All @@ -60,7 +71,8 @@ struct POSInformationCardFieldRow: View {
Button(buttonTitle, action: buttonAction)
.buttonStyle(POSInfoCardButtonStyle(
size: .compact,
variant: buttonStyle == .primary ? .primary : .default
variant: buttonStyle == .primary ? .primary : .default,
isLoading: isLoading
))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import SwiftUI

struct POSInformationCardFieldRowWithToggle: View {
let label: String
let value: String
let showSeparator: Bool
@Binding var isOn: Bool

init(label: String,
value: String,
showSeparator: Bool = true,
isOn: Binding<Bool>) {
self.label = label
self.value = value
self.showSeparator = showSeparator
self._isOn = isOn
}

var body: some View {
VStack(alignment: .leading, spacing: POSPadding.small) {
HStack(alignment: .center, spacing: POSSpacing.medium) {
VStack(alignment: .leading, spacing: POSPadding.small) {
Text(label)
.font(.posBodyMediumBold)
Text(value)
.font(.posBodyMediumRegular())
.foregroundStyle(.secondary)
}

Spacer()

Toggle("", isOn: $isOn)
.toggleStyle(SwitchToggleStyle())
.tint(Color.posPrimaryContainer)
}

if showSeparator {
Divider()
.padding(.top, POSPadding.small)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import SwiftUI

struct POSSettingsLocalCatalogDetailView: View {
// TODO: WOOMOB-1335 - implement full sync cellular data setting functionality
private let viewModel: POSSettingsLocalCatalogViewModel

init(viewModel: POSSettingsLocalCatalogViewModel) {
Expand Down Expand Up @@ -35,96 +34,63 @@ struct POSSettingsLocalCatalogDetailView: View {
private extension POSSettingsLocalCatalogDetailView {
@ViewBuilder
var catalogStatus: some View {
VStack(spacing: POSSpacing.none) {
sectionHeaderView(title: Localization.catalogStatus)

VStack(spacing: POSSpacing.medium) {
fieldRowView(label: Localization.catalogSize, value: viewModel.catalogSize)
fieldRowView(label: Localization.lastIncrementalUpdate, value: viewModel.lastIncrementalSyncDate)
fieldRowView(label: Localization.lastFullSync, value: viewModel.lastFullSyncDate)
POSInformationCard {
VStack(spacing: POSSpacing.small) {
POSInformationCardFieldRow(
label: Localization.catalogSize,
value: viewModel.catalogSize
)
POSInformationCardFieldRow(
label: Localization.lastIncrementalSync,
value: viewModel.lastIncrementalSyncDate
)
POSInformationCardFieldRow(
label: Localization.lastFullSync,
value: viewModel.lastFullSyncDate,
showSeparator: false
)
}
.padding(.bottom, POSPadding.medium)
.redacted(reason: viewModel.isLoading ? .placeholder : [])
.shimmering(active: viewModel.isLoading)
}
.redacted(reason: viewModel.isLoading ? .placeholder : [])
.shimmering(active: viewModel.isLoading)
}

@ViewBuilder
var managingDataUsage: some View {
@Bindable var viewModel = viewModel
VStack(spacing: POSSpacing.none) {
sectionHeaderView(title: Localization.managingDataUsage)

VStack(spacing: POSSpacing.medium) {
toggleRowView(label: Localization.allowFullSyncOnCellular, isOn: $viewModel.allowFullSyncOnCellular)
POSInformationCard {
POSInformationCardFieldRowWithToggle(
label: Localization.managingDataUsage,
value: Localization.allowSyncOnCellular,
showSeparator: false,
isOn: $viewModel.allowFullSyncOnCellular
)
}
.padding(.bottom, POSPadding.medium)
}
}

@ViewBuilder
var manualCatalogUpdate: some View {
VStack(spacing: POSSpacing.none) {
sectionHeaderView(title: Localization.manualCatalogUpdate)

VStack(spacing: POSSpacing.medium) {
Text(Localization.manualUpdateInfo)
.font(.posCaptionRegular)
.foregroundStyle(.secondary)
.frame(maxWidth: .infinity, alignment: .leading)

Button(action: {
Task {
await viewModel.refreshCatalog()
}
}) {
Text(Localization.refreshCatalog)
}
.buttonStyle(POSFilledButtonStyle(size: .normal, isLoading: viewModel.isRefreshingCatalog))
POSInformationCard {
POSInformationCardFieldRow(
label: Localization.manualCatalogUpdate,
value: Localization.manualUpdateInfo,
showSeparator: false,
labelStyle: .bold,
buttonTitle: Localization.updateCatalog,
buttonAction: {
Task {
await viewModel.refreshCatalog()
}
},
buttonStyle: .primary,
isLoading: viewModel.isRefreshingCatalog
)
}
.padding(.horizontal, POSPadding.medium)
.padding(.bottom, POSPadding.medium)
}
}

@ViewBuilder
func sectionHeaderView(title: String) -> some View {
ZStack {
Style.backgroundColor
Text(title)
.font(.posBodyLargeBold)
.foregroundColor(.posOnSurface)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, POSPadding.medium)
.padding(.vertical, POSPadding.small)
}
}

@ViewBuilder
func fieldRowView(label: String, value: String) -> some View {
VStack(alignment: .leading, spacing: POSPadding.small) {
Text(label)
.font(.posBodyMediumRegular())
Text(value)
.font(.posBodyMediumRegular())
.foregroundStyle(.secondary)
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, POSPadding.medium)
}

@ViewBuilder
func toggleRowView(label: String, isOn: Binding<Bool>) -> some View {
HStack {
Text(label)
.font(.posBodyMediumRegular())
Spacer()
Toggle("", isOn: isOn)
.toggleStyle(SwitchToggleStyle())
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal, POSPadding.medium)
}
}

private extension POSSettingsLocalCatalogDetailView {
Expand All @@ -134,65 +100,57 @@ private extension POSSettingsLocalCatalogDetailView {

enum Localization {
static let localCatalogTitle = NSLocalizedString(
"posSettingsLocalCatalogDetailView.title",
value: "Catalog Settings",
"posSettingsLocalCatalogDetailView.title.1",
value: "Product catalog",
comment: "Navigation title for the local catalog details in POS settings."
)

static let catalogStatus = NSLocalizedString(
"posSettingsLocalCatalogDetailView.catalogStatus",
value: "Catalog Status",
comment: "Section title for catalog status in Point of Sale settings."
)

static let managingDataUsage = NSLocalizedString(
"posSettingsLocalCatalogDetailView.managingDataUsage.1",
value: "Managing Data Usage",
"posSettingsLocalCatalogDetailView.managingDataUsage.2",
value: "Cellular data",
comment: "Section title for managing data usage in Point of Sale settings."
)

static let lastIncrementalUpdate = NSLocalizedString(
"posSettingsLocalCatalogDetailView.lastIncrementalSync",
value: "Last update",
comment: "Label for last incremental update field in Point of Sale settings."
static let lastIncrementalSync = NSLocalizedString(
"posSettingsLocalCatalogDetailView.lastIncrementalSync.1",
value: "Last incremental sync",
comment: "Label for last incremental sync field in Point of Sale settings."
)

static let lastFullSync = NSLocalizedString(
"posSettingsLocalCatalogDetailView.lastFullSync.1",
value: "Last full update",
"posSettingsLocalCatalogDetailView.lastFullSync.2",
value: "Last full sync",
comment: "Label for last full sync field in Point of Sale settings."
)

static let catalogSize = NSLocalizedString(
"posSettingsLocalCatalogDetailView.catalogSize",
value: "Catalog size",
"posSettingsLocalCatalogDetailView.catalogSize.1",
value: "Size",
comment: "Label for catalog size field in Point of Sale settings."
)


static let allowFullSyncOnCellular = NSLocalizedString(
"posSettingsLocalCatalogDetailView.allowFullSyncOnCellular.1",
value: "Allow full update on cellular data",
comment: "Label for allow full sync on cellular data toggle in Point of Sale settings."
static let allowSyncOnCellular = NSLocalizedString(
"posSettingsLocalCatalogDetailView.allowSyncOnCellular.2",
value: "Allow sync using cellular data",
comment: "Label for allow sync on cellular data toggle in Point of Sale settings."
)


static let manualCatalogUpdate = NSLocalizedString(
"posSettingsLocalCatalogDetailView.manualCatalogUpdate",
value: "Manual Catalog Update",
"posSettingsLocalCatalogDetailView.manualCatalogUpdate.1",
value: "Catalog update",
comment: "Section title for manual catalog update in Point of Sale settings."
)

static let manualUpdateInfo = NSLocalizedString(
"posSettingsLocalCatalogDetailView.manualUpdateInfo",
value: "Use this refresh only when something seems off - POS keeps data current automatically.",
comment: "Info text explaining when to use manual catalog update."
"posSettingsLocalCatalogDetailView.manualUpdateInfo.1",
value: "Update the catalog manually",
comment: "Info text explaining the usage of the manual catalog update button."
)

static let refreshCatalog = NSLocalizedString(
"posSettingsLocalCatalogDetailView.refreshCatalog",
value: "Refresh catalog",
comment: "Button text for refreshing the catalog manually."
static let updateCatalog = NSLocalizedString(
"posSettingsLocalCatalogDetailView.updateCatalog",
value: "Update catalog",
comment: "Button text for updating the catalog manually."
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private extension POSSettingsLocalCatalogViewModel {
enum Localization {
static let catalogSizeFormat = NSLocalizedString(
"posSettingsLocalCatalogViewModel.catalogSizeFormat",
value: "%1$d products, %2$ld variations",
value: "%1$d products and %2$ld variations",
comment: "Format string for catalog size showing product count and variation count. " +
"%1$d will be replaced by the product count, and %2$ld will be replaced by the variation count."
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ extension POSSettingsView {
)

static let sidebarNavigationLocalCatalogTitle = NSLocalizedString(
"pointOfSaleSettingsView.sidebarNavigationLocalCatalogTitle",
value: "Catalog",
"pointOfSaleSettingsView.sidebarNavigationLocalCatalogTitle.2",
value: "Product catalog",
comment: "Title of the Local catalog section within Point of Sale settings."
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct POSSettingsLocalCatalogViewModelTests {
await sut.loadCatalogData()

// Then
#expect(sut.catalogSize == "150 products, 75 variations")
#expect(sut.catalogSize == "150 products and 75 variations")
#expect(sut.lastFullSyncDate.contains("ago"))
#expect(sut.lastIncrementalSyncDate.contains("ago"))
#expect(sut.isLoading == false)
Expand Down Expand Up @@ -81,7 +81,7 @@ struct POSSettingsLocalCatalogViewModelTests {
await sut.loadCatalogData()

// Then
#expect(sut.catalogSize == "100 products, 50 variations")
#expect(sut.catalogSize == "100 products and 50 variations")
#expect(sut.lastFullSyncDate == "Not updated")
#expect(sut.lastIncrementalSyncDate == "Not updated")
}
Expand Down Expand Up @@ -128,7 +128,7 @@ struct POSSettingsLocalCatalogViewModelTests {
// Then
#expect(catalogSyncCoordinator.performFullSyncInvocationCount == 1)
#expect(catalogSyncCoordinator.performFullSyncSiteID == sampleSiteID)
#expect(sut.catalogSize == "200 products, 100 variations")
#expect(sut.catalogSize == "200 products and 100 variations")
#expect(sut.isRefreshingCatalog == false)
}

Expand Down Expand Up @@ -198,7 +198,7 @@ struct POSSettingsLocalCatalogViewModelTests {
await refreshTask.value

// Then
#expect(sut.catalogSize == "100 products, 50 variations")
#expect(sut.catalogSize == "100 products and 50 variations")
#expect(sut.isLoading == false)
#expect(sut.isRefreshingCatalog == false)
#expect(catalogSyncCoordinator.performFullSyncInvocationCount == 1)
Expand Down