Skip to content

Commit f22bf57

Browse files
authored
Merge pull request #2298 from woocommerce/issue/2279-order-details-rearrange-headers
Order Details → Rearrange Header Elements
2 parents b30d41a + ab60fb8 commit f22bf57

File tree

12 files changed

+415
-353
lines changed

12 files changed

+415
-353
lines changed

WooCommerce/Classes/Extensions/Date+Woo.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ extension Date {
106106

107107
return selfYear == otherYear
108108
}
109+
110+
/// Returns `true` if `self` is in the same day as `other`.
111+
///
112+
func isSameDay(as other: Date, using calendar: Calendar = .current) -> Bool {
113+
calendar.isDate(self, inSameDayAs: other)
114+
}
109115
}
110116

111117

WooCommerce/Classes/Extensions/DateFormatter+Helpers.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,12 @@ extension DateFormatter {
138138
formatter.setLocalizedDateFormatFromTemplate("yyyy")
139139
return formatter
140140
}()
141+
142+
/// Localized date formatter that generates the time only. Example, “11:23 AM”.
143+
///
144+
static let timeFormatter: DateFormatter = {
145+
let formatter = DateFormatter()
146+
formatter.setLocalizedDateFormatFromTemplate("hh:mm a")
147+
return formatter
148+
}()
141149
}

WooCommerce/Classes/ViewModels/Order Details/OrderDetailsDataSource.swift

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,6 @@ final class OrderDetailsDataSource: NSObject {
3333
///
3434
var trackingIsReachable: Bool = false
3535

36-
/// For example, #560 Pamela Nguyen
37-
///
38-
var summaryTitle: String? {
39-
if let billingAddress = order.billingAddress {
40-
return "#\(order.number) \(billingAddress.firstName) \(billingAddress.lastName)"
41-
}
42-
return "#\(order.number)"
43-
}
44-
45-
/// For example, Oct 1, 2019 at 2:31 PM
46-
///
47-
private var summaryDateCreated: String {
48-
return order.dateModified.relativelyFormattedUpdateString
49-
}
50-
5136
/// Closure to be executed when the cell was tapped.
5237
///
5338
var onCellAction: ((CellActionType, IndexPath?) -> Void)?
@@ -506,18 +491,16 @@ private extension OrderDetailsDataSource {
506491
}
507492

508493
private func configureSummary(cell: SummaryTableViewCell) {
509-
cell.title = summaryTitle
510-
cell.dateCreated = summaryDateCreated
494+
let cellViewModel = SummaryTableViewCellViewModel(
495+
order: order,
496+
status: lookUpOrderStatus(for: order)
497+
)
498+
499+
cell.configure(cellViewModel)
500+
511501
cell.onEditTouchUp = { [weak self] in
512502
self?.onCellAction?(.summary, nil)
513503
}
514-
515-
516-
let status = lookUpOrderStatus(for: order)?.status ?? OrderStatusEnum(rawValue: order.statusKey)
517-
let statusName = lookUpOrderStatus(for: order)?.name ?? order.statusKey
518-
let presentation = SummaryTableViewCellPresentation(status: status, statusName: statusName)
519-
520-
cell.display(presentation: presentation)
521504
}
522505
}
523506

WooCommerce/Classes/ViewModels/Order Details/OrderDetailsViewModel.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ final class OrderDetailsViewModel {
3232
return formatter.string(from: order.dateCreated)
3333
}
3434

35-
var summaryTitle: String? {
36-
return dataSource.summaryTitle
37-
}
38-
3935
let productLeftTitle = NSLocalizedString("PRODUCT", comment: "Product section title")
4036

4137
let productRightTitle = NSLocalizedString("QTY", comment: "Quantity abbreviation for section title")

