Skip to content

Commit 1c6c624

Browse files
authored
MAGETWO-80100: Technical improvements from community (MSI) #11003
2 parents 3882f29 + dea4e63 commit 1c6c624

File tree

19 files changed

+732
-35
lines changed

19 files changed

+732
-35
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Ui\Component\Control;
7+
8+
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
9+
use Magento\Ui\Component\Control\Container;
10+
11+
/**
12+
* Represents split-button with pre-configured options
13+
* Provide an ability to show drop-down list with options clicking on the "Save" button
14+
*
15+
* @api
16+
*/
17+
class SaveSplitButton implements ButtonProviderInterface
18+
{
19+
/**
20+
* @var string
21+
*/
22+
private $targetName;
23+
24+
/**
25+
* @param string $targetName
26+
*/
27+
public function __construct(string $targetName)
28+
{
29+
$this->targetName = $targetName;
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function getButtonData()
36+
{
37+
return [
38+
'label' => __('Save &amp; Continue'),
39+
'class' => 'save primary',
40+
'data_attribute' => [
41+
'mage-init' => [
42+
'buttonAdapter' => [
43+
'actions' => [
44+
[
45+
'targetName' => $this->targetName,
46+
'actionName' => 'save',
47+
'params' => [
48+
// first param is redirect flag
49+
false,
50+
]
51+
]
52+
]
53+
]
54+
]
55+
],
56+
'class_name' => Container::SPLIT_BUTTON,
57+
'options' => $this->getOptions(),
58+
'sort_order' => 40,
59+
];
60+
}
61+
62+
/**
63+
* @return array
64+
*/
65+
private function getOptions(): array
66+
{
67+
$options = [
68+
[
69+
'label' => __('Save &amp; Close'),
70+
'data_attribute' => [
71+
'mage-init' => [
72+
'buttonAdapter' => [
73+
'actions' => [
74+
[
75+
'targetName' => $this->targetName,
76+
'actionName' => 'save',
77+
'params' => [
78+
// first param is redirect flag
79+
true,
80+
],
81+
],
82+
],
83+
],
84+
],
85+
],
86+
'sort_order' => 10,
87+
],
88+
[
89+
'label' => __('Save &amp; New'),
90+
'data_attribute' => [
91+
'mage-init' => [
92+
'buttonAdapter' => [
93+
'actions' => [
94+
[
95+
'targetName' => $this->targetName,
96+
'actionName' => 'save',
97+
'params' => [
98+
// first param is redirect flag, second is data that will be added to post
99+
// request
100+
true,
101+
[
102+
'redirect_to_new' => 1,
103+
],
104+
],
105+
],
106+
],
107+
],
108+
],
109+
],
110+
'sort_order' => 20,
111+
],
112+
];
113+
return $options;
114+
}
115+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Backend\Ui\Component\Listing\Column;
7+
8+
use Magento\Framework\UrlInterface;
9+
use Magento\Framework\View\Element\UiComponent\ContextInterface;
10+
use Magento\Framework\View\Element\UiComponentFactory;
11+
use Magento\Ui\Component\Listing\Columns\Column;
12+
13+
/**
14+
* Represents Edit link in grid for entity by its identifier field
15+
*
16+
* @api
17+
*/
18+
class EditAction extends Column
19+
{
20+
/**
21+
* @var UrlInterface
22+
*/
23+
private $urlBuilder;
24+
25+
/**
26+
* @param ContextInterface $context
27+
* @param UiComponentFactory $uiComponentFactory
28+
* @param UrlInterface $urlBuilder
29+
* @param array $components
30+
* @param array $data
31+
*/
32+
public function __construct(
33+
ContextInterface $context,
34+
UiComponentFactory $uiComponentFactory,
35+
UrlInterface $urlBuilder,
36+
array $components = [],
37+
array $data = []
38+
) {
39+
$this->urlBuilder = $urlBuilder;
40+
parent::__construct($context, $uiComponentFactory, $components, $data);
41+
}
42+
43+
/**
44+
* @param array $dataSource
45+
* @return array
46+
*/
47+
public function prepareDataSource(array $dataSource)
48+
{
49+
if (isset($dataSource['data']['items'])) {
50+
foreach ($dataSource['data']['items'] as &$item) {
51+
if (isset($item[$item['id_field_name']])) {
52+
$editUrlPath = $this->getData('config/editUrlPath') ?: '#';
53+
$item[$this->getData('name')] = [
54+
'edit' => [
55+
'href' => $this->urlBuilder->getUrl($editUrlPath, [
56+
$item['id_field_name'] => $item[$item['id_field_name']],
57+
]),
58+
'label' => __('Edit')
59+
]
60+
];
61+
unset($item);
62+
}
63+
}
64+
}
65+
return $dataSource;
66+
}
67+
}

app/code/Magento/Backend/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"magento/module-translation": "100.3.*",
1919
"magento/module-require-js": "100.3.*",
2020
"magento/module-config": "100.3.*",
21+
"magento/module-ui": "100.3.*",
2122
"magento/framework": "100.3.*"
2223
},
2324
"suggest": {

app/code/Magento/Shipping/Model/Config.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace Magento\Shipping\Model;
1010

11+
use Magento\Shipping\Model\Carrier\AbstractCarrierInterface;
12+
1113
/**
1214
* Class Config
1315
* @api
@@ -59,7 +61,7 @@ public function __construct(
5961
* Retrieve active system carriers
6062
*
6163
* @param mixed $store
62-
* @return array
64+
* @return AbstractCarrierInterface[]
6365
*/
6466
public function getActiveCarriers($store = null)
6567
{
@@ -80,7 +82,7 @@ public function getActiveCarriers($store = null)
8082
* Retrieve all system carriers
8183
*
8284
* @param mixed $store
83-
* @return array
85+
* @return AbstractCarrierInterface[]
8486
*/
8587
public function getAllCarriers($store = null)
8688
{
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Ui\DataProvider;
7+
8+
use Magento\Framework\Api\AttributeValue;
9+
use Magento\Framework\Api\AttributeValueFactory;
10+
use Magento\Framework\Api\Search\DocumentFactory;
11+
use Magento\Framework\Api\Search\SearchResultInterface;
12+
use Magento\Framework\Api\SearchCriteriaInterface;
13+
use Magento\Framework\Api\Search\SearchResultFactory as BaseSearchResultFactory;
14+
use Magento\Framework\EntityManager\HydratorInterface;
15+
16+
/**
17+
* Allows to use Repositories (instead of Collections) in UI Components Data providers
18+
*
19+
* @api
20+
*/
21+
class SearchResultFactory
22+
{
23+
/**
24+
* @var HydratorInterface
25+
*/
26+
private $hydrator;
27+
28+
/**
29+
* @var DocumentFactory
30+
*/
31+
private $documentFactory;
32+
33+
/**
34+
* @var BaseSearchResultFactory
35+
*/
36+
private $searchResultFactory;
37+
38+
/**
39+
* @var AttributeValueFactory
40+
*/
41+
private $attributeValueFactory;
42+
43+
/**
44+
* @param HydratorInterface $hydrator
45+
* @param DocumentFactory $documentFactory
46+
* @param BaseSearchResultFactory $searchResultFactory
47+
* @param AttributeValueFactory $attributeValueFactory
48+
*/
49+
public function __construct(
50+
HydratorInterface $hydrator,
51+
DocumentFactory $documentFactory,
52+
BaseSearchResultFactory $searchResultFactory,
53+
AttributeValueFactory $attributeValueFactory
54+
) {
55+
$this->hydrator = $hydrator;
56+
$this->documentFactory = $documentFactory;
57+
$this->searchResultFactory = $searchResultFactory;
58+
$this->attributeValueFactory = $attributeValueFactory;
59+
}
60+
61+
/**
62+
* @param array $items
63+
* @param int $totalCount
64+
* @param SearchCriteriaInterface SearchCriteriaInterface $searchCriteria
65+
* @param string $idFieldName
66+
* @return SearchResultInterface
67+
*/
68+
public function create(
69+
array $items,
70+
$totalCount,
71+
SearchCriteriaInterface $searchCriteria,
72+
$idFieldName
73+
): SearchResultInterface {
74+
$documents = [];
75+
foreach ($items as $item) {
76+
$itemData = $this->hydrator->extract($item);
77+
$itemId = $itemData[$idFieldName];
78+
$attributes = $this->createAttributes($idFieldName, $itemData);
79+
80+
$document = $this->documentFactory->create();
81+
$document->setId($itemId);
82+
$document->setCustomAttributes($attributes);
83+
$documents[] = $document;
84+
}
85+
86+
$searchResult = $this->searchResultFactory->create();
87+
$searchResult->setItems($documents);
88+
$searchResult->setTotalCount($totalCount);
89+
$searchResult->setSearchCriteria($searchCriteria);
90+
return $searchResult;
91+
}
92+
93+
/**
94+
* @param string $idFieldName
95+
* @param array $itemData
96+
* @return AttributeValue[]
97+
*/
98+
private function createAttributes(string $idFieldName, array $itemData): array
99+
{
100+
$attributes = [];
101+
102+
$idFieldNameAttribute = $this->attributeValueFactory->create();
103+
$idFieldNameAttribute->setAttributeCode('id_field_name');
104+
$idFieldNameAttribute->setValue($idFieldName);
105+
$attributes['id_field_name'] = $idFieldNameAttribute;
106+
107+
foreach ($itemData as $key => $value) {
108+
$attribute = $this->attributeValueFactory->create();
109+
$attribute->setAttributeCode($key);
110+
if (is_bool($value)) {
111+
// for proper work of form and grid (for example for Yes/No properties)
112+
$value = (string)(int)$value;
113+
}
114+
$attribute->setValue($value);
115+
$attributes[$key] = $attribute;
116+
}
117+
return $attributes;
118+
}
119+
}

app/code/Magento/Ui/view/base/web/js/dynamic-rows/dynamic-rows-grid.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ define([
214214
return false;
215215
}
216216

217-
changes.each(function (changedObject) {
217+
changes.forEach(function (changedObject) {
218218
this.mappingValue(changedObject);
219219
}, this);
220220
}
@@ -266,7 +266,7 @@ define([
266266
changes = [],
267267
obj = {};
268268

269-
max.each(function (record, index) {
269+
max.forEach(function (record, index) {
270270
obj[this.map[this.identificationDRProperty]] = record[this.map[this.identificationDRProperty]];
271271

272272
if (!_.where(this.cacheGridData, obj).length) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\TestFramework\Assert;
7+
8+
use PHPUnit\Framework\Assert;
9+
10+
/**
11+
* Check that actual data contains all values from expected data
12+
* But actual data can have more values than expected data
13+
*/
14+
class AssertArrayContains
15+
{
16+
/**
17+
* @param array $expected
18+
* @param array $actual
19+
* @return void
20+
*/
21+
public static function assert(array $expected, array $actual)
22+
{
23+
foreach ($expected as $key => $value) {
24+
Assert::assertArrayHasKey(
25+
$key,
26+
$actual,
27+
"Expected value for key '{$key}' is missed"
28+
);
29+
if (is_array($value)) {
30+
self::assert($value, $actual[$key]);
31+
} else {
32+
Assert::assertEquals(
33+
$value,
34+
$actual[$key],
35+
"Expected value for key '{$key}' doesn't match"
36+
);
37+
}
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)