Merge branch 'develop' into feature/form_page

This commit is contained in:
Kevin G Christiano 2020-03-11 15:28:06 -04:00
commit 1ae91f55ae
16 changed files with 164 additions and 40 deletions

View File

@ -122,6 +122,8 @@
525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */; };
52B201D224081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */; };
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */; };
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */; };
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D084AD12410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift */; };
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */; };
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */; };
8D448E5524050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */; };
@ -484,6 +486,8 @@
525019E62406853600EED91C /* ListFourColumnDataUsageDivider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFourColumnDataUsageDivider.swift; sourceTree = "<group>"; };
52B201D024081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethod.swift; sourceTree = "<group>"; };
52B201D124081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListLeftVariableRadioButtonAndPaymentMethodModel.swift; sourceTree = "<group>"; };
8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyTextModel.swift; sourceTree = "<group>"; };
8D084AD12410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextBodyText.swift; sourceTree = "<group>"; };
8D24041023E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaret.swift; sourceTree = "<group>"; };
8D24041423E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretModel.swift; sourceTree = "<group>"; };
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListOneColumnFullWidthTextAllTextAndLinksModel.swift; sourceTree = "<group>"; };
@ -868,6 +872,8 @@
children = (
8D448E5424050A46006211BB /* ListOneColumnFullWidthTextAllTextAndLinksModel.swift */,
52267A0623FFE25000906CBA /* ListOneColumnFullWidthTextAllTextAndLinks.swift */,
8D084ACF2410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift */,
8D084AD12410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift */,
);
path = OneColumn;
sourceTree = "<group>";
@ -1844,6 +1850,7 @@
94C2D9AB23872EB50006CF46 /* LabelAttributeActionModel.swift in Sources */,
52B201D324081CFB00D2011E /* ListLeftVariableRadioButtonAndPaymentMethodModel.swift in Sources */,
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */,
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */,
014AA73123C5059B006F3E93 /* ListPageTemplateModel.swift in Sources */,
017BEB4023620A230024EF95 /* TextFieldModel.swift in Sources */,
D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */,
@ -1951,6 +1958,7 @@
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
522679C223FE886900906CBA /* ListLeftVariableCheckboxAllTextAndLinksModel.swift in Sources */,
8D084AD02410BF4800951227 /* ListOneColumnFullWidthTextBodyTextModel.swift in Sources */,
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */,
8D24041123E7FB9E009E23BE /* ListLeftVariableIconWithRightCaret.swift in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,

View File

@ -81,7 +81,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
return NSRange(location: 0, length: frontText?.count ?? 0)
}
private var actionRange: NSRange {
public var actionRange: NSRange {
return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0)
}

View File

@ -8,14 +8,22 @@
import UIKit
@objcMembers public class LeftRightLabelModel: MoleculeModelProtocol {
@objcMembers open class LeftRightLabelModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "leftRightLabelView"
public var moleculeName: String? = LeftRightLabelModel.identifier
public var backgroundColor: Color?
public var leftText: LabelModel
public var rightText: LabelModel?
init(_ leftText: LabelModel) {
//--------------------------------------------------
// MARK: - Initializer
//--------------------------------------------------
public init(_ leftText: LabelModel) {
self.leftText = leftText
}
}

View File

@ -120,7 +120,7 @@ import UIKit
}
// MARK: - MFViewProtocol
public func updateView(_ size: CGFloat) {
open func updateView(_ size: CGFloat) {
containerHelper.updateViewMargins(self, model: listItemModel, size: size)
if accessoryView != nil {
@ -151,7 +151,7 @@ import UIKit
}
//TODO: ModelProtocol, Change to model
public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
open func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? ListItemModelProtocol else { return }
self.listItemModel = model
@ -176,6 +176,9 @@ import UIKit
let backgroundColor = moleculeModel.backgroundColor {
self.backgroundColor = backgroundColor.uiColor
}
// align if needed.
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)
}
open func reset() {
@ -183,11 +186,11 @@ import UIKit
backgroundColor = .white
}
public class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
return model.moleculeName
}
public class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return nil
}

View File

@ -31,9 +31,10 @@ extension MFViewController: MoleculeDelegateProtocol {
return nil
}
@objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) { }
// These are required because swift will call the extension function otherwise.
@objc public func moleculeLayoutUpdated(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {}
@objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
@objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) { }
@objc public func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {}
@objc public func addMolecules(_ molecules: [[AnyHashable : Any]], indexPath: IndexPath, animation: UITableView.RowAnimation) {}
@objc public func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {}
}

View File

@ -23,15 +23,15 @@ open class Container: View, ContainerProtocol {
}
// MARK:- ContainerProtocol
public func alignHorizontal(_ alignment: UIStackView.Alignment) {
open func alignHorizontal(_ alignment: UIStackView.Alignment) {
containerHelper.alignHorizontal(alignment)
}
public func alignVertical(_ alignment: UIStackView.Alignment) {
open func alignVertical(_ alignment: UIStackView.Alignment) {
containerHelper.alignVertical(alignment)
}
public func constrainView(_ view: UIView) {
open func constrainView(_ view: UIView) {
containerHelper.constrainView(view)
}
}

View File

@ -9,7 +9,7 @@
import Foundation
public class ContainerHelper: NSObject {
open class ContainerHelper: NSObject {
var leftConstraint: NSLayoutConstraint?
var topConstraint: NSLayoutConstraint?
var bottomConstraint: NSLayoutConstraint?
@ -28,7 +28,7 @@ public class ContainerHelper: NSObject {
var bottomLowConstraint: NSLayoutConstraint?
var rightLowConstraint: NSLayoutConstraint?
func constrainView(_ view: UIView) {
open func constrainView(_ view: UIView) {
guard let margins = view.superview?.layoutMarginsGuide else { return }
leftConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor)
leftConstraint?.isActive = true
@ -69,7 +69,7 @@ public class ContainerHelper: NSObject {
setAccessibility(view)
}
func setAccessibility(_ view: UIView) {
open func setAccessibility(_ view: UIView) {
guard let superView = view.superview else { return }
superView.isAccessibilityElement = false
if let elements = view.accessibilityElements {
@ -79,7 +79,7 @@ public class ContainerHelper: NSObject {
}
}
func alignHorizontal(_ alignment: UIStackView.Alignment) {
open func alignHorizontal(_ alignment: UIStackView.Alignment) {
switch alignment {
case .center:
alignCenterHorizontalConstraint?.isActive = true
@ -109,7 +109,7 @@ public class ContainerHelper: NSObject {
}
}
func alignVertical(_ alignment: UIStackView.Alignment) {
open func alignVertical(_ alignment: UIStackView.Alignment) {
switch alignment {
case .center:
alignCenterVerticalConstraint?.isActive = true
@ -139,7 +139,7 @@ public class ContainerHelper: NSObject {
}
}
static func getAlignment(for string: String) -> UIStackView.Alignment? {
public static func getAlignment(for string: String) -> UIStackView.Alignment? {
switch string {
case "leading":
return .leading
@ -154,7 +154,7 @@ public class ContainerHelper: NSObject {
}
}
static func getAlignmentString(for alignment: UIStackView.Alignment?) -> String? {
public static func getAlignmentString(for alignment: UIStackView.Alignment?) -> String? {
switch alignment {
case .leading:
return "leading"
@ -169,11 +169,11 @@ public class ContainerHelper: NSObject {
}
}
func updateViewMargins(_ view: UIView, model: ContainerModelProtocol?, size: CGFloat) {
open func updateViewMargins(_ view: UIView, model: ContainerModelProtocol?, size: CGFloat) {
MFStyler.setMarginsFor(view, size: size, defaultHorizontal: model?.useHorizontalMargins ?? false, top: (model?.useVerticalMargins ?? false) ? (model?.topMarginPadding ?? 0) : 0, bottom: (model?.useVerticalMargins ?? false) ? (model?.bottomMarginPadding ?? 0) : 0)
}
func set(with model: ContainerModelProtocol, for contained: MVMCoreUIViewConstrainingProtocol?) {
open func set(with model: ContainerModelProtocol, for contained: MVMCoreUIViewConstrainingProtocol?) {
if let horizontalAlignment = model.horizontalAlignment ?? contained?.horizontalAlignment?() {
alignHorizontal(horizontalAlignment)
}
@ -182,7 +182,7 @@ public class ContainerHelper: NSObject {
}
}
func set(with JSON: [AnyHashable: Any]?, for contained: UIView) {
open func set(with JSON: [AnyHashable: Any]?, for contained: UIView) {
if let horizontalAlignmentString = JSON?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {
alignHorizontal(alignment)
} else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {

View File

@ -0,0 +1,35 @@
//
// ListOneColumnFullWidthTextBodyText.swift
// MVMCoreUI
//
// Created by Kruthika KP on 05/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
@objcMembers open class ListOneColumnFullWidthTextBodyText: TableViewCell {
//-----------------------------------------------------
// MARK: - Outlets
//-----------------------------------------------------
public var headlineBody = HeadlineBody(frame: .zero)
//-----------------------------------------------------
// MARK: - View Lifecycle
//-----------------------------------------------------
override open func setupView() {
super.setupView()
addMolecule(headlineBody)
}
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?){
super.set(with: model, delegateObject, additionalData)
guard let model = model as? ListOneColumnFullWidthTextBodyTextModel else { return }
headlineBody.set(with: model.headlineBody, delegateObject, additionalData)
}
open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
return 90
}
}

View File

@ -0,0 +1,43 @@
//
// ListOneColumnFullWidthTextBodyTextModel.swift
// MVMCoreUI
//
// Created by Kruthika KP on 05/03/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class ListOneColumnFullWidthTextBodyTextModel: ListItemModel, MoleculeModelProtocol {
public static var identifier: String = "list1CFWBdy"
public var headlineBody: HeadlineBodyModel
public init(headlineBody: HeadlineBodyModel) {
self.headlineBody = headlineBody
super.init()
}
// Defaults to set
override public func setDefaults() {
super.setDefaults()
headlineBody.style = "item"
}
private enum CodingKeys: String, CodingKey {
case moleculeName
case headlineBody
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
headlineBody = try typeContainer.decode(HeadlineBodyModel.self, forKey: .headlineBody)
try super.init(from: decoder)
}
public override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(headlineBody, forKey: .headlineBody)
}
}

View File

@ -14,4 +14,9 @@ public struct ImageHeadlineBodyModel: MoleculeModelProtocol {
public var backgroundColor: Color?
public var image: ImageViewModel
public var headlineBody: HeadlineBodyModel
public init(image: ImageViewModel, headlineBody: HeadlineBodyModel) {
self.image = image
self.headlineBody = headlineBody
}
}

View File

@ -109,7 +109,9 @@ import UIKit
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? TwoButtonViewModel else { return }
if let secondaryModel = model.secondaryButton {
showSecondaryButton()
secondaryButton.set(with: secondaryModel, delegateObject, additionalData)

View File

@ -14,18 +14,18 @@ import UIKit
// MARK: - MVMCoreUIMoleculeViewProtocol
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? MoleculeListItemModel else { return }
if molecule != nil {
(molecule as? ModelMoleculeViewProtocol)?.set(with: model.molecule, delegateObject, additionalData)
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject, false) {
addMolecule(moleculeView)
guard let castModel = model as? MoleculeListItemModel else {
super.set(with: model, delegateObject, additionalData)
return
}
containerHelper.set(with: model, for: molecule as? MVMCoreUIViewConstrainingProtocol)
if molecule != nil {
(molecule as? ModelMoleculeViewProtocol)?.set(with: castModel.molecule, delegateObject, additionalData)
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(castModel.molecule, delegateObject, false) {
addMolecule(moleculeView)
}
super.set(with: model, delegateObject, additionalData)
}
public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {

View File

@ -8,7 +8,7 @@
import Foundation
@objcMembers public class HeadlineBodyModel: MoleculeModelProtocol {
@objcMembers open class HeadlineBodyModel: MoleculeModelProtocol {
public static var identifier: String = "headlineBody"
public var moleculeName: String? = HeadlineBodyModel.identifier
public var headline: LabelModel?
@ -19,4 +19,8 @@ import Foundation
public init(headline: LabelModel) {
self.headline = headline
}
public init(body: LabelModel) {
self.body = body
}
}

View File

@ -20,6 +20,8 @@ public protocol MoleculeDelegateProtocol {
/// Asks the delegate to add or remove molecules.
//optional
func addMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation)
func addMolecules(_ molecules: [[AnyHashable : Any]], indexPath: IndexPath, animation: UITableView.RowAnimation)
func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation)
//optional
@ -36,6 +38,10 @@ extension MoleculeDelegateProtocol {
// Do nothing
}
public func addMolecules(_ molecules: [[AnyHashable : Any]], indexPath: IndexPath, animation: UITableView.RowAnimation) {
// Do nothing
}
public func removeMolecules(_ molecules: [[AnyHashable : Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
// Do nothing
}

View File

@ -106,6 +106,7 @@ import Foundation
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListLeftVariableRadioButtonAndPaymentMethod.self, viewModelClass: ListLeftVariableRadioButtonAndPaymentMethodModel.self)
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListRVWheel.self, viewModelClass: ListRVWheelModel.self)
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListOneColumnFullWidthTextAllTextAndLinks.self, viewModelClass: ListOneColumnFullWidthTextAllTextAndLinksModel.self)
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListOneColumnFullWidthTextBodyText.self, viewModelClass: ListOneColumnFullWidthTextBodyTextModel.self)
// Designed Section Dividers
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ListFourColumnDataUsageDivider.self, viewModelClass: ListFourColumnDataUsageDividerModel.self)

View File

@ -183,8 +183,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
}
}
public override func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
open override func addMolecules(_ molecules: [[AnyHashable : Any]], indexPath: IndexPath, animation: UITableView.RowAnimation) {
var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]()
molecules.forEach { molecule in
@ -194,7 +193,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
}
DispatchQueue.main.async {
guard let indexPath = self.tableView?.indexPath(for: sender) else { return }
var indexPaths: [IndexPath] = []
for molecule in tmpMolecules {
@ -212,7 +210,17 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
}
}
public override func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
open override func addMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
DispatchQueue.main.async { [weak self] in
guard let indexPath = self?.tableView?.indexPath(for: sender) else { return }
DispatchQueue.global().async {
self?.addMolecules(molecules, indexPath: indexPath, animation: animation)
}
}
}
open override func removeMolecules(_ molecules: [[AnyHashable: Any]], sender: UITableViewCell, animation: UITableView.RowAnimation) {
var tmpMolecules = [ListItemModelProtocol & MoleculeModelProtocol]()
@ -240,7 +248,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
view.layoutIfNeeded()
}
public func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
open func addMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
// This dispatch is needed to fix a race condition that can occur if this function is called during the table setup.
DispatchQueue.main.async {
@ -262,7 +270,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol
}
}
public func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
open func removeMolecules(_ molecules: [ListItemModelProtocol & MoleculeModelProtocol], sender: UITableViewCell, animation: UITableView.RowAnimation) {
var indexPaths: [IndexPath] = []
//TODO: cehck for molecule protocola eqality