Skip to content

Commit 48844b5

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-58251' into MPI-PR-PayPal
2 parents 7ef0730 + 84a36b5 commit 48844b5

File tree

8 files changed

+222
-54
lines changed

8 files changed

+222
-54
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright © 2016 Magento. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'uiElement',
8+
'mage/translate'
9+
], function (Element, $t) {
10+
'use strict';
11+
12+
var DEFAULT_GROUP_ALIAS = 'default';
13+
14+
return Element.extend({
15+
defaults: {
16+
alias: DEFAULT_GROUP_ALIAS,
17+
title: $t('Payment Method'),
18+
sortOrder: 100,
19+
displayArea: 'payment-methods-items-${ $.alias }'
20+
},
21+
22+
/**
23+
* Checks if group instance is default
24+
*
25+
* @returns {Boolean}
26+
*/
27+
isDefault: function () {
28+
return this.alias === DEFAULT_GROUP_ALIAS;
29+
}
30+
});
31+
});

app/code/Magento/Checkout/view/frontend/web/js/view/payment/list.js

Lines changed: 113 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,22 @@ define([
1010
'Magento_Checkout/js/model/payment/method-list',
1111
'Magento_Checkout/js/model/payment/renderer-list',
1212
'uiLayout',
13-
'Magento_Checkout/js/model/checkout-data-resolver'
14-
], function (_, ko, utils, Component, paymentMethods, rendererList, layout, checkoutDataResolver) {
13+
'Magento_Checkout/js/model/checkout-data-resolver',
14+
'mage/translate',
15+
'uiRegistry'
16+
], function (_, ko, utils, Component, paymentMethods, rendererList, layout, checkoutDataResolver, $t, registry) {
1517
'use strict';
1618

1719
return Component.extend({
1820
defaults: {
1921
template: 'Magento_Checkout/payment-methods/list',
20-
visible: paymentMethods().length > 0
22+
visible: paymentMethods().length > 0,
23+
configDefaultGroup: {
24+
name: 'methodGroup',
25+
component: 'Magento_Checkout/js/model/payment/method-group'
26+
},
27+
paymentGroupsList: [],
28+
defaultGroupTitle: $t('Select a new payment method')
2129
},
2230

2331
/**
@@ -26,7 +34,7 @@ define([
2634
* @returns {Component} Chainable.
2735
*/
2836
initialize: function () {
29-
this._super().initChildren();
37+
this._super().initDefaulGroup().initChildren();
3038
paymentMethods.subscribe(
3139
function (changes) {
3240
checkoutDataResolver.resolvePaymentMethod();
@@ -47,6 +55,27 @@ define([
4755
return this;
4856
},
4957

58+
/** @inheritdoc */
59+
initObservable: function () {
60+
this._super().
61+
observe(['paymentGroupsList']);
62+
63+
return this;
64+
},
65+
66+
/**
67+
* Creates default group
68+
*
69+
* @returns {Component} Chainable.
70+
*/
71+
initDefaulGroup: function() {
72+
layout([
73+
this.configDefaultGroup
74+
]);
75+
76+
return this;
77+
},
78+
5079
/**
5180
* Create renders for child payment methods.
5281
*
@@ -77,7 +106,7 @@ define([
77106
rendererTemplate = {
78107
parent: '${ $.$data.parentName }',
79108
name: '${ $.$data.name }',
80-
displayArea: 'payment-method-items',
109+
displayArea: payment.displayArea,
81110
component: payment.component
82111
};
83112
rendererComponent = utils.template(rendererTemplate, templateData);
@@ -95,49 +124,105 @@ define([
95124
* @param {Object} paymentMethodData
96125
*/
97126
createRenderer: function (paymentMethodData) {
98-
var isRendererForMethod = false;
127+
var isRendererForMethod = false,
128+
currentGroup;
129+
130+
registry.get(this.configDefaultGroup.name, function (defaultGroup) {
131+
_.each(rendererList(), function (renderer) {
99132

100-
_.find(rendererList(), function (renderer) {
133+
if (renderer.hasOwnProperty('typeComparatorCallback') &&
134+
typeof renderer.typeComparatorCallback == 'function'
135+
) {
136+
isRendererForMethod = renderer.typeComparatorCallback(renderer.type, paymentMethodData.method);
137+
} else {
138+
isRendererForMethod = renderer.type === paymentMethodData.method;
139+
}
101140

102-
if (renderer.hasOwnProperty('typeComparatorCallback') &&
103-
typeof renderer.typeComparatorCallback == 'function'
104-
) {
105-
isRendererForMethod = renderer.typeComparatorCallback(renderer.type, paymentMethodData.method);
106-
} else {
107-
isRendererForMethod = renderer.type === paymentMethodData.method;
108-
}
141+
if (isRendererForMethod) {
142+
currentGroup = renderer.group ? renderer.group : defaultGroup;
109143

110-
if (isRendererForMethod) {
111-
layout(
112-
[
144+
this.collectPaymentGroups(currentGroup);
145+
146+
layout([
113147
this.createComponent(
114148
{
115149
config: renderer.config,
116150
component: renderer.component,
117151
name: renderer.type,
118152
method: paymentMethodData.method,
119-
item: paymentMethodData
153+
item: paymentMethodData,
154+
displayArea: currentGroup.displayArea
120155
}
121-
)
122-
]
123-
);
124-
}
156+
)]);
157+
}
158+
}.bind(this));
125159
}.bind(this));
126160
},
127161

162+
/**
163+
* Collects unique groups of available payment methods
164+
*
165+
* @param {Object} group
166+
*/
167+
collectPaymentGroups: function (group) {
168+
var groupsList = this.paymentGroupsList(),
169+
isGroupExists = _.some(groupsList, function (existsGroup) {
170+
return existsGroup.alias === group.alias;
171+
});
172+
173+
if (!isGroupExists) {
174+
groupsList.push(group);
175+
groupsList = _.sortBy(groupsList, function (existsGroup) {
176+
return existsGroup.sortOrder;
177+
});
178+
this.paymentGroupsList(groupsList);
179+
}
180+
},
181+
182+
/**
183+
* Returns payment group title
184+
*
185+
* @param {Object} group
186+
* @returns {String}
187+
*/
188+
getGroupTitle: function (group) {
189+
var title = group().title;
190+
191+
if (group().isDefault() && this.paymentGroupsList().length > 1) {
192+
title = this.defaultGroupTitle;
193+
}
194+
195+
return title + ':';
196+
},
197+
198+
/**
199+
* Checks if at least one payment method available
200+
*
201+
* @returns {String}
202+
*/
203+
isPaymentMethodsAvailable: function () {
204+
return _.some(this.paymentGroupsList(), function (group) {
205+
return this.getRegion(group.displayArea)().length;
206+
}, this);
207+
},
208+
128209
/**
129210
* Remove view renderer.
130211
*
131212
* @param {String} paymentMethodCode
132213
*/
133214
removeRenderer: function (paymentMethodCode) {
134-
var items = this.getRegion('payment-method-items');
215+
var items;
216+
217+
_.each(this.paymentGroupsList(), function (group) {
218+
items = this.getRegion(group.displayArea);
135219

136-
_.find(items(), function (value) {
137-
if (value.item.method.indexOf(paymentMethodCode) === 0) {
138-
value.disposeSubscriptions();
139-
value.destroy();
140-
}
220+
_.find(items(), function (value) {
221+
if (value.item.method.indexOf(paymentMethodCode) === 0) {
222+
value.disposeSubscriptions();
223+
value.destroy();
224+
}
225+
});
141226
}, this);
142227
}
143228
});

app/code/Magento/Checkout/view/frontend/web/template/payment-methods/list.html

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@
44
* See COPYING.txt for license details.
55
*/
66
-->
7-
<div class="items payment-methods">
8-
<!-- ko foreach: { data: getRegion('payment-method-items'), as: 'element'} -->
9-
<!-- ko template: element.getTemplate() --><!-- /ko -->
10-
<!-- /ko -->
7+
<div if="isPaymentMethodsAvailable()"
8+
class="items payment-methods">
9+
<div repeat="foreach: paymentGroupsList, item: '$group'"
10+
class="payment-group">
11+
<div if="getRegion($group().displayArea)().length"
12+
translate="getGroupTitle($group)"
13+
class="step-title"
14+
data-role="title">
15+
</div>
16+
<each args="data: getRegion($group().displayArea), as: 'method'" render=""/>
17+
</div>
18+
</div>
19+
<div ifnot="isPaymentMethodsAvailable()"
20+
class="no-payments-block"
21+
translate="'No Payment Methods'">
1122
</div>
12-
<!-- ko ifnot: getRegion('payment-method-items')().length > 0 --><div class="no-payments-block"><!-- ko i18n: 'No Payment Methods'--><!-- /ko --></div><!-- /ko -->

app/code/Magento/Checkout/view/frontend/web/template/payment.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
-->
77
<li id="payment" role="presentation" class="checkout-payment-method" data-bind="fadeVisible: isVisible">
8-
<div class="step-title" data-bind="i18n: title" data-role="title"></div>
98
<div id="checkout-step-payment"
109
class="step-content"
1110
data-role="content"

app/code/Magento/Ui/view/base/web/js/lib/core/collection.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ define([
268268

269269
_.each(grouped, this.updateRegion, this);
270270

271+
_.each(this.regions, function (items) {
272+
var hasObsoleteComponents = items().length && !_.intersection(_elems, items()).length;
273+
274+
if (hasObsoleteComponents) {
275+
items.removeAll();
276+
}
277+
});
278+
271279
this.elems(_elems);
272280

273281
return this;

app/code/Magento/Vault/view/frontend/web/js/view/payment/vault.js

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,32 @@
44
*/
55
/*browser:true*/
66
/*global define*/
7-
define(
8-
[
9-
'underscore',
10-
'uiComponent',
11-
'Magento_Checkout/js/model/payment/renderer-list'
12-
],
13-
function (
14-
_,
15-
Component,
16-
rendererList
17-
) {
18-
'use strict';
7+
define([
8+
'underscore',
9+
'uiComponent',
10+
'Magento_Checkout/js/model/payment/renderer-list',
11+
'uiLayout',
12+
'uiRegistry'
13+
], function (_, Component, rendererList, layout, registry) {
14+
'use strict';
1915

16+
var vaultGroupName = 'vaultGroup';
17+
18+
layout([{
19+
name: vaultGroupName,
20+
component: 'Magento_Checkout/js/model/payment/method-group',
21+
alias: 'vault',
22+
sortOrder: 10
23+
}]);
24+
25+
registry.get(vaultGroupName, function (vaultGroup) {
2026
_.each(window.checkoutConfig.payment.vault, function (config, index) {
2127
rendererList.push(
2228
{
2329
type: index,
2430
config: config.config,
2531
component: config.component,
32+
group: vaultGroup,
2633

2734
/**
2835
* Custom payment method types comparator
@@ -37,10 +44,10 @@ define(
3744
}
3845
);
3946
});
47+
});
4048

41-
/**
42-
* Add view logic here if needed
43-
*/
44-
return Component.extend({});
45-
}
46-
);
49+
/**
50+
* Add view logic here if needed
51+
*/
52+
return Component.extend({});
53+
});

app/design/frontend/Magento/blank/Magento_Checkout/web/css/source/module/checkout/_payments.less

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
& when (@media-common = true) {
2525
.checkout-payment-method {
2626
.step-title {
27+
border-bottom: 0;
2728
margin-bottom: 0;
2829
}
2930

@@ -39,6 +40,12 @@
3940
display: block;
4041
}
4142
}
43+
44+
& + .payment-method {
45+
.payment-method-title {
46+
.lib-css(border-top, @checkout-payment-method-title__border);
47+
}
48+
}
4249
}
4350

4451
.payment-method-content {
@@ -54,7 +61,6 @@
5461
}
5562

5663
.payment-method-title {
57-
.lib-css(border-top, @checkout-payment-method-title__border);
5864
.lib-css(padding, @checkout-payment-method-title__padding 0);
5965
margin: 0;
6066

@@ -80,6 +86,14 @@
8086
}
8187
}
8288

89+
.payment-group {
90+
& + .payment-group {
91+
.step-title {
92+
margin: @indent__base 0 0;
93+
}
94+
}
95+
}
96+
8397
.field-select-billing,
8498
.billing-address-form {
8599
.lib-css(max-width, @checkout-billing-address-form__max-width);

0 commit comments

Comments
 (0)