Merge branch 'feature/order_tracker' into 'develop'

Order tracker

See merge request BPHV_MIPS/mvm_core_ui!529
This commit is contained in:
Pfeil, Scott Robert 2020-07-15 20:21:31 -04:00
commit fe4a9755de
19 changed files with 519 additions and 42 deletions

View File

@ -62,6 +62,8 @@
01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; }; 01EB369323609801006832FA /* HeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368C23609801006832FA /* HeaderModel.swift */; };
01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; }; 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368D23609801006832FA /* HeadlineBodyModel.swift */; };
01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */; }; 01F2A03223A4498200D954D8 /* CaretLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */; };
0A0B147924ACFD8300BADD56 /* OrderTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A0B147824ACFD8200BADD56 /* OrderTracker.swift */; };
0A0B147B24ACFDAD00BADD56 /* OrderTrackerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A0B147A24ACFDAD00BADD56 /* OrderTrackerModel.swift */; };
0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; };
0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */; }; 0A1B4A96233BB18F005B3FB4 /* CheckboxLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA2232BE63400FB8E22 /* CheckboxLabel.swift */; };
0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB7E235DECC500C160A2 /* EntryField.swift */; }; 0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A21DB7E235DECC500C160A2 /* EntryField.swift */; };
@ -109,6 +111,9 @@
0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; }; 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */; };
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; }; 0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; }; 0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
0AC16CEB24B3A1080085EF34 /* Step.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC16CEA24B3A1080085EF34 /* Step.swift */; };
0AC16CED24B3A11C0085EF34 /* StepModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC16CEC24B3A11C0085EF34 /* StepModel.swift */; };
0AC16CEE24B3A39C0085EF34 /* ImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7918F423F5E7EA00772FF4 /* ImageView.swift */; };
0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; }; 0AE14F64238315D2005417F8 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE14F63238315D2005417F8 /* TextField.swift */; };
0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */; }; 0AE98BAF23FEF956004C5109 /* ExternalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */; };
0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */; }; 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */; };
@ -522,6 +527,8 @@
01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; }; 01EB368C23609801006832FA /* HeaderModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderModel.swift; sourceTree = "<group>"; };
01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = "<group>"; }; 01EB368D23609801006832FA /* HeadlineBodyModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeadlineBodyModel.swift; sourceTree = "<group>"; };
01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = "<group>"; }; 01F2A03123A4498200D954D8 /* CaretLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaretLinkModel.swift; sourceTree = "<group>"; };
0A0B147824ACFD8200BADD56 /* OrderTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTracker.swift; sourceTree = "<group>"; };
0A0B147A24ACFDAD00BADD56 /* OrderTrackerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTrackerModel.swift; sourceTree = "<group>"; };
0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = "<group>"; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = "<group>"; };
0A209CD223A7E2810068F8B0 /* UIStackViewAlignment+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackViewAlignment+Extension.swift"; sourceTree = "<group>"; }; 0A209CD223A7E2810068F8B0 /* UIStackViewAlignment+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIStackViewAlignment+Extension.swift"; sourceTree = "<group>"; };
0A21DB7E235DECC500C160A2 /* EntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; }; 0A21DB7E235DECC500C160A2 /* EntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; };
@ -572,6 +579,8 @@
0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPickerView+Extension.swift"; sourceTree = "<group>"; }; 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIPickerView+Extension.swift"; sourceTree = "<group>"; };
0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; }; 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryField.swift; sourceTree = "<group>"; };
0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; }; 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ItemDropdownEntryField.swift; sourceTree = "<group>"; };
0AC16CEA24B3A1080085EF34 /* Step.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Step.swift; sourceTree = "<group>"; };
0AC16CEC24B3A11C0085EF34 /* StepModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StepModel.swift; sourceTree = "<group>"; };
0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; }; 0AE14F63238315D2005417F8 /* TextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextField.swift; sourceTree = "<group>"; };
0AE98BAE23FEF956004C5109 /* ExternalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLink.swift; sourceTree = "<group>"; }; 0AE98BAE23FEF956004C5109 /* ExternalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLink.swift; sourceTree = "<group>"; };
0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLinkModel.swift; sourceTree = "<group>"; }; 0AE98BB223FF0934004C5109 /* ExternalLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLinkModel.swift; sourceTree = "<group>"; };
@ -1037,6 +1046,17 @@
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
0AC16CE924B3A0ED0085EF34 /* Order Tracker */ = {
isa = PBXGroup;
children = (
0A0B147A24ACFDAD00BADD56 /* OrderTrackerModel.swift */,
0A0B147824ACFD8200BADD56 /* OrderTracker.swift */,
0AC16CEC24B3A11C0085EF34 /* StepModel.swift */,
0AC16CEA24B3A1080085EF34 /* Step.swift */,
);
path = "Order Tracker";
sourceTree = "<group>";
};
0AE98BAD23FEF92B004C5109 /* Link */ = { 0AE98BAD23FEF92B004C5109 /* Link */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1263,10 +1283,11 @@
C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */, C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */,
D2E2A99923D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift */, D2E2A99923D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift */,
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */, 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */,
EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */,
EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */, EA5124FC243601600051A3A4 /* BGImageHeadlineBodyButton.swift */,
0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */, EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */,
0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */, 0A775F2724893937009EFB58 /* ThreeHeadlineBodyLinkModel.swift */,
0A775F2524893916009EFB58 /* ThreeHeadlineBodyLink.swift */,
0AC16CE924B3A0ED0085EF34 /* Order Tracker */,
); );
path = VerticalCombinationViews; path = VerticalCombinationViews;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2127,6 +2148,7 @@
324FB6AA249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift in Sources */, 324FB6AA249366F3002552C7 /* ListLeftVariableNumberedListBodyTextModel.swift in Sources */,
5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */, 5248BFED23F12E350059236A /* ListThreeColumnPlanDataDividerModel.swift in Sources */,
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */, AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */,
0A0B147924ACFD8300BADD56 /* OrderTracker.swift in Sources */,
0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */, 0A5D59C223AD2F5700EFD9E9 /* AppleGuidelinesProtocol.swift in Sources */,
8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */, 8D070BB0241B56530099AC56 /* ListRightVariableTotalDataModel.swift in Sources */,
943784F5236B77BB006A1E82 /* Wheel.swift in Sources */, 943784F5236B77BB006A1E82 /* Wheel.swift in Sources */,
@ -2193,6 +2215,7 @@
9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */, 9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */,
01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */, 01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */,
011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */, 011D95A3240453F8000E3791 /* RuleRegexModel.swift in Sources */,
0A0B147B24ACFDAD00BADD56 /* OrderTrackerModel.swift in Sources */,
D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */, D2E2A98323D8B32D000B42E6 /* EyebrowHeadlineBodyLinkModel.swift in Sources */,
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */,
BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */, BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */,
@ -2361,6 +2384,7 @@
32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */, 32F8804624765C6E00C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinksModel.swift in Sources */,
011D958524042432000E3791 /* RulesProtocol.swift in Sources */, 011D958524042432000E3791 /* RulesProtocol.swift in Sources */,
AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */, AA9972502475309F00FC7472 /* ListLeftVariableIconAllTextLinksModel.swift in Sources */,
0AC16CED24B3A11C0085EF34 /* StepModel.swift in Sources */,
AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */, AA69AAF62445BF5700AF3D3B /* ListLeftVariableCheckboxBodyText.swift in Sources */,
D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */, D264FAA3243E632F00D98315 /* ProgrammaticCollectionViewController.swift in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
@ -2379,9 +2403,11 @@
011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */, 011D95A5240455DC000E3791 /* FormGroupRule.swift in Sources */,
D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */, D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */,
D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */, D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */,
0AC16CEB24B3A1080085EF34 /* Step.swift in Sources */,
C7F8012123E8303200396FBD /* ListRVWheel.swift in Sources */, C7F8012123E8303200396FBD /* ListRVWheel.swift in Sources */,
BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */, BB2C968F24330EA7006FF80C /* ListRightVariableTextLinkAllTextAndLinksModel.swift in Sources */,
D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */, D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */,
0AC16CEE24B3A39C0085EF34 /* ImageView.swift in Sources */,
279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */, 279B1569242BBC2F00921D6C /* ActionModelAdapter.swift in Sources */,
BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */, BB6C6AC0242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTallModel.swift in Sources */,
8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */, 8DEFA95E243DAC2F000D27E5 /* ListThreeColumnDataUsageDivider.swift in Sources */,

View File

@ -38,7 +38,7 @@ import Foundation
public func getMoleculeModelForJSON(_ json: [String: Any]) throws -> MoleculeModelProtocol? { public func getMoleculeModelForJSON(_ json: [String: Any]) throws -> MoleculeModelProtocol? {
guard let moleculeName = json.optionalStringForKey(KeyMoleculeName), guard let moleculeName = json.optionalStringForKey(KeyMoleculeName),
let type = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) else { let type = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) else {
throw ModelRegistry.Error.decoderErrorModelNotMapped() throw ModelRegistry.Error.decoderErrorModelNotMapped()
} }
guard let model = try type.decode(jsonDict: json) as? MoleculeModelProtocol else { guard let model = try type.decode(jsonDict: json) as? MoleculeModelProtocol else {
throw ModelRegistry.Error.decoderError throw ModelRegistry.Error.decoderError
@ -88,8 +88,6 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: Tags.self, viewModelClass: TagsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Tags.self, viewModelClass: TagsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Tag.self, viewModelClass: TagModel.self) MoleculeObjectMapping.shared()?.register(viewClass: Tag.self, viewModelClass: TagModel.self)
// MARK:- Other Atoms // MARK:- Other Atoms
MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ProgressBar.self, viewModelClass: ProgressBarModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self) MoleculeObjectMapping.shared()?.register(viewClass: MultiProgress.self, viewModelClass: MultiProgressBarModel.self)
@ -119,6 +117,8 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyButton.self, viewModelClass: HeadlineBodyButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: HeadlineBodyButton.self, viewModelClass: HeadlineBodyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: BGImageHeadlineBodyButton.self, viewModelClass: BGImageHeadlineBodyButtonModel.self) MoleculeObjectMapping.shared()?.register(viewClass: BGImageHeadlineBodyButton.self, viewModelClass: BGImageHeadlineBodyButtonModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: ThreeHeadlineBodyLink.self, viewModelClass: ThreeHeadlineBodyLinkModel.self) MoleculeObjectMapping.shared()?.register(viewClass: ThreeHeadlineBodyLink.self, viewModelClass: ThreeHeadlineBodyLinkModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: OrderTracker.self, viewModelClass: OrderTrackerModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Step.self, viewModelClass: StepModel.self)
// MARK:- Left Right Molecules // MARK:- Left Right Molecules
MoleculeObjectMapping.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self) MoleculeObjectMapping.shared()?.register(viewClass: CornerLabels.self, viewModelClass: CornerLabelsModel.self)

