diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index 8818107b..08afefde 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -18,6 +18,8 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat //-------------------------------------------------- //Making static property as class property so that subclasses can override getter function of the property open class var identifier: String { "button" } + public var id: String = UUID().uuidString + public var accessibilityIdentifier: String? public var accessibilityText: String? public var title: String @@ -174,6 +176,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -201,6 +204,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) title = try typeContainer.decode(String.self, forKey: .title) @@ -263,6 +267,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(title, forKey: .title) try container.encode(enabled, forKey: .enabled) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 71431d0f..3a5429e1 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -16,6 +16,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea //-------------------------------------------------- public static var identifier: String = "caretLink" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? public var title: String @@ -41,6 +42,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case backgroundColor case accessibilityIdentifier case title @@ -61,6 +63,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decode(String.self, forKey: .title) @@ -94,6 +97,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, Enablea public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(title, forKey: .title) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift index 560027f3..a61ec150 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ImageButtonModel.swift @@ -14,8 +14,9 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro //-------------------------------------------------- public static var identifier: String = "imageButton" + public var id: String = UUID().uuidString + public var backgroundColor: Color? - public var image: ImageViewModel? public var accessibilityText: String? @@ -34,6 +35,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro } private enum CodingKeys: String, CodingKey { + case id case moleculeName case image case backgroundColor @@ -52,6 +54,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) image = try typeContainer.decodeIfPresent(ImageViewModel.self, forKey: .image) accessibilityText = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityText) @@ -77,6 +80,7 @@ open class ImageButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGro public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(image, forKey: .image) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index 38bcb491..62ba0422 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -15,6 +15,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode //-------------------------------------------------- public class var identifier: String { "link" } + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -48,6 +49,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -91,6 +93,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decode(String.self, forKey: .title) @@ -137,6 +140,7 @@ open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableMode public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(title, forKey: .title) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift index 823d2478..40cb98b7 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagModel.swift @@ -11,11 +11,14 @@ import MVMCore @objcMembers public class TagModel: MoleculeModelProtocol { public static var identifier: String = "tag" + public var id: String = UUID().uuidString + public var label: LabelModel public var action: ActionModelProtocol? public var backgroundColor: Color? private enum CodingKeys: String, CodingKey { + case id case moleculeName case label case action @@ -38,6 +41,7 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString label = try typeContainer.decode(LabelModel.self, forKey: .label) action = try typeContainer.decodeModelIfPresent(codingKey: .action) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -45,6 +49,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(label, forKey: .label) try container.encodeModelIfPresent(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift index 6330bb94..22ce1d9a 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/Tags/TagsModel.swift @@ -11,10 +11,13 @@ import MVMCore @objcMembers public class TagsModel: MoleculeModelProtocol { public static var identifier: String = "tags" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var tags: [TagModel] private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case tags @@ -30,12 +33,14 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString tags = try typeContainer.decode([TagModel].self, forKey: .tags) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tags, forKey: .tags) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift index 7b3eee03..6f58cf64 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/EntryFieldModel.swift @@ -16,6 +16,7 @@ import Foundation //-------------------------------------------------- public class var identifier: String { "" } + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -63,6 +64,7 @@ import Foundation //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -138,6 +140,7 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decodeIfPresent(String.self, forKey: .title) @@ -166,6 +169,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift index 7b6b36d8..604a8a8d 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/CheckboxModel.swift @@ -20,6 +20,7 @@ //-------------------------------------------------- public static var identifier: String = "checkbox" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var accessibilityIdentifier: String? public var selected: Bool = false @@ -51,6 +52,7 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case accessibilityIdentifier case checked @@ -107,6 +109,8 @@ required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) if let borderWidth = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .borderWidth) { @@ -180,6 +184,7 @@ public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(groupName, forKey: .groupName) try container.encodeIfPresent(fieldKey, forKey: .fieldKey) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift index 4be1343a..cb301e22 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/HeartModel.swift @@ -14,6 +14,8 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- public static var identifier: String = "heart" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var isActive: Bool = false @@ -27,6 +29,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -49,6 +52,8 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let isActive = try typeContainer.decodeIfPresent(Bool.self, forKey: .isActive) { self.isActive = isActive } @@ -75,6 +80,7 @@ open class HeartModel: MoleculeModelProtocol, EnableableModelProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(isActive, forKey: .isActive) try container.encode(activeColor, forKey: .activeColor) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift index 27defd48..acec6e83 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioBox" + public var id: String = UUID().uuidString + public var text: String public var subText: String? public var backgroundColor: Color? @@ -30,6 +32,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case text case subText @@ -58,6 +61,8 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString text = try typeContainer.decode(String.self, forKey: .text) subText = try typeContainer.decodeIfPresent(String.self, forKey: .subText) selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) @@ -81,6 +86,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(text, forKey: .text) try container.encodeIfPresent(subText, forKey: .subText) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift index 6348eac5..f1c652f7 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioBoxesModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioBoxes" + public var id: String = UUID().uuidString + public var boxes: [RadioBoxModel] public var backgroundColor: Color? public var accessibilityIdentifier: String? @@ -49,6 +51,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case enabled case readOnly @@ -75,6 +78,7 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString selectedAccentColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedAccentColor) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) @@ -91,6 +95,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(boxes, forKey: .boxes) try container.encodeIfPresent(selectedAccentColor, forKey: .selectedAccentColor) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift index 86eb36e9..99b5cdb7 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioButtonModel.swift @@ -15,6 +15,8 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public static var identifier: String = "radioButton" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var state: Bool = false @@ -35,6 +37,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -80,6 +83,8 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { self.state = state } @@ -105,6 +110,7 @@ open class RadioButtonModel: MoleculeModelProtocol, FormFieldProtocol { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(state, forKey: .state) try container.encode(enabled, forKey: .enabled) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift index f0a194e9..91f13b48 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioSwatch" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var color: Color = Color(uiColor: .mvmBlue) @@ -29,6 +31,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -54,6 +57,7 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) @@ -79,6 +83,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift index d5d3992a..f424593b 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/RadioSwatchesModel.swift @@ -13,6 +13,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioSwatches" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var swatches: [RadioSwatchModel] @@ -43,6 +45,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -67,6 +70,7 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) swatches = try typeContainer.decode([RadioSwatchModel].self, forKey: .swatches) @@ -81,6 +85,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift index e8d50851..429a5769 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/ToggleModel.swift @@ -13,6 +13,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- public static var identifier: String = "toggle" + public var id: String = UUID().uuidString + public var accessibilityIdentifier: String? public var backgroundColor: Color? public var selected: Bool = false @@ -36,6 +38,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case state case animated @@ -86,6 +89,8 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) { self.selected = state } @@ -128,6 +133,7 @@ public class ToggleModel: MoleculeModelProtocol, FormFieldProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encodeModelIfPresent(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift index 388f1669..7697143e 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ArrowModel.swift @@ -17,8 +17,9 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { public static var identifier: String { return "arrow" } - public var moleculeName: String? + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var disabledColor: Color = Color(uiColor: .mvmCoolGray3) public var color: Color = Color(uiColor: .mvmBlack) @@ -57,6 +58,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case disabledColor @@ -75,7 +77,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) - + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) if let disabledColor = try typeContainer.decodeIfPresent(Color.self, forKey: .disabledColor) { @@ -113,6 +115,7 @@ open class ArrowModel: MoleculeModelProtocol, EnableableModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(disabledColor, forKey: .disabledColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift index 1e2595ec..380328d5 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CaretViewModel.swift @@ -15,6 +15,7 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "caretView" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var strokeColor: Color = Color(uiColor: .mvmBlack) public var strokeColor_inverted: Color = Color(uiColor: .mvmWhite) @@ -28,6 +29,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case strokeColor @@ -51,6 +53,8 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let strokeColor = try typeContainer.decodeIfPresent(Color.self, forKey: .strokeColor) { self.strokeColor = strokeColor } @@ -78,6 +82,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(strokeColor, forKey: .strokeColor) try container.encode(strokeColor_inverted, forKey: .strokeColor_inverted) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index 164bb306..f5c0adeb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -18,6 +18,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro return "" } + public var id: String = UUID().uuidString public var backgroundColor: Color? public var moleculeName: String? public var numberOfPages: Int = 0 @@ -44,6 +45,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case currentIndex @@ -66,6 +68,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString moleculeName = try typeContainer.decodeIfPresent(String.self, forKey: .moleculeName) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -112,6 +115,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(numberOfPages, forKey: .numberOfPages) diff --git a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift index 58f398b6..ca0acd79 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CheckboxLabelModel.swift @@ -18,6 +18,8 @@ public enum CheckboxPosition: String, Codable { @objcMembers open class CheckboxLabelModel: MoleculeModelProtocol { open class var identifier: String { "checkboxLabel" } public var moleculeName: String = CheckboxLabelModel.identifier + @DecodableDefault.UUIDString public var id: String + public var backgroundColor: Color? public var checkboxAlignment: CheckboxPosition? public var checkbox: CheckboxModel diff --git a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift index 95cc40fd..8e533fde 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/DashLineModel.swift @@ -15,6 +15,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "dashLine" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var accessibilityIdentifier: String? public var dashColor: Color = Color(uiColor: .mvmCoolGray3) @@ -35,6 +37,7 @@ import MVMCore //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case accessibilityIdentifier @@ -56,6 +59,8 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let dashColor = try typeContainer.decodeIfPresent(Color.self, forKey: .dashColor) { self.dashColor = dashColor } @@ -74,6 +79,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(dashColor, forKey: .dashColor) try container.encode(isHidden, forKey: .isHidden) diff --git a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift index c61739a7..5079fc93 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ImageViewModel.swift @@ -13,6 +13,7 @@ //-------------------------------------------------- open class var identifier: String { "image" } + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var moleculeName: String = ImageViewModel.identifier @@ -45,6 +46,7 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case image diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift index 76b534a5..19284756 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/LabelModel.swift @@ -7,13 +7,14 @@ // -@objcMembers open class LabelModel: MoleculeModelProtocol, Identifiable { +@objcMembers open class LabelModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- open class var identifier: String { "label" } public var id: String + public var backgroundColor: Color? public var text: String public var accessibilityText: String? @@ -35,8 +36,8 @@ //-------------------------------------------------- private enum CodingKeys: String, CodingKey { - case moleculeName case id + case moleculeName case text case accessibilityText case textColor @@ -110,7 +111,7 @@ open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeIfPresent(moleculeName, forKey: .moleculeName) - try container.encodeIfPresent(id, forKey: .id) + try container.encode(id, forKey: .id) try container.encode(text, forKey: .text) try container.encodeIfPresent(accessibilityText, forKey: .accessibilityText) try container.encodeIfPresent(textColor, forKey: .textColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift index 07c534f8..2f442dc8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LeftRightLabelModel.swift @@ -15,6 +15,8 @@ import UIKit public static var identifier: String = "leftRightLabelView" public var moleculeName: String = LeftRightLabelModel.identifier + @DecodableDefault.UUIDString public var id: String + public var backgroundColor: Color? public var leftText: LabelModel public var rightText: LabelModel? diff --git a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift index cc9e7333..3b4c57e9 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LineModel.swift @@ -53,6 +53,8 @@ import VDSColorTokens //-------------------------------------------------- public static var identifier: String = "line" + public var id: String = UUID().uuidString + public var type: Style = .secondary public var frequency: Frequency? = .allExceptTop @@ -120,6 +122,7 @@ import VDSColorTokens //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case type case backgroundColor @@ -138,6 +141,8 @@ import VDSColorTokens required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let type = try typeContainer.decodeIfPresent(Style.self, forKey: .type) { self.type = type } @@ -158,6 +163,7 @@ import VDSColorTokens public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(id, forKey: .id) try container.encode(type, forKey: .type) try container.encode(inverted, forKey: .inverted) try container.encodeIfPresent(frequency, forKey: .frequency) diff --git a/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift b/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift index ddfba326..b74807fb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/LoadingSpinnerModel.swift @@ -13,9 +13,10 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - public var backgroundColor: Color? public static var identifier: String = "loadingSpinner" + public var id: String = UUID().uuidString + + public var backgroundColor: Color? public var strokeColor = Color(uiColor: .mvmBlack) public var lineWidth: CGFloat = 4 public var diameter: CGFloat = 40 @@ -25,6 +26,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case strokeColor @@ -45,6 +47,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) if let diameter = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .diameter) { @@ -62,6 +65,7 @@ open class LoadingSpinnerModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(diameter, forKey: .diameter) diff --git a/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift b/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift index fb70ffd0..d664afa6 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/MultiProgressModel.swift @@ -19,13 +19,17 @@ import Foundation } @objcMembers public class MultiProgressBarModel: MoleculeModelProtocol { + public static var identifier: String = "multiProgressBar" + public var id: String = UUID().uuidString + public var progressList: [SingleProgressBarModel] public var backgroundColor: Color? public var thickness: CGFloat? public var roundedCorners: Bool? private enum CodingKeys: String, CodingKey { + case id case moleculeName case progressList case thickness @@ -39,6 +43,7 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString progressList = try typeContainer.decode([SingleProgressBarModel].self, forKey: .progressList) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) thickness = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .thickness) @@ -47,6 +52,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(progressList, forKey: .progressList) try container.encodeIfPresent(thickness, forKey: .thickness) diff --git a/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift b/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift index 7cef8936..439fad3d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/ProgressBarModel.swift @@ -10,6 +10,8 @@ import Foundation @objcMembers public class ProgressBarModel: MoleculeModelProtocol { public static var identifier: String = "progressBar" + public var id: String = UUID().uuidString + @Percent public var percent: CGFloat public var color: Color = Color(uiColor: .mfCerulean()) public var backgroundColor: Color? = Color(uiColor: .mfLightSilver()) @@ -17,6 +19,7 @@ import Foundation public var thickness: CGFloat? private enum CodingKeys: String, CodingKey { + case id case moleculeName case roundedCorners case thickness @@ -31,6 +34,7 @@ import Foundation required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString percent = try typeContainer.decode(CGFloat.self, forKey: .percent) if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) { self.color = color @@ -44,6 +48,7 @@ import Foundation public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(percent, forKey: .percent) try container.encode(color, forKey: .color) diff --git a/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift b/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift index 56f4f7ad..7b427cde 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/StarModel.swift @@ -13,6 +13,8 @@ open class StarModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "star" + public var id: String = UUID().uuidString + public var backgroundColor: Color? @Percent public var percent: CGFloat = 0 public var borderColor: Color? @@ -23,6 +25,7 @@ open class StarModel: MoleculeModelProtocol { // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case percent @@ -43,6 +46,7 @@ open class StarModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) { self.percent = percent } @@ -56,6 +60,7 @@ open class StarModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(percent, forKey: .percent) diff --git a/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift b/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift index f79f638e..10e6400a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/StarsModel.swift @@ -13,6 +13,8 @@ import MVMCore // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "stars" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var starBackgroundColor: Color? public var stars: [StarModel] @@ -25,6 +27,7 @@ import MVMCore // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case starBackgroundColor @@ -48,6 +51,8 @@ import MVMCore //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString stars = try typeContainer.decode([StarModel].self, forKey: .stars) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) starBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .starBackgroundColor) @@ -63,6 +68,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(stars, forKey: .stars) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index 620e0940..b41d9eef 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -15,6 +15,7 @@ open class TileletModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "tilelet" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var color: TileContainer.BackgroundColor public var padding: TileContainer.Padding @@ -30,6 +31,7 @@ open class TileletModel: MoleculeModelProtocol { public var action: ActionModelProtocol? private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case color @@ -47,6 +49,7 @@ open class TileletModel: MoleculeModelProtocol { } required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + self.id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor) self.color = try container.decodeIfPresent(TileContainer.BackgroundColor.self, forKey: .color) ?? TileContainer.BackgroundColor.black self.padding = try container.decodeIfPresent(TileContainer.Padding.self, forKey: .padding) ?? TileContainer.Padding.padding4X @@ -86,6 +89,7 @@ open class TileletModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(color, forKey: .color) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift b/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift index 7c348760..27567926 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Video/VideoModel.swift @@ -10,6 +10,7 @@ import Foundation open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { public static var identifier = "video" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var video: String public var showControls = false @@ -43,6 +44,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { private var resignActiveListener: Any? private enum CodingKeys: String, CodingKey { + case id case moleculeName case video case showControls @@ -57,6 +59,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString video = try typeContainer.decode(String.self, forKey:.video) if let showControls = try typeContainer.decodeIfPresent(Bool.self, forKey: .showControls) { self.showControls = showControls @@ -72,6 +75,7 @@ open class VideoModel: MoleculeModelProtocol, PageBehaviorProtocolRequirer { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(video, forKey: .video) try container.encode(showControls, forKey: .showControls) diff --git a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift index 4cb2bd55..28d619a8 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WebViewModel.swift @@ -12,6 +12,8 @@ import MVMCore @objcMembers public class WebViewModel: MoleculeModelProtocol { public static var identifier: String = "webview" public var moleculeName: String = WebViewModel.identifier + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var url: URL? public var htmlString: String? @@ -23,6 +25,7 @@ import MVMCore } private enum CodingKeys: String, CodingKey{ + case id case moleculeName case backgroundColor case url @@ -39,6 +42,7 @@ import MVMCore required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) url = try typeContainer.decodeIfPresent(URL.self, forKey: .url) htmlString = try typeContainer.decodeIfPresent(String.self, forKey: .htmlString) @@ -51,6 +55,7 @@ import MVMCore public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(url, forKey: .url) diff --git a/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift b/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift index 85e4fffb..4fed14cb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/WheelModel.swift @@ -19,6 +19,8 @@ public enum GraphStyle: String, Codable { public class WheelModel: MoleculeModelProtocol { public static var identifier: String = "wheel" + public var id: String = UUID().uuidString + public var style: GraphStyle = .unlimited { didSet { updateStyle() @@ -43,6 +45,7 @@ public class WheelModel: MoleculeModelProtocol { } private enum CodingKeys: String, CodingKey { + case id case style case size case diameter @@ -56,6 +59,8 @@ public class WheelModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let style = try typeContainer.decodeIfPresent(GraphStyle.self, forKey: .style) { self.style = style } @@ -84,6 +89,7 @@ public class WheelModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(style, forKey: .style) try container.encode(size, forKey: .size) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift index 0d68da42..acbf276d 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockUpsPlanNamesModel.swift @@ -13,6 +13,8 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { // MARK: - Properties //-------------------------------------------------- public static var identifier: String = "planNamesLockup" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var headline: LabelModel public var subHeadline: LabelModel @@ -31,6 +33,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { // MARK: - Keys //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headline @@ -43,6 +46,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) headline = try typeContainer.decode(LabelModel.self, forKey: .headline) subHeadline = try typeContainer.decode(LabelModel.self, forKey: .subHeadline) @@ -51,6 +55,7 @@ public class LockUpsPlanNamesModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(headline, forKey: .headline) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift index 433bc322..3e1c1bcc 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/LockupsPlanSMLXLModel.swift @@ -14,6 +14,8 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "planLockup" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var planLabel : LabelModel public var headline : LabelModel @@ -43,6 +45,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case planLabel @@ -57,6 +60,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) planLabel = try typeContainer.decode(LabelModel.self, forKey: .planLabel) headline = try typeContainer.decode(LabelModel.self, forKey: .headline) @@ -67,6 +71,7 @@ public class LockupsPlanSMLXLModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(planLabel, forKey: .planLabel) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift index 4548207d..89d32ca9 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/LockUps/TitleLockupModel.swift @@ -16,6 +16,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco public static var identifier: String = "titleLockup" public var moleculeName: String = TitleLockupModel.identifier + public var id: String = UUID().uuidString public var eyebrow: LabelModel? public var title: LabelModel @@ -130,6 +131,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case eyebrow @@ -145,6 +147,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString title = try typeContainer.decodeMolecule(codingKey: .title) eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow) subTitle = try typeContainer.decodeMoleculeIfPresent(codingKey: .subTitle) @@ -164,6 +167,7 @@ public class TitleLockupModel: MoleculeModelProtocol, ParentMoleculeModelProtoco public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(eyebrow, forKey: .eyebrow) try container.encodeModel(title, forKey: .title) diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift index ee4e664a..7ac68d0a 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartItemModel.swift @@ -14,9 +14,11 @@ import Foundation // MARK: - Properties //-------------------------------------------------- - public var backgroundColor: Color? public static var identifier: String = "doughnutChartItem" public var moleculeName: String = DoughnutChartItemModel.identifier + @DecodableDefault.UUIDString public var id: String + + public var backgroundColor: Color? public var label: LabelModel @Percent public var percent: CGFloat public var color: Color diff --git a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift index fbb034c6..3333ae77 100644 --- a/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Doughnut/DoughnutChartModel.swift @@ -14,9 +14,11 @@ import Foundation // MARK: - Properties //-------------------------------------------------- - public var backgroundColor: Color? public static var identifier: String = "doughnutChart" public var moleculeName: String = DoughnutChartModel.identifier + @DecodableDefault.UUIDString public var id: String + + public var backgroundColor: Color? public var title: LabelModel? public var subtitle: LabelModel? public var sections: [DoughnutChartItemModel] diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift index 2c188d6b..84518c8c 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/ImageHeadlineBodyModel.swift @@ -15,6 +15,8 @@ public class ImageHeadlineBodyModel: MoleculeModelProtocol { public static var identifier: String = "imageHeadlineBody" public var moleculeName: String = ImageHeadlineBodyModel.identifier + @DecodableDefault.UUIDString public var id: String + public var backgroundColor: Color? public var image: ImageViewModel public var headlineBody: HeadlineBodyModel diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift index 69bca3fc..571848dc 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/RadioButtonLabelModel.swift @@ -15,6 +15,8 @@ import MVMCore //-------------------------------------------------- public static var identifier: String = "radioButtonLabel" + @DecodableDefault.UUIDString public var id: String + public var backgroundColor: Color? public var moleculeName: String = RadioButtonLabelModel.identifier public var radioButton: RadioButtonModel diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift index 3b62210c..b984a9da 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabBarModel.swift @@ -11,6 +11,8 @@ import VDSColorTokens open class TabBarModel: MoleculeModelProtocol { public static var identifier: String = "tabBar" + public var id: String = UUID().uuidString + open var tabs: [TabBarItemModel] private var _backgroundColor: Color? @@ -58,6 +60,7 @@ open class TabBarModel: MoleculeModelProtocol { open var selectedTab: Int = 0 private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case tabs @@ -73,6 +76,7 @@ open class TabBarModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString tabs = try typeContainer.decode([TabBarItemModel].self, forKey: .tabs) if let color = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) { backgroundColor = color @@ -93,6 +97,7 @@ open class TabBarModel: MoleculeModelProtocol { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tabs, forKey: .tabs) try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift index 6e154895..3671e5e1 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TabsModel.swift @@ -11,6 +11,8 @@ import VDSColorTokens open class TabsModel: MoleculeModelProtocol { public static var identifier: String = "tabs" + public var id: String = UUID().uuidString + open var tabs: [TabItemModel] open var style: NavigationItemStyle? @@ -71,6 +73,7 @@ open class TabsModel: MoleculeModelProtocol { open var selectedIndex: Int = 0 private enum CodingKeys: String, CodingKey { + case id case moleculeName case tabs case backgroundColor @@ -87,6 +90,7 @@ open class TabsModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString tabs = try typeContainer.decode([TabItemModel].self, forKey: .tabs) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) _selectedColor = try typeContainer.decodeIfPresent(Color.self, forKey: .selectedColor) @@ -100,6 +104,7 @@ open class TabsModel: MoleculeModelProtocol { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encode(tabs, forKey: .tabs) try container.encodeIfPresent(_backgroundColor, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift index 718cfc30..b5d07c4a 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoButtonViewModel.swift @@ -15,6 +15,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "twoButtonView" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var primaryButton: ButtonModel? public var secondaryButton: ButtonModel? @@ -28,6 +29,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case primaryButton @@ -49,6 +51,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) //set context value for 'primary' style to be set for the primaryButton in case the @@ -66,6 +69,7 @@ public class TwoButtonViewModel: ParentMoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(primaryButton, forKey: .primaryButton) diff --git a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift index 57962c09..c9ae177b 100644 --- a/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HorizontalCombinationViews/TwoLinkViewModel.swift @@ -10,11 +10,14 @@ import Foundation public class TwoLinkViewModel: MoleculeModelProtocol { public static var identifier: String = "twoLinkView" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var rightLink: LinkModel? public var leftLink: LinkModel? private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case rightLink @@ -28,6 +31,7 @@ public class TwoLinkViewModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) rightLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .rightLink) leftLink = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .leftLink) @@ -35,6 +39,7 @@ public class TwoLinkViewModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(rightLink, forKey: .rightLink) diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift index 7c8bd202..2e7b7500 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ActionDetailWithImageModel.swift @@ -11,6 +11,8 @@ import Foundation public class ActionDetailWithImageModel: MoleculeModelProtocol { public static var identifier: String = "actionDetailWithImage" public var moleculeName: String = ActionDetailWithImageModel.identifier + @DecodableDefault.UUIDString public var id: String + public var backgroundColor: Color? public var headlineBodyButton: HeadlineBodyButtonModel public var image: ImageViewModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift index aabd29e7..dc8f2396 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/CornerLabelsModel.swift @@ -11,6 +11,7 @@ import MVMCore public class CornerLabelsModel: ParentMoleculeModelProtocol { public static var identifier: String = "cornerLabels" + public var id: String = UUID().uuidString public var backgroundColor: Color? public var topLeftLabel: LabelModel? public var topRightLabel: LabelModel? @@ -26,6 +27,7 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { } private enum CodingKeys: String, CodingKey { + case id case backgroundColor case topLeftLabel case topRightLabel @@ -37,6 +39,7 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) molecule = try typeContainer.decodeModelIfPresent(codingKey: .molecule) topLeftLabel = try typeContainer.decodeMoleculeIfPresent(codingKey: .topLeftLabel) @@ -47,6 +50,7 @@ public class CornerLabelsModel: ParentMoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModelIfPresent(molecule, forKey: .molecule) try container.encodeModelIfPresent(topLeftLabel, forKey: .topLeftLabel) diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift index 19c1f4d6..84a03adf 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyLinkToggleModel.swift @@ -10,6 +10,7 @@ import Foundation public class HeadlineBodyLinkToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLinkToggle" public var moleculeName: String = HeadlineBodyLinkToggleModel.identifier + @DecodableDefault.UUIDString public var id: String public var backgroundColor: Color? public var headlineBodyLink: HeadlineBodyLinkModel public var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift index 800c976b..4c86ed76 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/HeadlineBodyToggleModel.swift @@ -12,6 +12,7 @@ import Foundation open class HeadlineBodyToggleModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyToggle" public var moleculeName: String = HeadlineBodyToggleModel.identifier + @DecodableDefault.UUIDString public var id: String open var backgroundColor: Color? open var headlineBody: HeadlineBodyModel open var toggle: ToggleModel diff --git a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift index ee0c5f78..fe8cc16a 100644 --- a/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift +++ b/MVMCoreUI/Atomic/Molecules/LeftRightViews/ToggleMolecules/LabelToggleModel.swift @@ -12,6 +12,8 @@ import MVMCore public class LabelToggleModel: MoleculeModelProtocol { public static var identifier: String = "labelToggle" public var moleculeName: String = LabelToggleModel.identifier + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var label: LabelModel public var toggle: ToggleModel @@ -22,6 +24,7 @@ public class LabelToggleModel: MoleculeModelProtocol { } private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case label @@ -30,6 +33,7 @@ public class LabelToggleModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey:.backgroundColor) label = try typeContainer.decode(LabelModel.self, forKey:.label) toggle = try typeContainer.decode(ToggleModel.self, forKey:.toggle) @@ -38,6 +42,7 @@ public class LabelToggleModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(label, forKey: .label) try container.encode(toggle, forKey: .toggle) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index f0b0bbc0..ab1c993e 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -13,9 +13,11 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule // MARK: - Properties //-------------------------------------------------- + public static var identifier: String = "navigationImageButton" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var accessibilityIdentifier: String? - public static var identifier: String = "navigationImageButton" public var image: String public var action: ActionModelProtocol public var accessibilityText: String? @@ -35,6 +37,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case image case action case accessibilityIdentifier @@ -49,6 +52,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) image = try typeContainer.decode(String.self, forKey: .image) action = try typeContainer.decodeModel(codingKey: .action) @@ -60,6 +64,7 @@ public class NavigationImageButtonModel: NavigationButtonModelProtocol, Molecule open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(image, forKey: .image) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encode(moleculeName, forKey: .moleculeName) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift index d72c6ae0..33529e77 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -12,8 +12,10 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo // MARK: - Properties //-------------------------------------------------- - open var backgroundColor: Color? open class var identifier: String { "navigationLabelButton" } + public var id: String = UUID().uuidString + + open var backgroundColor: Color? open var accessibilityIdentifier: String? open var title: String open var action: ActionModelProtocol @@ -32,6 +34,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case accessibilityIdentifier case title @@ -44,6 +47,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString accessibilityIdentifier = try typeContainer.decodeIfPresent(String.self, forKey: .accessibilityIdentifier) title = try typeContainer.decode(String.self, forKey: .title) action = try typeContainer.decodeModel(codingKey: .action) @@ -51,6 +55,7 @@ open class NavigationLabelButtonModel: NavigationButtonModelProtocol, MoleculeMo open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(accessibilityIdentifier, forKey: .accessibilityIdentifier) try container.encode(title, forKey: .title) diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index 64b61480..d39cdeaf 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -19,6 +19,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc //-------------------------------------------------- open class var identifier: String { "navigationBar" } + public var id: String = UUID().uuidString private let defaultHidesSystemBackButton = true @@ -74,6 +75,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case title case hidden @@ -96,6 +98,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString title = try typeContainer.decodeIfPresent(String.self, forKey: .title) if let hidden = try typeContainer.decodeIfPresent(Bool.self, forKey: .hidden) { self.hidden = hidden @@ -122,6 +125,7 @@ open class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProtoc open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(title, forKey: .title) try container.encode(hidden, forKey: .hidden) diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift index 931e7c04..b34922db 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMoleculeModel.swift @@ -9,11 +9,15 @@ import Foundation open class ModuleMoleculeModel: MoleculeModelProtocol { - public var backgroundColor: Color? + public static var identifier: String = "moduleMolecule" + public var id: String = UUID().uuidString + + public var backgroundColor: Color? public var moduleName: String private enum CodingKeys: String, CodingKey { + case id case moduleName } @@ -23,11 +27,13 @@ open class ModuleMoleculeModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString moduleName = try typeContainer.decode(String.self, forKey:.moduleName) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moduleName, forKey: .moduleName) } } diff --git a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift index 71324dff..ac1c8905 100644 --- a/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/TopNotification/NotificationXButtonModel.swift @@ -10,12 +10,16 @@ import Foundation import MVMCore public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtocol { + public static var identifier: String = "notificationXButton" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var color: Color? public var action: ActionModelProtocol = ActionNoopModel() private enum CodingKeys: String, CodingKey { + case id case moleculeName case color case action @@ -28,6 +32,7 @@ public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtoco public required init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString color = try typeContainer.decodeIfPresent(Color.self, forKey: .color) if let action: ActionModelProtocol = try typeContainer.decodeModelIfPresent(codingKey: .action) { self.action = action @@ -36,6 +41,7 @@ public class NotificationXButtonModel: ButtonModelProtocol, MoleculeModelProtoco public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(color, forKey: .color) try container.encodeModel(action, forKey: .action) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift index 83f5b4bd..0d46916e 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/EyebrowHeadlineBodyLinkModel.swift @@ -13,6 +13,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule //-------------------------------------------------- public static var identifier: String = "eyebrowHeadlineBodyLink" + public var id: String = UUID().uuidString public var moleculeName: String = EyebrowHeadlineBodyLinkModel.identifier public var backgroundColor: Color? public var eyebrow: LabelModel? @@ -56,6 +57,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case eyebrow @@ -70,6 +72,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow) headline = try typeContainer.decodeMoleculeIfPresent(codingKey: .headline) @@ -84,6 +87,7 @@ public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol, ParentMolecule public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeIfPresent(eyebrow, forKey: .eyebrow) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift index 70a08d3b..1b713720 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyButtonModel.swift @@ -14,6 +14,8 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyButton" public var moleculeName: String = HeadlineBodyButtonModel.identifier + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var headlineBody: HeadlineBodyModel @@ -45,6 +47,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headlineBody @@ -58,6 +61,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody) button = try typeContainer.decode(ButtonModel.self, forKey: .button) @@ -67,6 +71,7 @@ public class HeadlineBodyButtonModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(headlineBody, forKey: .headlineBody) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift index 9f16e3ce..6c2113bf 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyLinkModel.swift @@ -16,6 +16,8 @@ public class HeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "headlineBodyLink" public var moleculeName: String = HeadlineBodyLinkModel.identifier + @DecodableDefault.UUIDString public var id: String + public var headlineBody: HeadlineBodyModel public var link: LinkModel public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 20df223a..a3eaf918 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -14,6 +14,7 @@ public static var identifier: String = "headlineBody" public var moleculeName: String = HeadlineBodyModel.identifier + public var id: String = UUID().uuidString public var headline: LabelModel? public var body: LabelModel? public var style: Style? @@ -23,6 +24,15 @@ [headline, body].compactMap { $0 } } + public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { + return [ + \HeadlineBodyModel.headline, + \HeadlineBodyModel.body, + ].contains { + replaceChildMolecule(on: self, keyPath: $0, replacementMolecule: replacementMolecule) + } + } + //-------------------------------------------------- // MARK: - Enum //-------------------------------------------------- @@ -57,6 +67,7 @@ //----------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case headline case body @@ -66,6 +77,7 @@ required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString headline = try typeContainer.decodeMoleculeIfPresent(codingKey: .headline) body = try typeContainer.decodeMoleculeIfPresent(codingKey: .body) style = try typeContainer.decodeIfPresent(Style.self, forKey: .style) @@ -74,6 +86,7 @@ public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(headline, forKey: .headline) try container.encodeIfPresent(body, forKey: .body) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift index b1b12a54..8ffc24e4 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift @@ -13,6 +13,8 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "stringAndMoleculeModel" + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var string: String public var molecule: MoleculeModelProtocol @@ -33,6 +35,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case string @@ -46,6 +49,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { public required init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) string = try typeContainer.decode(String.self, forKey: .string) molecule = try typeContainer.decodeModel(codingKey: .molecule) @@ -54,6 +58,7 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(string, forKey: .string) try container.encodeModel(molecule, forKey: .molecule) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift index efdc058c..8f413429 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/ThreeHeadlineBodyLinkModel.swift @@ -16,6 +16,8 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { public static var identifier: String = "threeHeadlineBodyLink" public var moleculeName: String = ThreeHeadlineBodyLinkModel.identifier + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var headline1: LabelModel @@ -41,6 +43,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case headline1 @@ -56,6 +59,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) headline1 = try typeContainer.decode(LabelModel.self, forKey: .headline1) headline2 = try typeContainer.decode(LabelModel.self, forKey: .headline2) @@ -67,6 +71,7 @@ public class ThreeHeadlineBodyLinkModel: MoleculeModelProtocol { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) + try container.encode(id, forKey: .id) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(headline1, forKey: .headline1) try container.encode(headline2, forKey: .headline2) diff --git a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift index bc3877e5..5bfd8d0f 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel/CarouselModel.swift @@ -19,6 +19,8 @@ import UIKit return "carousel" } + public var id: String = UUID().uuidString + public var backgroundColor: Color? public var molecules: [MoleculeModelProtocol & CarouselItemModelProtocol] public var index: Int = 0 @@ -78,6 +80,7 @@ import UIKit //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case moleculeName case backgroundColor case molecules @@ -108,6 +111,7 @@ import UIKit required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString molecules = try typeContainer.decodeModels(codingKey: .molecules) index = try typeContainer.decodeIfPresent(Int.self, forKey: .index) ?? 0 selectable = try typeContainer.decodeIfPresent(Bool.self, forKey: .selectable) ?? false @@ -144,6 +148,7 @@ import UIKit public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encodeModels(molecules, forKey: .molecules) diff --git a/MVMCoreUI/Atomic/Organisms/StackModel.swift b/MVMCoreUI/Atomic/Organisms/StackModel.swift index 6310fcea..da6c067e 100644 --- a/MVMCoreUI/Atomic/Organisms/StackModel.swift +++ b/MVMCoreUI/Atomic/Organisms/StackModel.swift @@ -25,6 +25,15 @@ return molecules } + public func replaceChildMolecule(with replacementMolecule: MoleculeModelProtocol) -> Bool { + guard let replacementMolecule = replacementMolecule as? StackItemModelProtocol & MoleculeModelProtocol else { return false } + guard let matchingIndex = molecules.firstIndex(where: { molecule in + molecule.id == replacementMolecule.id + }) else { return false } + molecules[matchingIndex] = replacementMolecule + return true + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift index 6845d44b..31adc6ef 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift @@ -5,10 +5,10 @@ public enum MolecularError: Swift.Error { case countImbalance(String) } - public protocol MoleculeModelProtocol: ModelProtocol, AccessibilityModelProtocol, MoleculeTreeTraversalProtocol, MoleculeMaskingProtocol { var moleculeName: String { get } var backgroundColor: Color? { get set } + var id: String { get } } public extension MoleculeModelProtocol { @@ -20,7 +20,6 @@ public extension MoleculeModelProtocol { static var categoryCodingKey: String { "moleculeName" } } - // Helpers made due to swift not able to reconcile which category. extension KeyedDecodingContainer where Key: CodingKey { /// Decodes to a registered molecule based on the identifier @@ -53,8 +52,9 @@ public extension MoleculeModelProtocol { } // Base case. No additional children to traverse. - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { - onVisit(depth, self) + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool)->Void) { + var stop = false + onVisit(depth, self, &stop) } } @@ -67,7 +67,7 @@ public extension Array where Element == MoleculeModelProtocol { } } - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) { forEach { (molecule) in molecule.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit) } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift index 2ec05db4..78377a25 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ParentMoleculeModelProtocol.swift @@ -8,10 +8,11 @@ import Foundation -public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol { +public protocol ParentMoleculeModelProtocol: MoleculeModelProtocol, AnyObject { var children: [MoleculeModelProtocol] { get } + func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool } public extension ParentMoleculeModelProtocol { @@ -35,21 +36,44 @@ public extension ParentMoleculeModelProtocol { return result } - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool)->Void) { + var stop = false if (options == .parentFirst) { - onVisit(depth, self) + onVisit(depth, self, &stop) + guard !stop else { return } } - children.forEach { (molecule) in - if let additionalParent = molecule as? ParentMoleculeModelProtocol { + for child in children { + if let additionalParent = child as? ParentMoleculeModelProtocol { // Safety net to make sure the ParentMoleculeModelProtocol's method extension is called over the base MoleculeModelProtocol. additionalParent.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit) } else { - molecule.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit) + child.depthFirstTraverse(options: options, depth: depth + 1, onVisit: onVisit) } + guard !stop else { return } } if (options == .childFirst) { - onVisit(depth, self) + onVisit(depth, self, &stop) } // if options == .leafOnly don't call on self. } + + /// Top level test to replace child molecules. Each parent molecule should attempt to replace. + func replaceChildMolecule(with molecule: MoleculeModelProtocol) -> Bool { return false } + + /// Helper function for replacing molecules on a path. + func replaceChildMolecule(on target: P, keyPath: ReferenceWritableKeyPath, replacementMolecule: MoleculeModelProtocol) -> Bool { + if let currentMolecule = target[keyPath: keyPath], currentMolecule.id == replacementMolecule.id, let newHeadline = replacementMolecule as? T { + target[keyPath: keyPath] = newHeadline + return true + } + return false + } + + func replaceChildMolecule(on target: P, keyPath: ReferenceWritableKeyPath, replacementMolecule: MoleculeModelProtocol) -> Bool { + if target[keyPath: keyPath].id == replacementMolecule.id, let newHeadline = replacementMolecule as? T { + target[keyPath: keyPath] = newHeadline + return true + } + return false + } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift index 531a48d1..2cd233b0 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift @@ -30,7 +30,7 @@ public extension TemplateModelProtocol { return rootMolecules.reduceDepthFirstTraverse(options: options, depth: depth, initialResult: initialResult, nextPartialResult: nextPartialResult) } - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol) -> Void) { + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool) -> Void) { return rootMolecules.depthFirstTraverse(options: options, depth: depth, onVisit: onVisit) } } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift index d10a2d19..a2da7cf4 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeTreeTraversalProtocol.swift @@ -19,7 +19,7 @@ public protocol MoleculeTreeTraversalProtocol { func reduceDepthFirstTraverse(options: TreeTraversalOptions, depth: Int, initialResult: Result, nextPartialResult: (Result, MoleculeModelProtocol, Int)->Result) -> Result - func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol)->Void) + func depthFirstTraverse(options: TreeTraversalOptions, depth: Int, onVisit: (Int, MoleculeModelProtocol, inout Bool)->Void) //func breadthFirstTraverse() } @@ -37,7 +37,7 @@ public extension MoleculeTreeTraversalProtocol { } func printMolecules(options: TreeTraversalOptions = .parentFirst) { - depthFirstTraverse(options: options, depth: 1) { (depth, molecule) in + depthFirstTraverse(options: options, depth: 1) { depth, molecule, stop in print("\(String(repeating: ">>", count: depth)) \"\(molecule.moleculeName)\" [\(molecule)]") } } @@ -50,4 +50,11 @@ public extension MoleculeTreeTraversalProtocol { return accumulator } } + + func replaceMolecule(with replacementMolecule: MoleculeModelProtocol) { + depthFirstTraverse(options: .parentFirst, depth: 0) { depth, molecule, stop in + guard let parentMolecule = molecule as? ParentMoleculeModelProtocol else { return } + stop = parentMolecule.replaceChildMolecule(with: replacementMolecule) + } + } } diff --git a/MVMCoreUI/Containers/Views/ContainerModel.swift b/MVMCoreUI/Containers/Views/ContainerModel.swift index 731e9c95..b54590dd 100644 --- a/MVMCoreUI/Containers/Views/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/ContainerModel.swift @@ -13,6 +13,8 @@ open class ContainerModel: ContainerModelProtocol, Codable { // MARK: - Properties //-------------------------------------------------- + public var id: String = UUID().uuidString + public var horizontalAlignment: UIStackView.Alignment? public var useHorizontalMargins: Bool? public var leftPadding: CGFloat? @@ -30,6 +32,7 @@ open class ContainerModel: ContainerModelProtocol, Codable { //-------------------------------------------------- private enum CodingKeys: String, CodingKey { + case id case horizontalAlignment case useHorizontalMargins case leftPadding @@ -74,6 +77,9 @@ open class ContainerModel: ContainerModelProtocol, Codable { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + + id = try typeContainer.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString + if let verticalAlignmentString = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment) { verticalAlignment = ContainerHelper.getAlignment(for: verticalAlignmentString) } @@ -92,6 +98,7 @@ open class ContainerModel: ContainerModelProtocol, Codable { open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: verticalAlignment), forKey: .verticalAlignment) try container.encodeIfPresent(ContainerHelper.getAlignmentString(for: horizontalAlignment), forKey: .horizontalAlignment) try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)