Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Fields: Editor UI #13863

Merged
merged 16 commits into from
Sep 19, 2024
Merged

Custom Fields: Editor UI #13863

merged 16 commits into from
Sep 19, 2024

Conversation

hafizrahman
Copy link
Contributor

@hafizrahman hafizrahman commented Sep 5, 2024

Part of: #13493

Description

This PR adds the UI for editing custom fields.

These items are missing and should be added separately when working on functionality:

  1. Any editing functionalities
  2. The strings are not translatable yet! Given the potential complexity of replacing a string later on if it's been translated, I opt to keep things hardcoded. Once we finalize the design copy, we can convert them into translatable strings. They've all been commented
  3. Undo UI after deleting a custom field
  4. Validation/not allowing for entering duplicate key

Steps to reproduce

  1. Prepare some orders with Custom Fields added to it, if you haven't,
  2. Go to Orders,
  3. Select the order from step 1,
  4. Tap View Custom Fields,
  5. Ensure the Custom Fields list is shown. Compare with screenshot below.
  6. Tap an item,
  7. Ensure the Custom Fields edit screen is shown.
    • Check the general UI elements on the screen, compare with screenshot below.
    • Ensure the fields are editable,
    • Ensure that Save is disabled unless new edit is added,
    • Ensure the triple dot menu is shown, and tappable to show a sheet with three options (no functionality yet),
    • Ensure the Edit in Rich Text Editor opens the Aztec editor when tapped, and that its Cancel button works.

Testing information

I tested this on Simulator by going through the Order > Custom Fields flow as listed above.

Screenshots

Custom fields list Custom field editor
Simulator Screenshot - iPhone 15 Pro - 2024-09-09 at 13 36 52 Simulator Screenshot - iPhone 15 Pro - 2024-09-09 at 13 37 02
Custom fields sheet Custom fields edit Aztec
Simulator Screenshot - iPhone 15 Pro - 2024-09-09 at 13 37 09 Simulator Screenshot - iPhone 15 Pro - 2024-09-09 at 13 37 17

  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Reviewer (or Author, in the case of optional code reviews):

Please make sure these conditions are met before approving the PR, or request changes if the PR needs improvement:

  • The PR is small and has a clear, single focus, or a valid explanation is provided in the description. If needed, please request to split it into smaller PRs.
  • Ensure Adequate Unit Test Coverage: The changes are reasonably covered by unit tests or an explanation is provided in the PR description. <-- no unit tests as this is just UI.
  • Manual Testing: The author listed all the tests they ran, including smoke tests when needed (e.g., for refactorings). The reviewer confirmed that the PR works as expected on all devices (phone/tablet) and no regressions are added.

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Sep 5, 2024

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

App NameWooCommerce iOS WooCommerce iOS
Build Numberpr13863-91b89de
Version20.4
Bundle IDcom.automattic.alpha.woocommerce
Commit91b89de
App Center BuildWooCommerce - Prototype Builds #10922
Automatticians: You can use our internal self-serve MC tool to give yourself access to App Center if needed.

@hafizrahman hafizrahman added this to the 20.4 milestone Sep 9, 2024
@hafizrahman hafizrahman added the type: task An internally driven task. label Sep 9, 2024
@hafizrahman hafizrahman marked this pull request as ready for review September 9, 2024 06:39
Comment on lines 53 to 56
var containsHTML: Bool {
let stripped = self.strippedHTML
return stripped != self
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@hichamboushaba and I discussed back and forth on this whether to display Aztec automatically or not when the content is HTML, and this function is meant to support that.

This function is not yet used in any part of the PR since the latest decision is to show a button to show Aztec separately, but might be needed later on. It can also be deleted later once we finalize everything.

Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to have a unit test for this property

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With the latest conversation I think we want to make aztec editor available to all kind of text, and let user choose to use it instead of automatically selecting it for them, so this becomes unnecessary anymore. Removed in 45624f2

Copy link
Member

@pmusolino pmusolino left a comment

Choose a reason for hiding this comment

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

I reviewed the PR and this is what I found:

Missing fields

I noticed that, for some reason, one custom field doesn't appear in one order, while in another order the same custom field appears. The only difference is that the order where the custom field doesn't appear is in Processing status, while the other one is completed. After adding an extra custom field, then it started to appear. Any guess why this is happening? The value of the custom field is the same between those orders.

Expected custom field What I see in that order
Simulator Screenshot - iPhone 15 Pro Max - 2024-09-09 at 18 27 56 Simulator Screenshot - iPhone 15 Pro Max - 2024-09-09 at 18 28 07

Fields editing

When you tap on one field in the list, specifically you tap on title or description, they do not open at all. This often happens with custom fields containing long text. Sometimes, when you press on them, they appear to be in a "selectable" status, but I cannot navigate to the details until I press on the borders of the cell.

Comment on lines 53 to 56
var containsHTML: Bool {
let stripped = self.strippedHTML
return stripped != self
}
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to have a unit test for this property

Comment on lines +1 to +24
import SwiftUI

struct AztecEditorView: UIViewControllerRepresentable {
@Binding var html: String

func makeUIViewController(context: Context) -> AztecEditorViewController {
let viewProperties = EditorViewProperties(navigationTitle: "Navigation title", /* todo replace string */
placeholderText: "placeholder text", /* todo replace string */
showSaveChangesActionSheet: true)

let controller = AztecEditorViewController(
content: html,
product: nil,
viewProperties: viewProperties,
isAIGenerationEnabled: false
)

return controller
}

func updateUIViewController(_ uiViewController: AztecEditorViewController, context: Context) {
// Update the view controller if needed
}
}
Copy link
Member

Choose a reason for hiding this comment

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

This struct looks like something that could be used elsewhere in the future, so I strongly suggest moving it to a different file.

Copy link
Contributor Author

@hafizrahman hafizrahman Sep 11, 2024

Choose a reason for hiding this comment

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

I'm working on this on a separate PR, here #13925

struct CustomFieldEditorView: View {
@State private var key: String
@State private var value: String
@State private var isModified: Bool = false
Copy link
Member

Choose a reason for hiding this comment

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

I think hasUnsavedChanges is clearer and is already used throughout the app.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good! Updated in 22e7f3e

Comment on lines +165 to +193
private struct RichTextEditor: View {
@Binding var html: String
@State private var isModified: Bool = false
@Environment(\.presentationMode) var presentationMode

var body: some View {
NavigationView {
AztecEditorView(html: $html)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button {
presentationMode.wrappedValue.dismiss()
} label: {
Text("Cancel") // todo-13493: set String to be translatable
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button {
// todo-13493: implement save action
presentationMode.wrappedValue.dismiss()
} label: {
Text("Done") // todo-13493: set String to be translatable
}
.disabled(!isModified)
}
}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

I would also move this to a separate file since it could be reused.

Copy link
Contributor Author

@hafizrahman hafizrahman Sep 11, 2024

Choose a reason for hiding this comment

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

Also worked on separate PR #13925

static let sectionSpacing: CGFloat = 16
static let subSectionsSpacing: CGFloat = 8
static let cornerRadius: CGFloat = 8
static let inputInsets = EdgeInsets(top: 8, leading: 5, bottom: 8, trailing: 5)
Copy link
Member

Choose a reason for hiding this comment

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

This is the first time I've seen 5 used as padding in the app. Are we sure it shouldn't have been 6 or 8?

Copy link
Contributor Author

@hafizrahman hafizrahman Sep 11, 2024

Choose a reason for hiding this comment

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

For more context on this, I was looking at existing UI pattern in the app that shows more than 1 input fields on one screen (key/value input in our case).

That layout is surprisingly rare in our app, and I was able to find it in the Contact Support screen:

The layout here is pretty much a copy from there, here:

static let subjectInsets = EdgeInsets(top: 8, leading: 5, bottom: 8, trailing: 5)

Copy link
Member

@pmusolino pmusolino Sep 12, 2024

Choose a reason for hiding this comment

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

Got it :D I think this is an "error" also there probably

/// - key: The key for the custom field
/// - value: The value for the custom field
/// - isReadOnlyValue: Whether the value is read-only or not. To be used if the value is not string but JSON.
init(key: String, value: String, isReadOnlyValue: Bool = false) {
Copy link
Member

Choose a reason for hiding this comment

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

Why not pass the CustomFieldViewModel as input here? Any specific reason?

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 editor will also be used when adding a new custom field, and my thinking was that we don't need all the extra information in CustomFieldViewModel for this purpose, and instead just pass empty strings instead. wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's fine to start with, but consider you should not be able to test the editor logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point here, I'll keep in mind for future refactor I think!

title: customField.title,
content: customField.content,
contentURL: customField.contentURL)
if isEditable {
Copy link
Member

Choose a reason for hiding this comment

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

If not editable, it would be nice to show an alert, explaining why

Copy link
Contributor Author

Choose a reason for hiding this comment

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

isEditable here is simply a flag that contains the feature flag check while we're still developing. Once we're done, this will be removed as any field will be tappable (I see that it's confusing and probably should be isTappable instead of isEditable).

We do have a special type (JSON value) that can be tapped but can't be edited (refer to isReadOnlyValue param in CustomFieldEditorView). I agree we should let users know why this is not editable, whether with alert or a sort of label above the text box.

@hafizrahman
Copy link
Contributor Author

I noticed that, for some reason, one custom field doesn't appear in one order, while in another order the same custom field appears. The only difference is that the order where the custom field doesn't appear is in Processing status, while the other one is completed. After adding an extra custom field, then it started to appear. Any guess why this is happening? The value of the custom field is the same between those orders.

Interesting observation! There is no change in this PR in terms of which custom fields are shown, it's simply using all the metadata that the order has:

            let customFields = order.customFields.map {
                CustomFieldViewModel(metadata: $0)
            }
            let customFieldsView = UIHostingController(
                rootView: CustomFieldsListView(
                    isEditable: featureFlagService.isFeatureFlagEnabled(.viewEditCustomFieldsInProductsAndOrders),
                    customFields: customFields))
            viewController.present(customFieldsView, animated: true)

So, whatever the issue is, it already exists prior to this PR. I'll see if I can replicate it and put it in a separate issue.

@hafizrahman
Copy link
Contributor Author

When you tap on one field in the list, specifically you tap on title or description, they do not open at all. This often happens with custom fields containing long text.

Thanks! This was inconsistent to me but I was able to replicate from time to time. I added fdf7def that should fix it.

@hafizrahman
Copy link
Contributor Author

@pmusolino Thank you for the reviews! Aside from separating the Aztec view to their own file, which will be handled in this PR, I believe I've responded to all the review items. Good for another round of review!

Copy link
Member

@pmusolino pmusolino left a comment

Choose a reason for hiding this comment

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

Good to go 🎸

@wpmobilebot wpmobilebot removed this from the 20.4 milestone Sep 13, 2024
@wpmobilebot wpmobilebot added this to the 20.5 milestone Sep 13, 2024
@wpmobilebot
Copy link
Collaborator

Version 20.4 has now entered code-freeze, so the milestone of this PR has been updated to 20.5.

@dangermattic
Copy link
Collaborator

1 Warning
⚠️ This PR is assigned to the milestone 20.5. This milestone is due in less than 2 days.
Please make sure to get it merged by then or assign it to a milestone with a later deadline.

Generated by 🚫 Danger

@hafizrahman hafizrahman merged commit f9b95e7 into trunk Sep 19, 2024
13 of 14 checks passed
@hafizrahman hafizrahman deleted the feat/13493-custom-fields-edit-ui branch September 19, 2024 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: task An internally driven task.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants