Skip to content

Conversation

@iamgabrielma
Copy link
Contributor

@iamgabrielma iamgabrielma commented Aug 28, 2025

Closes WOOMOB-1176
Closes WOOMOB-1188
Closes WOOMOB-1205

Description

This PR adjusts and cleans up the responsibilities of the PointOfSaleSettingsController by:

  • DI settingsService and pluginsService into the settingsController
  • Remove usage of siteID from the protocol
  • Make a dedicated struct for receipt data
  • Make a dedicated view model for the store details view

I've also added a temporary "ghost table" for the loading state:

Screen.Recording.2025-08-28.at.20.43.46.mov

Testing

  • CI should pass.
  • Access to POS Settings should work the same as before, there is no user-face changes except the loading state.

@dangermattic
Copy link
Collaborator

dangermattic commented Aug 28, 2025

1 Warning
⚠️ This PR is larger than 300 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Aug 28, 2025

App Icon📲 You can test the changes from this Pull Request in WooCommerce iOS Prototype by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS Prototype
Build Numberpr16053-3e9979f
Version23.1
Bundle IDcom.automattic.alpha.woocommerce
Commit3e9979f
Installation URL1n9j4tivpvesg
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

@iamgabrielma iamgabrielma changed the title [POS Settings] DI PluginService in SettingsController. Clear protocol interface. Model for store details. [POS Settings] Adjust settings Controller-Service interface and dependencies Aug 28, 2025
}

// Temporary: Simplified copy from PointOfSaleOrderListView.GhostOrderRowView
private struct GhostSettingRowView: View {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is a mere copy of existing GhostOrderRowView, where I removed one of the extra lines. I'll iterate on this when I do the final design iteration tomorrow/next week.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondering, this is a separate UI enhancement from the architecture changes right? or does this become necessary after the refactoring? I'm not sure what the differences between these two structs, would be great to reuse the shared component if applicable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a separate UI enhancement from the architecture changes right? or does this become necessary after the refactoring?

That's separate from the architecture changes yes, just added it temporarily to reflect isLoading state changes in the UI. I'll be updating the struct in the next PR with the rest of UI updates 👍

@iamgabrielma iamgabrielma marked this pull request as ready for review August 28, 2025 13:50
@iamgabrielma iamgabrielma added type: task An internally driven task. feature: POS labels Aug 28, 2025
@iamgabrielma iamgabrielma added this to the 23.2 milestone Aug 28, 2025
@iamgabrielma iamgabrielma requested a review from jaclync August 28, 2025 13:51
Copy link
Contributor

@jaclync jaclync left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the changes and unit tests, still working as expected :shipit: just some non-blocking comments.

import enum Yosemite.Plugin
import struct Yosemite.SiteSetting

final class StoreSettingsViewModel: ObservableObject {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: on the first glance, I thought this is a class from store management. Maybe the prefix could be added for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah! Updated 037c47d

Comment on lines 63 to 65
viewModel: StoreSettingsViewModel(siteID: settingsController.siteID,
settingsService: settingsController.settingsService,
pluginsService: settingsController.pluginsService))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: with the current implementation, the view model isn't owned by any class and just initialized whenever this view is redrawn. Do we want the settings controller to own this view model, like if we want to keep the already retrieved receipt settings? This way, these 3 dependenceis (siteID, settingsService, pluginsService) don't have to be public either.

struct PointOfSaleSettingsStoreDetailView: View {
@State private var isLoading: Bool = false

let settingsController: PointOfSaleSettingsControllerProtocol
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it looks like settingsController is now only needed for storeName and storeAddress. Could these two values be provided by the view model, if no other settings sections need these info? so that the view only relies on the view model, leaving settings controller for keeping global states?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very true, updated: 3af72b4

}

// Temporary: Simplified copy from PointOfSaleOrderListView.GhostOrderRowView
private struct GhostSettingRowView: View {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wondering, this is a separate UI enhancement from the architecture changes right? or does this become necessary after the refactoring? I'm not sure what the differences between these two structs, would be great to reuse the shared component if applicable.

Comment on lines 51 to 57
receiptInformation = POSReceiptInformation(
storeName: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_name"),
storeAddress: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_address"),
phone: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_phone"),
email: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_email"),
refundReturnsPolicy: settingValue(from: siteSettings, settingID: "woocommerce_pos_refund_returns_policy")
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: how about moving the setting value mapping to settingsService.retrievePointOfSaleSettings for these fields in Yosemite, so that the method returns POSReceiptInformation? If there are more than receipt settings in the settings from this method, POSReceiptInformation can be included in a new struct as the return type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, at the moment is only receipt info, but I can foresee we'll have more pretty soon. Moved to Yosemite and updated: 951d0ad

#expect(sut.shouldShowReceiptInformation == false)
}

@Test func retrievePOSReceiptSettings_when_no_plugin_then_shouldShowReceiptInformation_returns_false() async throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice test cases for different plugin states 👍

@iamgabrielma iamgabrielma enabled auto-merge August 31, 2025 07:45
@iamgabrielma iamgabrielma merged commit 61afa87 into trunk Aug 31, 2025
14 checks passed
@iamgabrielma iamgabrielma deleted the task/WOOMOB-1176-DI-pluginservice-in-settings-controller branch August 31, 2025 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: POS type: task An internally driven task.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants