From 8a2d2c9233a44261e3b8ce76d6f445cd3e565aea Mon Sep 17 00:00:00 2001 From: Damodaram Date: Mon, 21 Dec 2020 17:28:40 +0530 Subject: [PATCH 01/27] changes in access specifier --- MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift b/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift index 717bbc55..080b4e88 100644 --- a/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift +++ b/MVMCoreUI/BaseClasses/UICollectionViewLeftAlignedLayout.swift @@ -9,8 +9,8 @@ import Foundation -class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout { - override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { +public class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout { + public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil } var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]() for attribute in attributes { From 291b0ee9fe2b19d74103ab7192b2ed0cf079e134 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 21 Dec 2020 13:01:03 -0500 Subject: [PATCH 02/27] change to public/open --- MVMCoreUI/Containers/Views/Container.swift | 4 +-- .../Containers/Views/ContainerHelper.swift | 28 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/MVMCoreUI/Containers/Views/Container.swift b/MVMCoreUI/Containers/Views/Container.swift index 7ad02f9d..159535d7 100644 --- a/MVMCoreUI/Containers/Views/Container.swift +++ b/MVMCoreUI/Containers/Views/Container.swift @@ -15,9 +15,9 @@ open class Container: View, ContainerProtocol { //-------------------------------------------------- public var view: UIView? - let containerHelper = ContainerHelper() + public let containerHelper = ContainerHelper() - var containerModel: ContainerModelProtocol? { + public var containerModel: ContainerModelProtocol? { get { return model as? ContainerModelProtocol } } diff --git a/MVMCoreUI/Containers/Views/ContainerHelper.swift b/MVMCoreUI/Containers/Views/ContainerHelper.swift index f60d1ee6..b60bcc1e 100644 --- a/MVMCoreUI/Containers/Views/ContainerHelper.swift +++ b/MVMCoreUI/Containers/Views/ContainerHelper.swift @@ -15,23 +15,23 @@ open class ContainerHelper: NSObject { // MARK: - Constraints //-------------------------------------------------- - var leftConstraint: NSLayoutConstraint? - var topConstraint: NSLayoutConstraint? - var bottomConstraint: NSLayoutConstraint? - var rightConstraint: NSLayoutConstraint? + open var leftConstraint: NSLayoutConstraint? + open var topConstraint: NSLayoutConstraint? + open var bottomConstraint: NSLayoutConstraint? + open var rightConstraint: NSLayoutConstraint? - var alignCenterHorizontalConstraint: NSLayoutConstraint? - var alignCenterLeftConstraint: NSLayoutConstraint? - var alignCenterRightConstraint: NSLayoutConstraint? + open var alignCenterHorizontalConstraint: NSLayoutConstraint? + open var alignCenterLeftConstraint: NSLayoutConstraint? + open var alignCenterRightConstraint: NSLayoutConstraint? - var alignCenterVerticalConstraint: NSLayoutConstraint? - var alignCenterTopConstraint: NSLayoutConstraint? - var alignCenterBottomConstraint: NSLayoutConstraint? + open var alignCenterVerticalConstraint: NSLayoutConstraint? + open var alignCenterTopConstraint: NSLayoutConstraint? + open var alignCenterBottomConstraint: NSLayoutConstraint? - var leftLowConstraint: NSLayoutConstraint? - var topLowConstraint: NSLayoutConstraint? - var bottomLowConstraint: NSLayoutConstraint? - var rightLowConstraint: NSLayoutConstraint? + open var leftLowConstraint: NSLayoutConstraint? + open var topLowConstraint: NSLayoutConstraint? + open var bottomLowConstraint: NSLayoutConstraint? + open var rightLowConstraint: NSLayoutConstraint? //-------------------------------------------------- // MARK: - Methods From db424ce04a45d2d6bcf499d360536e8270cea920 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 22 Dec 2020 16:35:21 -0500 Subject: [PATCH 03/27] field errors start --- .../Templates/MoleculeListTemplate.swift | 46 +++++++--- .../BaseControllers/ViewController.swift | 92 +++++++++---------- .../FormUIHelpers/FormFieldProtocol.swift | 5 +- 3 files changed, 79 insertions(+), 64 deletions(-) diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 4b6b565e..e23d2ccd 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -19,7 +19,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol var observer: NSKeyValueObservation? public var templateModel: ListPageTemplateModel? - + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -41,7 +41,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- - + open override func parsePageJSON() throws { try parseTemplate(json: loadObject?.pageJSON) try super.parsePageJSON() @@ -54,8 +54,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol open override func viewForTop() -> UIView { guard let headerModel = templateModel?.header, - let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar) - else { return super.viewForTop() } + let molecule = MoleculeObjectMapping.shared()?.createMolecule(headerModel, delegateObject: delegateObjectIVar) + else { return super.viewForTop() } // Temporary, Default the horizontal padding if var container = templateModel?.header as? ContainerModelProtocol, container.useHorizontalMargins == nil { @@ -67,8 +67,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol override open func viewForBottom() -> UIView { guard let footerModel = templateModel?.footer, - let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar) - else { return super.viewForBottom() } + let molecule = MoleculeObjectMapping.shared()?.createMolecule(footerModel, delegateObject: delegateObjectIVar) + else { return super.viewForBottom() } return molecule } @@ -86,7 +86,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol //Handle scroll handleScrollToSpecificRow() } - + //-------------------------------------------------- // MARK: - Handle scroll to spefic row @@ -117,12 +117,12 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol open func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { guard let moleculeInfo = getMoleculeInfo(for: indexPath), - let estimatedHeight = (moleculeInfo.class as? MoleculeViewProtocol.Type)?.estimatedHeight(with: moleculeInfo.molecule, delegateObject() as? MVMCoreUIDelegateObject) - else { return 0 } + let estimatedHeight = (moleculeInfo.class as? MoleculeViewProtocol.Type)?.estimatedHeight(with: moleculeInfo.molecule, delegateObject() as? MVMCoreUIDelegateObject) + else { return 0 } return estimatedHeight } - + open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return moleculesInfo?.count ?? 0 } @@ -130,8 +130,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let moleculeInfo = getMoleculeInfo(for: indexPath), - let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) - else { return UITableViewCell() } + let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) + else { return UITableViewCell() } (cell as? MoleculeViewProtocol)?.reset() (cell as? MoleculeListCellProtocol)?.setLines(with: templateModel?.line, delegateObject: delegateObjectIVar, additionalData: nil, indexPath: indexPath) @@ -156,6 +156,24 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol // MARK: - MoleculeDelegateProtocol //-------------------------------------------------- + public override func handleFieldErrors(_ fieldErrors: [Any]?, loadObject: MVMCoreLoadObject) { + super.handleFieldErrors(fieldErrors, loadObject: loadObject) + + for case let fieldError as [AnyHashable: Any] in fieldErrors ?? [] { + + guard let fieldKey = fieldError["fieldKey"] as? String, + let userError = fieldError["userMessage"] as? String, + let entryFieldModel = formValidator?.fields[fieldKey] as? EntryFieldModel + else { continue } + + entryFieldModel.errorMessage = userError + + DispatchQueue.main.async { + let c = self.tableView.cellForRow(at: IndexPath(row: 0, section: 0))?.layoutSubviews() + } + } + } + open override func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { if let tableView = tableView { @@ -222,8 +240,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol func createMoleculeInfo(with listItem: MoleculeModelProtocol?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { guard let listItem = listItem, - let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(listItem) - else { return nil } + let moleculeClass = MoleculeObjectMapping.shared()?.getMoleculeClass(listItem) + else { return nil } let moleculeName = moleculeClass.nameForReuse(with: listItem, delegateObject() as? MVMCoreUIDelegateObject) ?? listItem.moleculeName diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 33c47344..5fc57de7 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -18,12 +18,8 @@ import UIKit @objc public var loadObject: MVMCoreLoadObject? public var model: MVMControllerModelProtocol? public var pageModel: PageModelProtocol? { - get { - return model - } - set { - model = newValue as? MVMControllerModelProtocol - } + get { model } + set { model = newValue as? MVMControllerModelProtocol } } /// Set if this page is containted in a manager. @@ -31,12 +27,10 @@ import UIKit /// A temporary iVar backer for delegateObject() until we change the protocol public lazy var delegateObjectIVar: MVMCoreUIDelegateObject = { - return MVMCoreUIDelegateObject.create(withDelegateForAll: self) + MVMCoreUIDelegateObject.create(withDelegateForAll: self) }() - public func delegateObject() -> DelegateObject? { - return delegateObjectIVar - } + public func delegateObject() -> DelegateObject? { delegateObjectIVar } public var formValidator: FormValidator? @@ -52,7 +46,7 @@ import UIKit /// Checks if the screen width has changed open func screenSizeChanged() -> Bool { - return !MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1) + !MVMCoreGetterUtility.cgfequalwiththreshold(previousScreenSize.width, view.bounds.size.width, 0.1) } //-------------------------------------------------- @@ -61,8 +55,8 @@ import UIKit open func observeForResponseJSONUpdates() { guard !observingForResponses, - (pagesToListenFor()?.count ?? 0 > 0 || modulesToListenFor()?.count ?? 0 > 0) - else { return } + (pagesToListenFor()?.count ?? 0 > 0 || modulesToListenFor()?.count ?? 0 > 0) + else { return } observingForResponses = true NotificationCenter.default.addObserver(self, selector: #selector(responseJSONUpdated(notification:)), name: NSNotification.Name(rawValue: NotificationResponseLoaded), object: nil) @@ -80,28 +74,28 @@ import UIKit } open func modulesToListenFor() -> [String]? { - return loadObject?.requestParameters?.modules as? [String] + loadObject?.requestParameters?.modules as? [String] } @objc open func responseJSONUpdated(notification: Notification) { // Checks for a page we are listening for. var newData = false if let pagesLoaded = notification.userInfo?.optionalDictionaryForKey(KeyPageMap), - let pageType = pagesToListenFor()?.first(where: { (pageTypeListened) -> Bool in - guard let page = pagesLoaded.optionalDictionaryForKey(pageTypeListened), - let pageType = page.optionalStringForKey(KeyPageType), - pageType == pageTypeListened - else { return false } - - return true - }) { + let pageType = pagesToListenFor()?.first(where: { (pageTypeListened) -> Bool in + guard let page = pagesLoaded.optionalDictionaryForKey(pageTypeListened), + let pageType = page.optionalStringForKey(KeyPageType), + pageType == pageTypeListened + else { return false } + + return true + }) { newData = true loadObject?.pageJSON = pagesLoaded.optionalDictionaryForKey(pageType) } // Checks for modules we are listening for. if let modulesLoaded = notification.userInfo?.optionalDictionaryForKey(KeyModuleMap), - let modulesListened = modulesToListenFor() { + let modulesListened = modulesToListenFor() { for moduleName in modulesListened { if let module = modulesLoaded.optionalDictionaryForKey(moduleName) { newData = true @@ -196,9 +190,9 @@ import UIKit open class func verifyRequiredModulesLoaded(for loadObject: MVMCoreLoadObject?, error: AutoreleasingUnsafeMutablePointer) -> Bool { guard let pageType = loadObject?.pageType, - var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType), - !modulesRequired.isEmpty - else { return true } + var modulesRequired = MVMCoreUIViewControllerMappingObject.shared()?.modulesRequired(forPageType: pageType), + !modulesRequired.isEmpty + else { return true } guard let loadedModules = loadObject?.modulesJSON else { return false } @@ -263,8 +257,8 @@ import UIKit /// Sets the navigation item for this view controller. open func setNavigationItem() { guard let navigationItemModel = getNavigationModel(), - let navigationController = navigationController - else { return } + let navigationController = navigationController + else { return } // Utilize helper function to set the navigation item state. NavigationController.setNavigationItem(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: self) @@ -273,9 +267,9 @@ import UIKit /// Sets the appearance of the navigation bar based on the model. open func setNavigationBar() { guard let navigationItemModel = getNavigationModel(), - let navigationController = navigationController else { - MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate() - return + let navigationController = navigationController else { + MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate() + return } // Utilize helper function to set the split view and navigation item state. @@ -405,7 +399,7 @@ import UIKit } open override var supportedInterfaceOrientations: UIInterfaceOrientationMask { - return MVMCoreGetterUtility.isOnIPad() ? UIInterfaceOrientationMask.all : UIInterfaceOrientationMask.portrait + MVMCoreGetterUtility.isOnIPad() ? UIInterfaceOrientationMask.all : UIInterfaceOrientationMask.portrait } open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -424,6 +418,7 @@ import UIKit open func viewControllerReady(inManager manager: UIViewController & MVMCoreViewManagerProtocol) { pageShown() } + //-------------------------------------------------- // MARK: - MVMCoreLoadDelegateProtocol //-------------------------------------------------- @@ -435,15 +430,18 @@ import UIKit // Open the support panel if error == nil, - loadObject?.requestParameters?.openSupportPanel ?? (loadObject?.systemParametersJSON?.boolForKey(KeyOpenSupport) ?? false) == true { + loadObject?.requestParameters?.openSupportPanel ?? (loadObject?.systemParametersJSON?.boolForKey(KeyOpenSupport) ?? false) == true { MVMCoreUISession.sharedGlobal()?.splitViewController?.showRightPanel(animated: true) } } - + /// Override this method to avoid adding form params. open func addFormParams(_ requestParameters: MVMCoreRequestParameters) { formValidator?.addFormParams(requestParameters: requestParameters) } + + public func handleFieldErrors(_ fieldErrors: [Any]?, loadObject: MVMCoreLoadObject) { } + //-------------------------------------------------- // MARK: - MVMCoreActionDelegateProtocol //-------------------------------------------------- @@ -469,9 +467,9 @@ import UIKit open func getModuleWithName(_ moleculeName: String) -> MoleculeModelProtocol? { guard let moduleJSON = loadObject?.modulesJSON?.optionalDictionaryForKey(moleculeName), - let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), - let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) - else { return nil } + let moleculeName = moduleJSON.optionalStringForKey("moleculeName"), + let modelType = ModelRegistry.getType(for: moleculeName, with: MoleculeModelProtocol.self) + else { return nil } do { return try modelType.decode(jsonDict: moduleJSON) as? MoleculeModelProtocol @@ -483,8 +481,8 @@ import UIKit } // Needed otherwise when subclassed, the extension gets called. - open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) {} - open func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? { return nil } + open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { } + open func getIndexPath(for molecule: ListItemModelProtocol & MoleculeModelProtocol) -> IndexPath? { nil } open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], indexPath: IndexPath, animation: UITableView.RowAnimation) { } open func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], animation: UITableView.RowAnimation) { } @@ -514,13 +512,13 @@ import UIKit } open func showRightPanelForScreenBeforeLaunchApp() -> Bool { - return loadObject?.pageJSON?.lenientBoolForKey("showRightPanel") ?? false + loadObject?.pageJSON?.lenientBoolForKey("showRightPanel") ?? false } // TODO: make molecular open func isOverridingRightButton() -> Bool { guard let rightPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("rightPanelButtonLink") - else { return false } + else { return false } MVMCoreActionHandler.shared()?.handleAction(with: rightPanelLink, additionalData: nil, delegateObject: delegateObject()) return true } @@ -528,7 +526,7 @@ import UIKit // TODO: make molecular open func isOverridingLeftButton() -> Bool { guard let leftPanelLink = loadObject?.pageJSON?.optionalDictionaryForKey("leftPanelButtonLink") - else { return false } + else { return false } MVMCoreActionHandler.shared()?.handleAction(with: leftPanelLink, additionalData: nil, delegateObject: delegateObject()) return true } @@ -536,8 +534,8 @@ import UIKit // Eventually will be moved to Model open func bottomProgress() -> Float? { guard let progressString = loadObject?.pageJSON?.optionalStringForKey(KeyProgressPercent), - let progress = Float(progressString) - else { return nil } + let progress = Float(progressString) + else { return nil } return progress / Float(100) } @@ -558,8 +556,8 @@ import UIKit // TODO: Make this into a protocol if UIAccessibility.isVoiceOverRunning { if let toolBar = textField.inputAccessoryView as? UIToolbar, - let _ = toolBar.items?.last, - let pickerView = textField.inputView as? UIPickerView { + let _ = toolBar.items?.last, + let pickerView = textField.inputView as? UIPickerView { view.accessibilityElements = [pickerView, toolBar] } @@ -610,6 +608,6 @@ import UIKit //-------------------------------------------------- func executeBehaviors(_ behaviorBlock:(_ behavior:T)->Void) { - model?.behaviors?.compactMap({ $0 as? T }).forEach { behaviorBlock($0) } + model?.behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } } } diff --git a/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift b/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift index b9d2defe..f769e040 100644 --- a/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift +++ b/MVMCoreUI/FormUIHelpers/FormFieldProtocol.swift @@ -22,7 +22,6 @@ public protocol FormFieldProtocol: FormItemProtocol { } extension FormFieldProtocol { - var baseValue: AnyHashable? { - return nil - } + + var baseValue: AnyHashable? { nil } } From f040331b2c08a6d75b5d7138504c4d7ffa0ea107 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Tue, 22 Dec 2020 16:56:02 -0500 Subject: [PATCH 04/27] kind of working --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 2 ++ MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 65b13861..3efae2ac 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -325,6 +325,8 @@ import UIKit model.wasInitiallySelected = true self.isSelected = true } + + showError = model.isValid! } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index e23d2ccd..d5fa9100 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -167,9 +167,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol else { continue } entryFieldModel.errorMessage = userError + entryFieldModel.isValid = true + entryFieldModel.text = "" - DispatchQueue.main.async { - let c = self.tableView.cellForRow(at: IndexPath(row: 0, section: 0))?.layoutSubviews() + DispatchQueue.main.async { [self] in + tableView.reloadData() } } } From 57a3b92bb57e1dcb197fa3a49056aabee8a996a7 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 23 Dec 2020 09:59:38 -0500 Subject: [PATCH 05/27] dynamic --- .../Atoms/FormFields/TextFields/EntryField.swift | 10 ++++++++-- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 2 ++ MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 3efae2ac..195fa0b9 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -71,13 +71,17 @@ import UIKit public var showError: Bool { get { return entryFieldContainer.showError } set (error) { - self.feedback = error ? entryFieldModel?.errorMessage : entryFieldModel?.feedback + self.feedback = error ? errorMessage : entryFieldModel?.feedback self.feedbackLabel.textColor = error ? entryFieldModel?.errorTextColor?.uiColor ?? .mvmBlack : .mvmBlack self.entryFieldContainer.showError = error self.entryFieldModel?.showError = error } } + var errorMessage: String { + (entryFieldModel?.dynamicErrorMessage != nil ? entryFieldModel?.dynamicErrorMessage : entryFieldModel?.errorMessage) ?? "" + } + /// Toggles original or locked UI. public var isLocked: Bool { get { return entryFieldContainer.isLocked } @@ -326,7 +330,9 @@ import UIKit self.isSelected = true } - showError = model.isValid! + if model.dynamicErrorMessage != nil { + showError = model.isValid! + } } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index d64f70ae..e5b58733 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -21,6 +21,7 @@ import Foundation public var backgroundColor: Color? public var title: String? public var feedback: String? + public var dynamicErrorMessage: String? public var errorMessage: String? public var errorTextColor: Color? public var enabled: Bool = true @@ -67,6 +68,7 @@ import Foundation //-------------------------------------------------- public func formFieldValue() -> AnyHashable? { + dynamicErrorMessage = nil return text } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index d5fa9100..5884c763 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -166,7 +166,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol let entryFieldModel = formValidator?.fields[fieldKey] as? EntryFieldModel else { continue } - entryFieldModel.errorMessage = userError + entryFieldModel.dynamicErrorMessage = userError entryFieldModel.isValid = true entryFieldModel.text = "" From b84aeac3c1353d3d86b4e0f03ebe5b72fd18e492 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 23 Dec 2020 10:29:26 -0500 Subject: [PATCH 06/27] moved up a level --- .../Atomic/Templates/MoleculeListTemplate.swift | 16 ++-------------- MVMCoreUI/BaseControllers/ViewController.swift | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 5884c763..41117af4 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -159,20 +159,8 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol public override func handleFieldErrors(_ fieldErrors: [Any]?, loadObject: MVMCoreLoadObject) { super.handleFieldErrors(fieldErrors, loadObject: loadObject) - for case let fieldError as [AnyHashable: Any] in fieldErrors ?? [] { - - guard let fieldKey = fieldError["fieldKey"] as? String, - let userError = fieldError["userMessage"] as? String, - let entryFieldModel = formValidator?.fields[fieldKey] as? EntryFieldModel - else { continue } - - entryFieldModel.dynamicErrorMessage = userError - entryFieldModel.isValid = true - entryFieldModel.text = "" - - DispatchQueue.main.async { [self] in - tableView.reloadData() - } + DispatchQueue.main.async { [self] in + tableView.reloadData() } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 5fc57de7..b309e370 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -440,7 +440,20 @@ import UIKit formValidator?.addFormParams(requestParameters: requestParameters) } - public func handleFieldErrors(_ fieldErrors: [Any]?, loadObject: MVMCoreLoadObject) { } + public func handleFieldErrors(_ fieldErrors: [Any]?, loadObject: MVMCoreLoadObject) { + + for case let fieldError as [AnyHashable: Any] in fieldErrors ?? [] { + + guard let fieldKey = fieldError["fieldKey"] as? String, + let userError = fieldError["userMessage"] as? String, + let entryFieldModel = formValidator?.fields[fieldKey] as? EntryFieldModel + else { continue } + + entryFieldModel.dynamicErrorMessage = userError + entryFieldModel.isValid = true + entryFieldModel.text = "" + } + } //-------------------------------------------------- // MARK: - MVMCoreActionDelegateProtocol From 1e4963f58e1f6c1cf2d15e6b52f37a1ad44675ce Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 23 Dec 2020 12:20:38 -0500 Subject: [PATCH 07/27] updates --- MVMCoreUI.xcodeproj/project.pbxproj | 4 +++ .../FormFields/TextFields/EntryField.swift | 5 +-- .../TextFields/EntryFieldModel.swift | 4 +++ .../Atomic/Extensions/UIView+Extension.swift | 35 +++++++++++++++++++ .../Templates/MoleculeListTemplate.swift | 8 ----- .../BaseControllers/ViewController.swift | 6 ++++ 6 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 MVMCoreUI/Atomic/Extensions/UIView+Extension.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 3fce1455..a9c1a769 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -98,6 +98,7 @@ 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */; }; + 0A9394892593AC9D00D2791F /* UIView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9394882593AC9D00D2791F /* UIView+Extension.swift */; }; 0A9D091D2433796500D2E6C0 /* BarsCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */; }; 0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */; }; 0A9D091F2433796500D2E6C0 /* NumericIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */; }; @@ -641,6 +642,7 @@ 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsIgnoreCaseModel.swift; sourceTree = ""; }; + 0A9394882593AC9D00D2791F /* UIView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extension.swift"; sourceTree = ""; }; 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BarsCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericIndicatorView.swift; sourceTree = ""; }; @@ -1386,6 +1388,7 @@ 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */, D2ED27E6254B0CE600A1C293 /* UIAlertActionStyle+Codable.swift */, D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */, + 0A9394882593AC9D00D2791F /* UIView+Extension.swift */, ); path = Extensions; sourceTree = ""; @@ -2798,6 +2801,7 @@ 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */, 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */, D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */, + 0A9394892593AC9D00D2791F /* UIView+Extension.swift in Sources */, 0A51F3E32475CB73002E08B6 /* LoadingSpinner.swift in Sources */, BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 195fa0b9..3c990eef 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -78,8 +78,8 @@ import UIKit } } - var errorMessage: String { - (entryFieldModel?.dynamicErrorMessage != nil ? entryFieldModel?.dynamicErrorMessage : entryFieldModel?.errorMessage) ?? "" + var errorMessage: String? { + entryFieldModel?.dynamicErrorMessage ?? entryFieldModel?.errorMessage } /// Toggles original or locked UI. @@ -320,6 +320,7 @@ import UIKit feedback = model.feedback isEnabled = model.enabled entryFieldContainer.disableAllBorders = model.hideBorders + accessibilityIdentifier = model.accessibilityIdentifier ?? model.fieldKey if let isLocked = model.locked { self.isLocked = isLocked diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index e5b58733..02affc3d 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -19,6 +19,7 @@ import Foundation } public var backgroundColor: Color? + public var accessibilityIdentifier: String? public var title: String? public var feedback: String? public var dynamicErrorMessage: String? @@ -49,6 +50,7 @@ import Foundation private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor + case accessibilityIdentifier case title case enabled case feedback @@ -98,6 +100,7 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) + accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decodeIfPresent(String.self, forKey: .title) feedback = try typeContainer.decodeIfPresent(String.self, forKey: .feedback) errorMessage = try typeContainer.decodeIfPresent(String.self, forKey: .errorMessage) @@ -119,6 +122,7 @@ import Foundation var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encodeIfPresent(title, forKey: .title) try container.encodeIfPresent(feedback, forKey: .feedback) try container.encodeIfPresent(text, forKey: .text) diff --git a/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift new file mode 100644 index 00000000..3878b64a --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift @@ -0,0 +1,35 @@ +// +// UIView+Extension.swift +// MVMCoreUI +// +// Created by Kevin Christiano on 12/23/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + + +extension UIView { + + public class func findByAccessibility(identifier: String) -> UIView? { + + guard let window = UIApplication.shared.keyWindow else { return nil } + + func findByID(view: UIView, _ id: String) -> UIView? { + + if view.accessibilityIdentifier == id { + return view + } + + for v in view.subviews { + if let a = findByID(view: v, id) { + return a + } + } + + return nil + } + + return findByID(view: window, identifier) + } +} diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index 41117af4..ba057444 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -156,14 +156,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol // MARK: - MoleculeDelegateProtocol //-------------------------------------------------- - public override func handleFieldErrors(_ fieldErrors: [Any]?, loadObject: MVMCoreLoadObject) { - super.handleFieldErrors(fieldErrors, loadObject: loadObject) - - DispatchQueue.main.async { [self] in - tableView.reloadData() - } - } - open override func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { if let tableView = tableView { diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index b309e370..fa9a1232 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -452,6 +452,12 @@ import UIKit entryFieldModel.dynamicErrorMessage = userError entryFieldModel.isValid = true entryFieldModel.text = "" + + if let view = UIView.findByAccessibility(identifier: fieldKey), let moleculeView = view as? MoleculeViewProtocol { + DispatchQueue.main.async { [self] in + moleculeView.set(with: entryFieldModel, delegateObjectIVar, nil) + } + } } } From 5b42466c7c130588c153101cebf73ed212a54de3 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 23 Dec 2020 12:40:21 -0500 Subject: [PATCH 08/27] adjustments --- MVMCoreUI/Atomic/Extensions/UIView+Extension.swift | 12 ++++-------- MVMCoreUI/BaseControllers/ViewController.swift | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift index 3878b64a..5f4a9aa2 100644 --- a/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift +++ b/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift @@ -15,21 +15,17 @@ extension UIView { guard let window = UIApplication.shared.keyWindow else { return nil } - func findByID(view: UIView, _ id: String) -> UIView? { + func find(view: UIView, by id: String) -> UIView? { - if view.accessibilityIdentifier == id { - return view - } + if view.accessibilityIdentifier == id { return view } for v in view.subviews { - if let a = findByID(view: v, id) { - return a - } + if let aView = find(view: v, by: id) { return aView } } return nil } - return findByID(view: window, identifier) + return find(view: window, by: identifier) } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index fa9a1232..fadc02a3 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -453,8 +453,8 @@ import UIKit entryFieldModel.isValid = true entryFieldModel.text = "" - if let view = UIView.findByAccessibility(identifier: fieldKey), let moleculeView = view as? MoleculeViewProtocol { - DispatchQueue.main.async { [self] in + DispatchQueue.main.async { [self] in + if let view = UIView.findByAccessibility(identifier: fieldKey), let moleculeView = view as? MoleculeViewProtocol { moleculeView.set(with: entryFieldModel, delegateObjectIVar, nil) } } From ea49af01d645c177f3757f16d8dde7eaec8649cf Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 23 Dec 2020 15:58:43 -0500 Subject: [PATCH 09/27] alterations --- MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift | 3 ++- MVMCoreUI/BaseControllers/ViewController.swift | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 3c990eef..6bbef151 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -310,6 +310,7 @@ import UIKit if self.isSelected { self.updateValidation(model.isValid ?? true) + } else if model.isValid ?? true && self.showError { self.showError = false } @@ -332,7 +333,7 @@ import UIKit } if model.dynamicErrorMessage != nil { - showError = model.isValid! + showError = !(model.isValid ?? true) } } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index fadc02a3..700746b7 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -450,7 +450,7 @@ import UIKit else { continue } entryFieldModel.dynamicErrorMessage = userError - entryFieldModel.isValid = true + entryFieldModel.isValid = false entryFieldModel.text = "" DispatchQueue.main.async { [self] in From 5e7533a95cc24b984678782840ccde8035987145 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 28 Dec 2020 11:39:01 -0500 Subject: [PATCH 10/27] molecular top notification action --- .../Atomic/Actions/ActionTopAlertModel.swift | 9 ++- .../OtherHandlers/MVMCoreUIActionHandler.m | 58 +++++++++++++------ .../MVMCoreUITopAlertView+Extension.swift | 6 ++ 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift index 62e496c2..1e93d98f 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift @@ -12,7 +12,8 @@ import Foundation public static var identifier: String = "topAlert" public var actionType: String = ActionTopAlertModel.identifier - public var pageType: String + public var pageType: String? + public var topNotification: TopNotificationModel? public var extraParameters: JSONValueDictionary? public var analyticsData: JSONValueDictionary? @@ -21,4 +22,10 @@ import Foundation self.extraParameters = extraParameters self.analyticsData = analyticsData } + + public init(topNotification: TopNotificationModel, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) { + self.topNotification = topNotification + self.extraParameters = extraParameters + self.analyticsData = analyticsData + } } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m index 14888ed1..5ca372cd 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m @@ -81,18 +81,28 @@ - (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { // Perform a top alert. - NSString *pageTypeForTopAlert = [actionInformation stringForKey:KeyPageType]; - [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { - - NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; - if (responseInfo) { - MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData delegateObject:delegateObject]; - if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { - [((id )delegateObject.actionDelegate) willShowTopAlertWithAlertObject:alertObject alertJson:actionInformation]; + NSString *pageTypeForTopAlert = [actionInformation string:KeyPageType]; + if (pageTypeForTopAlert) { + [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { + + NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; + if (responseInfo) { + MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData delegateObject:delegateObject]; + if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { + [((id )delegateObject.actionDelegate) willShowTopAlertWithAlertObject:alertObject alertJson:actionInformation]; + } + [alertObject showAlert]; } - [alertObject showAlert]; + }]; + } else { + NSDictionary *topNotification = [actionInformation dict:@"topNotification"]; + if (topNotification) { + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:topNotification]; + } else { + MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeTopAlert]]; + [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; } - }]; + } } - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { @@ -152,17 +162,27 @@ - (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { // Perform a top alert. NSString *pageTypeForTopAlert = [actionInformation stringForKey:KeyPageType]; - [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { - - NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; - if (responseInfo) { - MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData actionDelegate:delegate]; - if ([delegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { - alertObject = [((id )delegate) willShowTopAlertWithAlertObject:alertObject alertJson:jsonDictionary]; + if (pageTypeForTopAlert) { + [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { + + NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; + if (responseInfo) { + MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData actionDelegate:delegate]; + if ([delegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { + alertObject = [((id )delegate) willShowTopAlertWithAlertObject:alertObject alertJson:jsonDictionary]; + } + [alertObject showAlert]; } - [alertObject showAlert]; + }]; + } else { + NSDictionary *topNotification = [actionInformation dict:@"topNotification"]; + if (topNotification) { + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:topNotification]; + } else { + MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegate class]),KeyActionTypeTopAlert]]; + [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegate:delegate]; } - }]; + } } - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift index f179fb11..107a3596 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertView+Extension.swift @@ -61,6 +61,12 @@ public extension MVMCoreUITopAlertView { MVMCoreAlertHandler.shared()?.add(operation) } + /// Shows the top alert with the json. + @objc func showTopAlert(with json: [AnyHashable: Any]) { + guard let model = decodeTopNotification(with: json, delegateObject: getDelegateObject()) else { return } + showTopAlert(with: model) + } + /// Checks for existing top alert object of same type and updates it. Only happens for molecular top alerts. Returns true if we updated. private func checkAndUpdateExisting(with topAlertObject: MVMCoreTopAlertObject) -> Bool { guard let queue = MVMCoreAlertHandler.shared()?.topAlertQueue.operations else { return false } From b520866bf48dc5216692140140171366e842d97e Mon Sep 17 00:00:00 2001 From: Damodaram Date: Tue, 29 Dec 2020 20:03:37 +0530 Subject: [PATCH 11/27] updated access specifier --- MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift | 6 +++--- .../Molecules/Items/MoleculeCollectionItemModel.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift index 1b9ce0dc..be67bfca 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift @@ -9,12 +9,12 @@ import Foundation -@objcMembers public class CarouselItemModel: MoleculeCollectionItemModel, CarouselItemModelProtocol { +@objcMembers open class CarouselItemModel: MoleculeCollectionItemModel, CarouselItemModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public override class var identifier: String { + open override class var identifier: String { return "carouselItem" } @@ -44,7 +44,7 @@ import Foundation try super.init(from: decoder) } - public override func encode(to encoder: Encoder) throws { + open override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(peakingUI, forKey: .peakingUI) diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift index 645d16b1..f9df766f 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift @@ -9,7 +9,7 @@ import Foundation /// A model for a collection item that is a container for any molecule. -@objcMembers public class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol { +@objcMembers open class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol { open override class var identifier: String { return "collectionItem" } From d75e423b0639a7afbef6ae146432f1eee1de0030 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 30 Dec 2020 21:29:11 -0500 Subject: [PATCH 12/27] fieldName --- MVMCoreUI/BaseControllers/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 700746b7..2071673d 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -444,7 +444,7 @@ import UIKit for case let fieldError as [AnyHashable: Any] in fieldErrors ?? [] { - guard let fieldKey = fieldError["fieldKey"] as? String, + guard let fieldKey = fieldError["fieldName"] as? String, let userError = fieldError["userMessage"] as? String, let entryFieldModel = formValidator?.fields[fieldKey] as? EntryFieldModel else { continue } From 87e02c37b75999a7ffd7a6fd306f0400b3d95979 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Thu, 31 Dec 2020 14:44:01 +0530 Subject: [PATCH 13/27] top notification action implementation --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++++ .../Atomic/Actions/ActionTopAlertModel.swift | 7 ------ .../Actions/ActionTopNotificationModel.swift | 24 +++++++++++++++++++ MVMCoreUI/Atomic/MoleculeObjectMapping.swift | 1 + .../OtherHandlers/MVMCoreUIActionHandler.h | 3 +++ .../OtherHandlers/MVMCoreUIActionHandler.m | 11 +++++++++ MVMCoreUI/Utility/MVMCoreUIConstants.h | 1 + MVMCoreUI/Utility/MVMCoreUIConstants.m | 1 + 8 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 3fce1455..2dc86525 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -290,6 +290,7 @@ BBC0C4FF24811DCA0087C44F /* TagModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBC0C4FE24811DCA0087C44F /* TagModel.swift */; }; C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; }; C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; }; + C6687441259D92D400F32D13 /* ActionTopNotificationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6687440259D92D400F32D13 /* ActionTopNotificationModel.swift */; }; C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */; }; C695A68123C9830D00BFB94E /* NumberedListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A68023C9830D00BFB94E /* NumberedListModel.swift */; }; C695A69423C9909000BFB94E /* DoughnutChartModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C695A69323C9909000BFB94E /* DoughnutChartModel.swift */; }; @@ -833,6 +834,7 @@ BBC0C4FE24811DCA0087C44F /* TagModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagModel.swift; sourceTree = ""; }; C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = ""; }; + C6687440259D92D400F32D13 /* ActionTopNotificationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionTopNotificationModel.swift; sourceTree = ""; }; C695A67E23C9830600BFB94E /* UnOrderedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnOrderedListModel.swift; sourceTree = ""; }; C695A68023C9830D00BFB94E /* NumberedListModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumberedListModel.swift; sourceTree = ""; }; C695A69323C9909000BFB94E /* DoughnutChartModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DoughnutChartModel.swift; sourceTree = ""; }; @@ -1308,6 +1310,7 @@ D2ED27E9254B0CE600A1C293 /* ActionAlertModel.swift */, D2ED27EA254B0CE700A1C293 /* AlertModel.swift */, D2ED27E8254B0CE600A1C293 /* ActionPopupModel.swift */, + C6687440259D92D400F32D13 /* ActionTopNotificationModel.swift */, ); path = Actions; sourceTree = ""; @@ -2432,6 +2435,7 @@ 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */, D2CAC7CF2511052300C75681 /* CollapsableNotificationModel.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, + C6687441259D92D400F32D13 /* ActionTopNotificationModel.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, 0A69F611241BDEA700F7231B /* RuleAnyRequiredModel.swift in Sources */, D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift index 1e93d98f..0fb9d00d 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift @@ -13,7 +13,6 @@ import Foundation public static var identifier: String = "topAlert" public var actionType: String = ActionTopAlertModel.identifier public var pageType: String? - public var topNotification: TopNotificationModel? public var extraParameters: JSONValueDictionary? public var analyticsData: JSONValueDictionary? @@ -22,10 +21,4 @@ import Foundation self.extraParameters = extraParameters self.analyticsData = analyticsData } - - public init(topNotification: TopNotificationModel, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) { - self.topNotification = topNotification - self.extraParameters = extraParameters - self.analyticsData = analyticsData - } } diff --git a/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift new file mode 100644 index 00000000..c1c362c5 --- /dev/null +++ b/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift @@ -0,0 +1,24 @@ +// +// ActionTopNotificationModel.swift +// MVMCoreUI +// +// Created by Murugan, Vimal on 31/12/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class ActionTopNotificationModel: ActionModelProtocol { + + public static var identifier: String = "topNotification" + public var actionType: String = ActionTopNotificationModel.identifier + public var topNotification: TopNotificationModel? + public var extraParameters: JSONValueDictionary? + public var analyticsData: JSONValueDictionary? + + public init(topNotification: TopNotificationModel, _ extraParameters: JSONValueDictionary? = nil, _ analyticsData: JSONValueDictionary? = nil) { + self.topNotification = topNotification + self.extraParameters = extraParameters + self.analyticsData = analyticsData + } +} diff --git a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift index ff262876..559b611b 100644 --- a/MVMCoreUI/Atomic/MoleculeObjectMapping.swift +++ b/MVMCoreUI/Atomic/MoleculeObjectMapping.swift @@ -259,6 +259,7 @@ import Foundation try? ModelRegistry.register(ActionTopAlertModel.self) try? ModelRegistry.register(ActionCollapseNotificationModel.self) try? ModelRegistry.register(ActionOpenPanelModel.self) + try? ModelRegistry.register(ActionTopNotificationModel.self) // MARK:- Behaviors try? ModelRegistry.register(ScreenBrightnessModifierBehavior.self) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h index 3835207b..b18a2249 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h @@ -24,6 +24,9 @@ NS_ASSUME_NONNULL_BEGIN // Collapses the current top notification - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; +// Shows a topnotification new molecular +- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject; + #pragma mark - Deprecated // Shows a popup diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m index 5ca372cd..bafdd418 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m @@ -31,6 +31,9 @@ } else if ([actionType isEqualToString:KeyActionTypeAlert]) { [self showAlert:actionInformation additionalData:additionalData delegateObject:delegateObject]; return YES; + } else if ([actionType isEqualToString:KeyActionTypeTopNotification]) { + [self topNotificationAction:actionInformation additionalData:additionalData delegateObject:delegateObject]; + return YES; } return NO; } @@ -112,6 +115,14 @@ } } +- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { + //Handle molecular topnotification + NSDictionary *topNotification = [actionInformation dict:@"topNotification"]; + if (topNotification) { + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:topNotification]; + } +} + - (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData { [super defaultHandleActionError:error additionalData:additionalData]; if (!error.silentError) { diff --git a/MVMCoreUI/Utility/MVMCoreUIConstants.h b/MVMCoreUI/Utility/MVMCoreUIConstants.h index b96d50ed..ab77986b 100644 --- a/MVMCoreUI/Utility/MVMCoreUIConstants.h +++ b/MVMCoreUI/Utility/MVMCoreUIConstants.h @@ -48,6 +48,7 @@ extern NSString * const KeyActionTypePopup; extern NSString * const KeyActionTypeAlert; extern NSString * const KeyActionTypeTopAlert; extern NSString * const KeyActionTypeCollapseNotification; +extern NSString * const KeyActionTypeTopNotification; /// Key for molecular top notification architecture. extern NSString * const KeyTopAlert; diff --git a/MVMCoreUI/Utility/MVMCoreUIConstants.m b/MVMCoreUI/Utility/MVMCoreUIConstants.m index 092851cd..2483826f 100644 --- a/MVMCoreUI/Utility/MVMCoreUIConstants.m +++ b/MVMCoreUI/Utility/MVMCoreUIConstants.m @@ -47,6 +47,7 @@ NSString * const KeyActionTypeAlert = @"alert"; NSString * const KeyActionTypeTopAlert = @"topAlert"; NSString * const KeyActionTypeCollapseNotification = @"collapseNotification"; +NSString * const KeyActionTypeTopNotification = @"topNotification"; NSString * const KeyTopAlert = @"TopNotification"; #pragma mark - Values From d4aa9ce48ad30816c83151cb6f98b0695f7177f1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Mon, 4 Jan 2021 10:40:05 -0500 Subject: [PATCH 14/27] updates for field name and cleartext. --- MVMCoreUI/BaseControllers/ViewController.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 2071673d..93e7ceb0 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -444,17 +444,20 @@ import UIKit for case let fieldError as [AnyHashable: Any] in fieldErrors ?? [] { - guard let fieldKey = fieldError["fieldName"] as? String, + guard let fieldName = fieldError["fieldName"] as? String, let userError = fieldError["userMessage"] as? String, - let entryFieldModel = formValidator?.fields[fieldKey] as? EntryFieldModel + let entryFieldModel = formValidator?.fields[fieldName] as? EntryFieldModel else { continue } entryFieldModel.dynamicErrorMessage = userError entryFieldModel.isValid = false - entryFieldModel.text = "" + + if fieldError["clearText"] as? Bool ?? true { + entryFieldModel.text = "" + } DispatchQueue.main.async { [self] in - if let view = UIView.findByAccessibility(identifier: fieldKey), let moleculeView = view as? MoleculeViewProtocol { + if let view = UIView.findByAccessibility(identifier: fieldName), let moleculeView = view as? MoleculeViewProtocol { moleculeView.set(with: entryFieldModel, delegateObjectIVar, nil) } } From 8a84d42c951d749ad6fc19bf5d2b963af2870197 Mon Sep 17 00:00:00 2001 From: "Murugan, Vimal" Date: Mon, 4 Jan 2021 22:19:14 +0530 Subject: [PATCH 15/27] review comments updated --- .../Actions/ActionTopNotificationModel.swift | 2 +- .../OtherHandlers/MVMCoreUIActionHandler.h | 3 ++ .../OtherHandlers/MVMCoreUIActionHandler.m | 33 +++++++++---------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift index c1c362c5..7ca1d6aa 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopNotificationModel.swift @@ -12,7 +12,7 @@ import UIKit public static var identifier: String = "topNotification" public var actionType: String = ActionTopNotificationModel.identifier - public var topNotification: TopNotificationModel? + public var topNotification: TopNotificationModel public var extraParameters: JSONValueDictionary? public var analyticsData: JSONValueDictionary? diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h index b18a2249..f6b89806 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.h @@ -35,6 +35,9 @@ NS_ASSUME_NONNULL_BEGIN // Shows a top alert - (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate __deprecated; +// Shows a molecular top alert +- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate __deprecated; + // Collapses the current top notification - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate __deprecated; diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m index bafdd418..dee4c547 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m @@ -98,13 +98,8 @@ } }]; } else { - NSDictionary *topNotification = [actionInformation dict:@"topNotification"]; - if (topNotification) { - [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:topNotification]; - } else { - MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeTopAlert]]; - [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; - } + MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeTopAlert]]; + [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; } } @@ -117,9 +112,8 @@ - (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { //Handle molecular topnotification - NSDictionary *topNotification = [actionInformation dict:@"topNotification"]; - if (topNotification) { - [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:topNotification]; + if (actionInformation) { + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dictionaryForKey:@"topNotification"]]; } } @@ -147,6 +141,9 @@ } else if ([actionType isEqualToString:KeyActionTypeCollapseNotification]) { [self collapseNotificationAction:actionInformation additionalData:additionalData delegate:delegate]; return YES; + } else if ([actionType isEqualToString:KeyActionTypeTopNotification]) { + [self topNotificationAction:actionInformation additionalData:additionalData delegate:delegate]; + return YES; } return NO; } @@ -186,13 +183,8 @@ } }]; } else { - NSDictionary *topNotification = [actionInformation dict:@"topNotification"]; - if (topNotification) { - [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:topNotification]; - } else { - MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegate class]),KeyActionTypeTopAlert]]; - [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegate:delegate]; - } + MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegate class]),KeyActionTypeTopAlert]]; + [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegate:delegate]; } } @@ -203,4 +195,11 @@ } } +- (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { + //Handle molecular topnotification + if (actionInformation) { + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dictionaryForKey:@"topNotification"]]; + } +} + @end From edc6296ff7666b00ec84a9c4d446efa1a9805203 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 4 Jan 2021 13:55:44 -0500 Subject: [PATCH 16/27] proper revert --- .../Atomic/Actions/ActionTopAlertModel.swift | 2 +- .../OtherHandlers/MVMCoreUIActionHandler.m | 60 +++++++------------ 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift index 0fb9d00d..62e496c2 100644 --- a/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift +++ b/MVMCoreUI/Atomic/Actions/ActionTopAlertModel.swift @@ -12,7 +12,7 @@ import Foundation public static var identifier: String = "topAlert" public var actionType: String = ActionTopAlertModel.identifier - public var pageType: String? + public var pageType: String public var extraParameters: JSONValueDictionary? public var analyticsData: JSONValueDictionary? diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m index dee4c547..79f92990 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.m @@ -84,23 +84,18 @@ - (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { // Perform a top alert. - NSString *pageTypeForTopAlert = [actionInformation string:KeyPageType]; - if (pageTypeForTopAlert) { - [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { - - NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; - if (responseInfo) { - MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData delegateObject:delegateObject]; - if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { - [((id )delegateObject.actionDelegate) willShowTopAlertWithAlertObject:alertObject alertJson:actionInformation]; - } - [alertObject showAlert]; + NSString *pageTypeForTopAlert = [actionInformation stringForKey:KeyPageType]; + [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { + + NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; + if (responseInfo) { + MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData delegateObject:delegateObject]; + if ([delegateObject.actionDelegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { + [((id )delegateObject.actionDelegate) willShowTopAlertWithAlertObject:alertObject alertJson:actionInformation]; } - }]; - } else { - MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegateObject.actionDelegate class]),KeyActionTypeTopAlert]]; - [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegateObject:delegateObject]; - } + [alertObject showAlert]; + } + }]; } - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { @@ -112,9 +107,7 @@ - (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegateObject:(nullable DelegateObject *)delegateObject { //Handle molecular topnotification - if (actionInformation) { - [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dictionaryForKey:@"topNotification"]]; - } + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dict:@"topNotification"] ?: @{}]; } - (void)defaultHandleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData { @@ -170,22 +163,17 @@ - (void)topAlertAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { // Perform a top alert. NSString *pageTypeForTopAlert = [actionInformation stringForKey:KeyPageType]; - if (pageTypeForTopAlert) { - [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { - - NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; - if (responseInfo) { - MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData actionDelegate:delegate]; - if ([delegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { - alertObject = [((id )delegate) willShowTopAlertWithAlertObject:alertObject alertJson:jsonDictionary]; - } - [alertObject showAlert]; + [[MVMCoreCache sharedCache] fetchJSONForPageType:pageTypeForTopAlert queue:nil waitUntilFinished:YES completionHandler:^(NSDictionary * _Nullable jsonDictionary) { + + NSDictionary *responseInfo = [jsonDictionary dict:KeyResponseInfo]; + if (responseInfo) { + MVMCoreAlertObject *alertObject = [MVMCoreAlertObject alertObjectForPageType:pageTypeForTopAlert responseInfo:responseInfo additionalData:additionalData actionDelegate:delegate]; + if ([delegate respondsToSelector:@selector(willShowTopAlertWithAlertObject:alertJson:)]) { + alertObject = [((id )delegate) willShowTopAlertWithAlertObject:alertObject alertJson:jsonDictionary]; } - }]; - } else { - MVMCoreErrorObject *error = [[MVMCoreErrorObject alloc] initWithTitle:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorTitle] message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeParsingJSON domain:ErrorDomainNative location:[NSString stringWithFormat:@"%@_%@",NSStringFromClass([delegate class]),KeyActionTypeTopAlert]]; - [self handleActionError:error actionInformation:actionInformation additionalData:additionalData delegate:delegate]; - } + [alertObject showAlert]; + } + }]; } - (void)collapseNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { @@ -197,9 +185,7 @@ - (void)topNotificationAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { //Handle molecular topnotification - if (actionInformation) { - [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dictionaryForKey:@"topNotification"]]; - } + [[MVMCoreUITopAlertView sharedGlobal] showTopAlertWith:[actionInformation dict:@"topNotification"] ?: @{}]; } @end From e229e5b1840c0130ecaa356e00b4ced7842f1b66 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 5 Jan 2021 11:33:14 -0500 Subject: [PATCH 17/27] change close button size in notification --- .../Atomic/Molecules/TopNotification/NotificationXButton.swift | 2 ++ MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m | 2 ++ 2 files changed, 4 insertions(+) diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift index 65c6e18c..d2696722 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButton.swift @@ -26,6 +26,8 @@ import Foundation adjustsImageWhenHighlighted = false accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "AccCloseButton") setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) + heightAnchor.constraint(equalToConstant: 16.0).isActive = true + widthAnchor.constraint(equalToConstant: 16.0).isActive = true } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) { diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m index 11d10ff0..892a6e94 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m @@ -77,6 +77,8 @@ [[MVMCoreUISession sharedGlobal].topAlertView hideAlertView:YES completionHandler:nil]; } } centeredVertically:YES]; + [closeButton.heightAnchor constraintEqualToConstant:16.0].active = YES; + [closeButton.widthAnchor constraintEqualToConstant:16.0].active = YES; [MVMCoreUITopAlertBaseView amendAccesibilityLabelForView:closeButton]; return closeButton; } From 0f9e6d4dae0bdd6e39d8863633f3f737d92b290a Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 6 Jan 2021 16:58:51 -0500 Subject: [PATCH 18/27] revised for validatiod --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 7 +++++++ .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 9 ++++++++- MVMCoreUI/BaseControllers/ViewController.swift | 9 +-------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 6bbef151..e29081ea 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -317,6 +317,13 @@ import UIKit }) } + model.updateUIDynamicError = { [weak self] in + MVMCoreDispatchUtility.performBlock(onMainThread: { + guard let self = self else { return } + self.updateValidation(model.isValid ?? false) + }) + } + title = model.title feedback = model.feedback isEnabled = model.enabled diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index 02affc3d..f70110ec 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -22,7 +22,12 @@ import Foundation public var accessibilityIdentifier: String? public var title: String? public var feedback: String? - public var dynamicErrorMessage: String? + public var dynamicErrorMessage: String? { + didSet { + isValid = false + updateUIDynamicError?() + } + } public var errorMessage: String? public var errorTextColor: Color? public var enabled: Bool = true @@ -43,6 +48,8 @@ import Foundation /// Temporary binding mechanism for the view to update on enable changes. public var updateUI: ActionBlock? + public var updateUIDynamicError: ActionBlock? + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 93e7ceb0..fc24d69f 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -449,18 +449,11 @@ import UIKit let entryFieldModel = formValidator?.fields[fieldName] as? EntryFieldModel else { continue } - entryFieldModel.dynamicErrorMessage = userError - entryFieldModel.isValid = false - if fieldError["clearText"] as? Bool ?? true { entryFieldModel.text = "" } - DispatchQueue.main.async { [self] in - if let view = UIView.findByAccessibility(identifier: fieldName), let moleculeView = view as? MoleculeViewProtocol { - moleculeView.set(with: entryFieldModel, delegateObjectIVar, nil) - } - } + entryFieldModel.dynamicErrorMessage = userError } } From 9495e3f69c99604509f29983d45c5e4b14ac2e2b Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Wed, 6 Jan 2021 17:32:51 -0500 Subject: [PATCH 19/27] deleted extension --- MVMCoreUI.xcodeproj/project.pbxproj | 4 --- .../Atomic/Extensions/UIView+Extension.swift | 31 ------------------- 2 files changed, 35 deletions(-) delete mode 100644 MVMCoreUI/Atomic/Extensions/UIView+Extension.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index e01de725..2dc86525 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -98,7 +98,6 @@ 0A7EF86523D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86423D8AFFF00B2AAD1 /* ItemDropdownEntryFieldModel.swift */; }; 0A7EF86723D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */; }; 0A849EFE246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */; }; - 0A9394892593AC9D00D2791F /* UIView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9394882593AC9D00D2791F /* UIView+Extension.swift */; }; 0A9D091D2433796500D2E6C0 /* BarsCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */; }; 0A9D091E2433796500D2E6C0 /* NumericCarouselIndicatorModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */; }; 0A9D091F2433796500D2E6C0 /* NumericIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */; }; @@ -643,7 +642,6 @@ 0A7EF86623D8B0AE00B2AAD1 /* DateDropdownEntryFieldModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateDropdownEntryFieldModel.swift; sourceTree = ""; }; 0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = ""; }; 0A849EFD246F1775009F277F /* RuleEqualsIgnoreCaseModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleEqualsIgnoreCaseModel.swift; sourceTree = ""; }; - 0A9394882593AC9D00D2791F /* UIView+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Extension.swift"; sourceTree = ""; }; 0A9D09172433796500D2E6C0 /* BarsCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BarsCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09182433796500D2E6C0 /* NumericCarouselIndicatorModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericCarouselIndicatorModel.swift; sourceTree = ""; }; 0A9D09192433796500D2E6C0 /* NumericIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericIndicatorView.swift; sourceTree = ""; }; @@ -1391,7 +1389,6 @@ 0AB764D224460FA400E7FE72 /* UIPickerView+Extension.swift */, D2ED27E6254B0CE600A1C293 /* UIAlertActionStyle+Codable.swift */, D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */, - 0A9394882593AC9D00D2791F /* UIView+Extension.swift */, ); path = Extensions; sourceTree = ""; @@ -2805,7 +2802,6 @@ 0A21DB83235DFBC500C160A2 /* MdnEntryField.swift in Sources */, 0AE98BB723FF18E9004C5109 /* ArrowModel.swift in Sources */, D28A837D23CCA86A00DFE4FC /* TabsListItemModel.swift in Sources */, - 0A9394892593AC9D00D2791F /* UIView+Extension.swift in Sources */, 0A51F3E32475CB73002E08B6 /* LoadingSpinner.swift in Sources */, BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift b/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift deleted file mode 100644 index 5f4a9aa2..00000000 --- a/MVMCoreUI/Atomic/Extensions/UIView+Extension.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// UIView+Extension.swift -// MVMCoreUI -// -// Created by Kevin Christiano on 12/23/20. -// Copyright © 2020 Verizon Wireless. All rights reserved. -// - -import UIKit - - -extension UIView { - - public class func findByAccessibility(identifier: String) -> UIView? { - - guard let window = UIApplication.shared.keyWindow else { return nil } - - func find(view: UIView, by id: String) -> UIView? { - - if view.accessibilityIdentifier == id { return view } - - for v in view.subviews { - if let aView = find(view: v, by: id) { return aView } - } - - return nil - } - - return find(view: window, by: identifier) - } -} From dabad14ed5009368214e7b9ffd27d3ff512061c7 Mon Sep 17 00:00:00 2001 From: "Suresh, Kamlesh" Date: Wed, 6 Jan 2021 18:51:03 -0500 Subject: [PATCH 20/27] code review fiixes --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 3 ++- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index e29081ea..23b9710f 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -319,7 +319,8 @@ import UIKit model.updateUIDynamicError = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { - guard let self = self else { return } + guard let self = self, model.dynamicErrorMessage != nil else { return } + model.isValid = false self.updateValidation(model.isValid ?? false) }) } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index f70110ec..08d3ee39 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -23,8 +23,7 @@ import Foundation public var title: String? public var feedback: String? public var dynamicErrorMessage: String? { - didSet { - isValid = false + didSet { updateUIDynamicError?() } } @@ -47,7 +46,8 @@ import Foundation /// Temporary binding mechanism for the view to update on enable changes. public var updateUI: ActionBlock? - + + // TODO: Remove once updateUI is fixed with isSelected public var updateUIDynamicError: ActionBlock? //-------------------------------------------------- From df5678f6961b86b04d9c1ad732b2045f7990844c Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 7 Jan 2021 09:14:07 -0500 Subject: [PATCH 21/27] adjusted --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 23b9710f..3c579317 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -319,7 +319,10 @@ import UIKit model.updateUIDynamicError = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { - guard let self = self, model.dynamicErrorMessage != nil else { return } + guard let self = self, + model.dynamicErrorMessage != nil + else { return } + model.isValid = false self.updateValidation(model.isValid ?? false) }) From 62b02b251690471628bcf3ab705dbbe312fec149 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 7 Jan 2021 09:29:11 -0500 Subject: [PATCH 22/27] altered --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 4 +--- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 3c579317..2d011898 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -319,9 +319,7 @@ import UIKit model.updateUIDynamicError = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { - guard let self = self, - model.dynamicErrorMessage != nil - else { return } + guard let self = self else { return } model.isValid = false self.updateValidation(model.isValid ?? false) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index 08d3ee39..cdcb97f6 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -23,8 +23,10 @@ import Foundation public var title: String? public var feedback: String? public var dynamicErrorMessage: String? { - didSet { - updateUIDynamicError?() + didSet { + if dynamicErrorMessage != nil { + updateUIDynamicError?() + } } } public var errorMessage: String? From 789442f13d885410a4c2fe3b92524ee1a4c59d91 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 7 Jan 2021 10:37:46 -0500 Subject: [PATCH 23/27] changes --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 4 ---- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 2d011898..9e8b531e 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -340,10 +340,6 @@ import UIKit model.wasInitiallySelected = true self.isSelected = true } - - if model.dynamicErrorMessage != nil { - showError = !(model.isValid ?? true) - } } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index cdcb97f6..63d1164e 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -23,11 +23,7 @@ import Foundation public var title: String? public var feedback: String? public var dynamicErrorMessage: String? { - didSet { - if dynamicErrorMessage != nil { - updateUIDynamicError?() - } - } + didSet { updateUIDynamicError?() } } public var errorMessage: String? public var errorTextColor: Color? From 5c0e43319335ddd0f03bd2a8bf01f74545822ea1 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 7 Jan 2021 10:48:27 -0500 Subject: [PATCH 24/27] changes --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 2 -- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 9 +++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 9e8b531e..16d36bc7 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -320,8 +320,6 @@ import UIKit model.updateUIDynamicError = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { guard let self = self else { return } - - model.isValid = false self.updateValidation(model.isValid ?? false) }) } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index 63d1164e..c9d60bfe 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -23,7 +23,10 @@ import Foundation public var title: String? public var feedback: String? public var dynamicErrorMessage: String? { - didSet { updateUIDynamicError?() } + didSet { + isValid = dynamicErrorMessage?.isEmpty ?? true + updateUIDynamicError?() + } } public var errorMessage: String? public var errorTextColor: Color? @@ -75,7 +78,9 @@ import Foundation //-------------------------------------------------- public func formFieldValue() -> AnyHashable? { - dynamicErrorMessage = nil + if dynamicErrorMessage != nil { + dynamicErrorMessage = nil + } return text } From c8d628da3151c9d5326098e8fac47f34809ecdaf Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 7 Jan 2021 10:59:09 -0500 Subject: [PATCH 25/27] changes --- .../Atomic/Atoms/FormFields/TextFields/EntryField.swift | 6 +++++- .../Atoms/FormFields/TextFields/EntryFieldModel.swift | 1 + MVMCoreUI/BaseControllers/ViewController.swift | 5 +---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 16d36bc7..8ecfc04d 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -320,7 +320,11 @@ import UIKit model.updateUIDynamicError = { [weak self] in MVMCoreDispatchUtility.performBlock(onMainThread: { guard let self = self else { return } - self.updateValidation(model.isValid ?? false) + let validState = model.isValid ?? false + self.updateValidation(validState) + if !validState && model.shouldClearText { + self.text = "" + } }) } diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index c9d60bfe..ef5c57e9 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -22,6 +22,7 @@ import Foundation public var accessibilityIdentifier: String? public var title: String? public var feedback: String? + public var shouldClearText: Bool = false public var dynamicErrorMessage: String? { didSet { isValid = dynamicErrorMessage?.isEmpty ?? true diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index fc24d69f..dcaf611e 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -449,10 +449,7 @@ import UIKit let entryFieldModel = formValidator?.fields[fieldName] as? EntryFieldModel else { continue } - if fieldError["clearText"] as? Bool ?? true { - entryFieldModel.text = "" - } - + entryFieldModel.shouldClearText = fieldError["clearText"] as? Bool ?? true entryFieldModel.dynamicErrorMessage = userError } } From 49c97466d6e58d84bdb3c62faca2e6f05249cced Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 7 Jan 2021 11:00:15 -0500 Subject: [PATCH 26/27] changes --- MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift index 8ecfc04d..811b2e2a 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryField.swift @@ -324,6 +324,7 @@ import UIKit self.updateValidation(validState) if !validState && model.shouldClearText { self.text = "" + model.shouldClearText = false } }) } From d080bdb2a767638a4dd2f85b30bc41af14eec8c6 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Thu, 7 Jan 2021 23:16:57 +0530 Subject: [PATCH 27/27] Changed access specifier for previousScreenSize --- MVMCoreUI/BaseControllers/ViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 33c47344..f8347cb3 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -43,7 +43,7 @@ import UIKit public var needsUpdateUI = false private var observingForResponses = false private var initialLoadFinished = false - private var previousScreenSize = CGSize.zero + public var previousScreenSize = CGSize.zero public var selectedField: UIView?