WooCommerce/Classes/ViewRelated/Orders/Cells/OrderTableViewCell.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ final class OrderTableViewCell: UITableViewCell & SearchResultCell {
3939
/// Renders the specified Order ViewModel
4040
///
4141
func configureCell(viewModel: OrderDetailsViewModel, orderStatus: OrderStatus?) {
42-
titleLabel.text = viewModel.summaryTitle
42+
titleLabel.text = title(for: viewModel.order)
4343
totalLabel.text = viewModel.totalFriendlyString
4444
dateCreatedLabel.text = viewModel.formattedDateCreated
4545

@@ -95,7 +95,6 @@ final class OrderTableViewCell: UITableViewCell & SearchResultCell {
9595
// MARK: - Private
9696
//
9797
private extension OrderTableViewCell {
98-
9998
/// Preserves the current Payment BG Color
10099
///
101100
func preserveLabelColors(action: () -> Void) {
@@ -108,6 +107,22 @@ private extension OrderTableViewCell {
108107
paymentStatusLabel.layer.borderColor = borderColor
109108
}
110109

110+
/// For example, #560 Pamela Nguyen
111+
///
112+
func title(for order: Order) -> String {
113+
if let billingAddress = order.billingAddress {
114+
return Localization.title(orderNumber: order.number,
115+
firstName: billingAddress.firstName,
116+
lastName: billingAddress.lastName)
117+
}
118+
119+
return Localization.title(orderNumber: order.number)
120+
}
121+
}
122+
123+
// MARK: - Setup
124+
125+
private extension OrderTableViewCell {
111126
func configureBackground() {
112127
backgroundColor = .listForeground
113128
selectedBackgroundView = UIView()
@@ -126,3 +141,25 @@ private extension OrderTableViewCell {
126141
dateCreatedLabel.applyCaption1Style()
127142
}
128143
}
144+
145+
// MARK: - Constants
146+
147+
private extension OrderTableViewCell {
148+
enum Localization {
149+
static func title(orderNumber: String, firstName: String, lastName: String) -> String {
150+
let format = NSLocalizedString("#%1$@ %2$@ %3$@", comment: "In Order List,"
151+
+ " the pattern to show the order number and the full name. For example, “#123 John Doe”."
152+
+ " The %1$@ is the order number. The %2$@ is the first name. The %3$@ is the last name.")
153+
154+
return String.localizedStringWithFormat(format, orderNumber, firstName, lastName)
155+
}
156+
157+
static func title(orderNumber: String) -> String {
158+
let format = NSLocalizedString("#%@", comment: "In Order List,"
159+
+ " the pattern to show the order number. For example, “#123456”."
160+
+ " The %@ placeholder is the order number.")
161+
162+
return String.localizedStringWithFormat(format, orderNumber)
163+
}
164+
}
165+
}

WooCommerce/Classes/ViewRelated/Orders/Order Details/Order Summary Section/SummaryTableViewCell.swift

Lines changed: 83 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,67 @@ import UIKit
22
import Yosemite
33
import Gridicons
44

5-
struct SummaryTableViewCellPresentation {
6-
let status: OrderStatusEnum
7-
let statusName: String
8-
}
5+
/// The ViewModel for `SummaryTableViewCell`.
6+
///
7+
/// TODO This and that cell class should be renamed to be less ambiguous.
8+
///
9+
struct SummaryTableViewCellViewModel {
10+
fileprivate struct OrderStatusPresentation {
11+
let style: OrderStatusEnum
12+
let title: String
13+
}
14+
15+
private let billingAddress: Address?
16+
private let dateCreated: Date
17+
private let orderNumber: String
18+
19+
fileprivate let presentation: OrderStatusPresentation
20+
21+
private let calendar: Calendar
22+
23+
init(order: Order,
24+
status: OrderStatus?,
25+
calendar: Calendar = .current) {
26+
27+
billingAddress = order.billingAddress
28+
dateCreated = order.dateCreated
29+
orderNumber = order.number
30+
31+
presentation = OrderStatusPresentation(
32+
style: status?.status ?? OrderStatusEnum(rawValue: order.statusKey),
33+
title: status?.name ?? order.statusKey
34+
)
935

36+
self.calendar = calendar
37+
}
38+
39+
/// The full name from the billing address
40+
///
41+
var billedPersonName: String {
42+
if let billingAddress = billingAddress {
43+
return Localization.billedPerson(firstName: billingAddress.firstName,
44+
lastName: billingAddress.lastName)
45+
} else {
46+
return ""
47+
}
48+
}
49+
50+
/// The date and the order number concatenated together. Example, “Jan 22, 2018 • #1587”.
51+
///
52+
/// If the date is today, the time will be returned instead.
53+
///
54+
var subtitle: String {
55+
let formatter: DateFormatter = {
56+
if dateCreated.isSameDay(as: Date(), using: calendar) {
57+
return DateFormatter.timeFormatter
58+
} else {
59+
return DateFormatter.mediumLengthLocalizedDateFormatter
60+
}
61+
}()
62+
63+
return "\(formatter.string(from: dateCreated)) • #\(orderNumber)"
64+
}
65+
}
1066

1167
// MARK: - SummaryTableViewCell
1268
//
@@ -16,9 +72,9 @@ final class SummaryTableViewCell: UITableViewCell {
1672
///
1773
@IBOutlet private weak var titleLabel: UILabel!
1874

19-
/// Label: Creation / Update Date
75+
/// Shows the dateCreated and order number.
2076
///
21-
@IBOutlet private weak var createdLabel: UILabel!
77+
@IBOutlet private weak var subtitleLabel: UILabel!
2278

2379
/// Label: Payment Status
2480
///
@@ -28,37 +84,22 @@ final class SummaryTableViewCell: UITableViewCell {
2884
///
2985
@IBOutlet private var updateStatusButton: UIButton!
3086

31-
/// Title
32-
///
33-
var title: String? {
34-
get {
35-
return titleLabel.text
36-
}
37-
set {
38-
titleLabel.text = newValue
39-
}
40-
}
41-
42-
/// Date
43-
///
44-
var dateCreated: String? {
45-
get {
46-
return createdLabel.text
47-
}
48-
set {
49-
createdLabel.text = newValue
50-
}
51-
}
52-
5387
/// Closure to be executed whenever the edit button is tapped.
5488
///
5589
var onEditTouchUp: (() -> Void)?
5690

91+
func configure(_ viewModel: SummaryTableViewCellViewModel) {
92+
titleLabel.text = viewModel.billedPersonName
93+
subtitleLabel.text = viewModel.subtitle
94+
95+
display(presentation: viewModel.presentation)
96+
}
97+
5798
/// Displays the specified OrderStatus, and applies the right Label Style
5899
///
59-
func display(presentation: SummaryTableViewCellPresentation) {
60-
paymentStatusLabel.applyStyle(for: presentation.status)
61-
paymentStatusLabel.text = presentation.statusName
100+
private func display(presentation: SummaryTableViewCellViewModel.OrderStatusPresentation) {
101+
paymentStatusLabel.applyStyle(for: presentation.style)
102+
paymentStatusLabel.text = presentation.title
62103
}
63104

64105
// MARK: - Overridden Methods
@@ -115,8 +156,8 @@ private extension SummaryTableViewCell {
115156
func configureLabels() {
116157
titleLabel.applyHeadlineStyle()
117158
titleLabel.accessibilityIdentifier = "summary-table-view-cell-title-label"
118-
createdLabel.applyFootnoteStyle()
119-
createdLabel.accessibilityIdentifier = "summary-table-view-cell-created-label"
159+
subtitleLabel.applyFootnoteStyle()
160+
subtitleLabel.accessibilityIdentifier = "summary-table-view-cell-created-label"
120161
paymentStatusLabel.applyPaddedLabelDefaultStyles()
121162
paymentStatusLabel.accessibilityIdentifier = "summary-table-view-cell-payment-status-label"
122163
}
@@ -147,22 +188,16 @@ private extension SummaryTableViewCell {
147188
}
148189
}
149190

191+
/// MARK: - Localization
150192

151-
/// MARK: - Testability
152-
extension SummaryTableViewCell {
153-
func getTitle() -> UILabel {
154-
return titleLabel
155-
}
156-
157-
func getCreatedLabel() -> UILabel {
158-
return createdLabel
159-
}
193+
private extension SummaryTableViewCellViewModel {
194+
enum Localization {
195+
static func billedPerson(firstName: String, lastName: String) -> String {
196+
let format = NSLocalizedString("%1$@ %2$@", comment: "In Order Details,"
197+
+ " the pattern to show the billed person's full name. For example, “John Doe”."
198+
+ " The %1$@ is the first name. The %2$@ is the last name.")
160199

161-
func getStatusLabel() -> UILabel {
162-
return paymentStatusLabel
163-
}
164-
165-
func getEditButton() -> UIButton {
166-
return updateStatusButton
200+
return String.localizedStringWithFormat(format, firstName, lastName)
201+
}
167202
}
168203
}

0 commit comments

Comments
 (0)