View File

@ -0,0 +1,133 @@
//
// OrderTracker.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 7/1/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
open class OrderTracker: View {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
var steps = [Step]()
//--------------------------------------------------
// MARK: - Life Cycle
//--------------------------------------------------
open override func setupView() {
super.setupView()
isOpaque = false
}
open override func reset() {
super.reset()
resetSteps()
}
//--------------------------------------------------
// MARK: - Methods
//--------------------------------------------------
func constrain(stepModels: [StepModel]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
resetSteps()
guard let stepModels = stepModels else { return }
var anchor = topAnchor
for stepModel in stepModels {
let step = Step()
step.set(with: stepModel, delegateObject, additionalData)
addSubview(step)
steps.append(step)
step.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
trailingAnchor.constraint(equalTo: step.trailingAnchor).isActive = true
step.topAnchor.constraint(equalTo: anchor).isActive = true
anchor = step.bottomAnchor
}
bottomAnchor.constraint(equalTo: anchor).isActive = true
(subviews.last as? Step)?.heightConstraint?.isActive = false
}
func resetSteps() {
steps.forEach {
$0.reset()
$0.removeFromSuperview()
}
steps = []
}
//--------------------------------------------------
// MARK: - Draw
//--------------------------------------------------
open override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext(),
let firstStep = steps.first
else { return }
context.setLineWidth(1)
let imageDimension = firstStep.stateImage.bounds.height
let halfDimension = imageDimension / 2
let startPoint = CGPoint(x: halfDimension, y: halfDimension)
let defaultGrey: UIColor = .mvmCoolGray3
context.move(to: startPoint)
var lineColor = (firstStep.state?.color() ?? defaultGrey).cgColor
for (i, step) in steps.dropFirst().enumerated() {
if let state = step.state, state == .incomplete {
lineColor = defaultGrey.cgColor
}
context.setStrokeColor(lineColor)
let relativeRect = convert(step.stateImage.frame, from: step.stateImage)
let point = CGPoint(x: halfDimension, y: relativeRect.midY)
context.addLine(to: point)
context.strokePath()
// Break out of loop since we're on the last step.
if i == steps.count - 2 {
break
}
lineColor = (step.state?.color() ?? defaultGrey).cgColor
context.move(to: point)
}
}
//------------------------------------------------------
// MARK: - MoleculeViewProtocol
//------------------------------------------------------
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 196
}
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? OrderTrackerModel else { return }
constrain(stepModels: model.steps, delegateObject: delegateObject, additionalData: additionalData)
setNeedsLayout()
setNeedsDisplay()
}
}

View File

@ -0,0 +1,48 @@
//
// OrderTrackerModel.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 7/1/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
open class OrderTrackerModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var backgroundColor: Color?
public static var identifier: String = "orderTracker"
public var steps: [StepModel]
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case steps
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
steps = try typeContainer.decode([StepModel].self, forKey: .steps)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(steps, forKey: .steps)
}
}

View File

@ -0,0 +1,114 @@
//
// Step.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 7/6/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
open class Step: View {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var headline = Label(fontStyle: .BoldMicro)
public var bodyTop = Label(fontStyle: .RegularMicro)
public var bodyBottom = Label(fontStyle: .RegularMicro)
public var stateImage = ImageView()
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
public var heightConstraint: NSLayoutConstraint?
//--------------------------------------------------
// MARK: - Computed Properties
//--------------------------------------------------
public var stepModel: StepModel? {
return model as? StepModel
}
public var state: StepModel.State? {
return stepModel?.state
}
//--------------------------------------------------
// MARK: - Life Cycle
//--------------------------------------------------
open override func setupView() {
super.setupView()
addSubview(stateImage)
addSubview(headline)
addSubview(bodyTop)
addSubview(bodyBottom)
stateImage.contentMode = .scaleAspectFit
stateImage.layer.backgroundColor = UIColor.white.cgColor
stateImage.topAnchor.constraint(equalTo: topAnchor).isActive = true
stateImage.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
stateImage.heightAnchor.constraint(equalToConstant: 18).isActive = true
stateImage.widthAnchor.constraint(equalToConstant: 18).isActive = true
headline.topAnchor.constraint(equalTo: topAnchor, constant: 2).isActive = true
headline.leadingAnchor.constraint(equalTo: stateImage.trailingAnchor, constant: Padding.Four).isActive = true
trailingAnchor.constraint(equalTo: headline.trailingAnchor).isActive = true
bodyTop.topAnchor.constraint(equalTo: headline.bottomAnchor).isActive = true
bodyTop.leadingAnchor.constraint(equalTo: stateImage.trailingAnchor, constant: Padding.Four).isActive = true
trailingAnchor.constraint(equalTo: bodyTop.trailingAnchor).isActive = true
bodyBottom.topAnchor.constraint(equalTo: bodyTop.bottomAnchor).isActive = true
bodyBottom.leadingAnchor.constraint(equalTo: stateImage.trailingAnchor, constant: Padding.Four).isActive = true
trailingAnchor.constraint(equalTo: bodyBottom.trailingAnchor).isActive = true
let bodyBottomConstraint = bottomAnchor.constraint(greaterThanOrEqualTo: bodyBottom.bottomAnchor)
bodyBottomConstraint.priority = .defaultHigh
bodyBottomConstraint.isActive = true
heightConstraint = heightAnchor.constraint(equalToConstant: 58)
heightConstraint?.priority = .defaultLow
heightConstraint?.isActive = true
}
public override func reset() {
super.reset()
headline.reset()
bodyTop.reset()
bodyBottom.reset()
stateImage.reset()
heightConstraint?.isActive = true
}
//------------------------------------------------------
// MARK: - MoleculeViewProtocol
//------------------------------------------------------
public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 64
}
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? StepModel else { return }
headline.set(with: model.headline, delegateObject, additionalData)
if let bodyTopModel = model.bodyTop {
bodyTop.set(with: bodyTopModel, delegateObject, additionalData)
}
if let bodyBottomModel = model.bodyBottom {
bodyBottom.set(with: bodyBottomModel, delegateObject, additionalData)
}
stateImage.image = model.state?.image()
}
}

View File

@ -0,0 +1,94 @@
//
// StepModel.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 7/6/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import UIKit
open class StepModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public var backgroundColor: Color?
public static var identifier: String = "step"
public var state: State?
public var headline: LabelModel
public var bodyTop: LabelModel?
public var bodyBottom: LabelModel?
//--------------------------------------------------
// MARK: - Enum
//--------------------------------------------------
public enum State: String, Codable {
case complete
case incomplete
case invalid
func image() -> UIImage? {
switch self {
case .complete:
return MVMCoreUIUtility.imageNamed("icon_tracker_complete")
case .incomplete:
return MVMCoreUIUtility.imageNamed("icon_tracker_incomplete")
case .invalid:
return MVMCoreUIUtility.imageNamed("icon_tracker_invalid")
}
}
func color() -> UIColor {
switch self {
case .complete:
return .mvmGreen
case .incomplete, .invalid:
return .mvmCoolGray3
}
}
}
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case state
case headline
case bodyTop
case bodyBottom
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
state = try typeContainer.decodeIfPresent(State.self, forKey: .state)
headline = try typeContainer.decode(LabelModel.self, forKey: .headline)
bodyTop = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bodyTop)
bodyBottom = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bodyBottom)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(headline, forKey: .headline)
try container.encodeIfPresent(bodyTop, forKey: .bodyTop)
try container.encodeIfPresent(bodyBottom, forKey: .bodyBottom)
}
}

View File

@ -8,7 +8,7 @@
import UIKit import UIKit
open class ImageView: UIImageView, ModelMoleculeViewProtocol { open class ImageView: UIImageView, MoleculeViewProtocol {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Properties // MARK: - Properties
//-------------------------------------------------- //--------------------------------------------------
@ -51,13 +51,25 @@ open class ImageView: UIImageView, ModelMoleculeViewProtocol {
} }
} }
/// Will be called only once.
open func setupView() {
translatesAutoresizingMaskIntoConstraints = false
insetsLayoutMarginsFromSafeArea = false
MVMCoreUIUtility.setMarginsFor(self, leading: 0, top: 0, trailing: 0, bottom: 0)
}
open func reset() {
image = nil
backgroundColor = .clear
}
//-------------------------------------------------- //--------------------------------------------------
// MARK: - ModelMoleculeViewProtocol // MARK: - MoleculeViewProtocol
//-------------------------------------------------- //--------------------------------------------------
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
self.model = model self.model = model
if let backgroundColor = model?.backgroundColor { if let backgroundColor = model.backgroundColor {
self.backgroundColor = backgroundColor.uiColor self.backgroundColor = backgroundColor.uiColor
} }
} }
@ -73,27 +85,8 @@ open class ImageView: UIImageView, ModelMoleculeViewProtocol {
open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? { open class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
return nil return nil
} }
}
// MARK:- MVMCoreViewProtocol
extension ImageView: MVMCoreViewProtocol {
open func updateView(_ size: CGFloat) { } open func updateView(_ size: CGFloat) { }
/// Will be called only once.
open func setupView() {
translatesAutoresizingMaskIntoConstraints = false
insetsLayoutMarginsFromSafeArea = false
MVMCoreUIUtility.setMarginsFor(self, leading: 0, top: 0, trailing: 0, bottom: 0)
}
}
// MARK:- MVMCoreUIMoleculeViewProtocol
extension ImageView: MVMCoreUIMoleculeViewProtocol {
open func reset() {
backgroundColor = .clear
}
open func setAsMolecule() { } open func setAsMolecule() { }
} }

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Green.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Green@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Green@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Empty state icon.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Empty state icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Empty state icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Alert icon.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Alert icon@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Alert icon@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}