Skip to content

Commit 52fdb4a

Browse files
committed
Merge pull request #236 from magento-tango/MAGETWO-46357
[Tango] UI Components improvements
2 parents b5bfc54 + 997962b commit 52fdb4a

File tree

12 files changed

+394
-80
lines changed

12 files changed

+394
-80
lines changed

app/code/Magento/Ui/Component/AbstractComponent.php

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
namespace Magento\Ui\Component;
77

88
use Magento\Framework\DataObject;
9+
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Framework\View\Element\UiComponentFactory;
911
use Magento\Framework\View\Element\UiComponentInterface;
1012
use Magento\Framework\View\Element\UiComponent\ContextInterface;
1113
use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
@@ -85,19 +87,92 @@ public function getName()
8587
*/
8688
public function prepare()
8789
{
90+
if ($this->getData(UiComponentFactory::IMPORT_CHILDREN_FROM_META)) {
91+
$children = (array)$this->getContext()->getDataProvider()->getMeta();
92+
foreach ($children as $name => $childData) {
93+
$this->createChildComponent($name, $childData);
94+
}
95+
}
96+
8897
$jsConfig = $this->getJsConfig($this);
8998
if (isset($jsConfig['provider'])) {
9099
unset($jsConfig['extends']);
91100
$this->getContext()->addComponentDefinition($this->getName(), $jsConfig);
92101
} else {
93102
$this->getContext()->addComponentDefinition($this->getComponentName(), $jsConfig);
94103
}
104+
105+
if ($this->hasData('actions')) {
106+
$this->getContext()->addActions($this->getData('actions'), $this);
107+
}
108+
95109
if ($this->hasData('buttons')) {
96110
$this->getContext()->addButtons($this->getData('buttons'), $this);
97111
}
98112
$this->getContext()->getProcessor()->notify($this->getComponentName());
99113
}
100114

115+
/**
116+
* Create child Ui Component
117+
*
118+
* @param string $name
119+
* @param array $childData
120+
* @return $this
121+
* @throws \Magento\Framework\Exception\LocalizedException
122+
*/
123+
protected function createChildComponent($name, array $childData)
124+
{
125+
if (empty($childData)) {
126+
return $this;
127+
}
128+
129+
$childComponent = $this->getComponent($name);
130+
if ($childComponent === null) {
131+
$argument = [
132+
'context' => $this->getContext(),
133+
'data' => [
134+
'name' => $name,
135+
'config' => $childData
136+
]
137+
];
138+
139+
if (!isset($childData['componentType'])) {
140+
throw new LocalizedException(
141+
__('The configuration parameter "componentType" is a required for "%1" component.', $name)
142+
);
143+
}
144+
145+
$childComponent = $this->getContext()
146+
->getUiComponentFactory()
147+
->create($name, $childData['componentType'], $argument);
148+
$this->prepareChildComponent($childComponent);
149+
$this->addComponent($name, $childComponent);
150+
} else {
151+
$this->updateComponent($childData, $childComponent);
152+
}
153+
154+
return $this;
155+
}
156+
157+
/**
158+
* Call prepare method in the component UI
159+
*
160+
* @param UiComponentInterface $component
161+
* @return $this
162+
*/
163+
protected function prepareChildComponent(UiComponentInterface $component)
164+
{
165+
$childComponents = $component->getChildComponents();
166+
if (!empty($childComponents)) {
167+
foreach ($childComponents as $child) {
168+
$this->prepareChildComponent($child);
169+
}
170+
}
171+
$component->prepare();
172+
173+
return $this;
174+
}
175+
101176
/**
102177
* Produce and return block's html output
103178
*
@@ -182,7 +257,7 @@ public function getTemplate()
182257
*/
183258
public function getConfiguration()
184259
{
185-
return (array) $this->getData('config');
260+
return (array)$this->getData('config');
186261
}
187262

188263
/**
@@ -194,7 +269,7 @@ public function getConfiguration()
194269
*/
195270
public function getJsConfig(UiComponentInterface $component)
196271
{
197-
$jsConfig = (array) $component->getData('js_config');
272+
$jsConfig = (array)$component->getData('js_config');
198273
if (!isset($jsConfig['extends'])) {
199274
$jsConfig['extends'] = $component->getContext()->getNamespace();
200275
}
@@ -264,4 +339,36 @@ protected function initObservers(array & $data = [])
264339
}
265340
}
266341
}
342+
343+
/**
344+
* Update component data
345+
*
346+
* @param array $componentData
347+
* @param UiComponentInterface $component
348+
* @return $this
349+
*/
350+
protected function updateComponent(array $componentData, UiComponentInterface $component)
351+
{
352+
$config = $component->getData('config');
353+
// XML data configuration override configuration coming from the DB
354+
$config = array_replace_recursive($componentData, $config);
355+
$component->setData('config', $config);
356+
357+
return $this;
358+
}
359+
360+
/**
361+
* Update DataScope
362+
*
363+
* @param array $data
364+
* @param string $name
365+
* @return array
366+
*/
367+
protected function updateDataScope(array $data, $name)
368+
{
369+
if (!isset($data['dataScope'])) {
370+
$data['dataScope'] = $name;
371+
}
372+
return $data;
373+
}
267374
}

app/code/Magento/Ui/Component/Form/Field.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,12 @@ public function prepare()
8787
(array) $this->getData('config')
8888
)
8989
);
90-
$this->wrappedComponent->prepare();
90+
91+
foreach ($this->components as $nameComponent => $component) {
92+
$this->wrappedComponent->addComponent($nameComponent, $component);
93+
}
94+
$this->prepareChildComponent($this->wrappedComponent);
95+
9196
$this->components = $this->wrappedComponent->getChildComponents();
9297
// Merge JS configuration with wrapped component configuration
9398
$wrappedComponentConfig = $this->getJsConfig($this->wrappedComponent);

app/code/Magento/Ui/Component/Layout/Tabs.php

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Magento\Framework\View\Element\UiComponentFactory;
1212
use Magento\Framework\View\Element\UiComponentInterface;
1313
use Magento\Framework\View\Element\UiComponent\LayoutInterface;
14+
use Magento\Framework\View\Element\UiComponent\BlockWrapperInterface;
1415

1516
/**
1617
* Class Tabs
@@ -22,16 +23,6 @@ class Tabs extends \Magento\Framework\View\Layout\Generic implements LayoutInter
2223
*/
2324
protected $navContainerName;
2425

25-
/**
26-
* @var UiComponentInterface
27-
*/
28-
protected $component;
29-
30-
/**
31-
* @var string
32-
*/
33-
protected $namespace;
34-
3526
/**
3627
* @var array
3728
*/
@@ -42,21 +33,17 @@ class Tabs extends \Magento\Framework\View\Layout\Generic implements LayoutInter
4233
*/
4334
protected $sortIncrement = 10;
4435

45-
/**
46-
* @var UiComponentFactory
47-
*/
48-
protected $uiComponentFactory;
49-
5036
/**
5137
* Constructor
5238
*
5339
* @param UiComponentFactory $uiComponentFactory
5440
* @param null|string $navContainerName
41+
* @param array $data
5542
*/
56-
public function __construct(UiComponentFactory $uiComponentFactory, $navContainerName = null)
43+
public function __construct(UiComponentFactory $uiComponentFactory, $navContainerName = null, $data = [])
5744
{
5845
$this->navContainerName = $navContainerName;
59-
$this->uiComponentFactory = $uiComponentFactory;
46+
parent::__construct($uiComponentFactory, $data);
6047
}
6148

6249
/**
@@ -72,15 +59,6 @@ public function build(UiComponentInterface $component)
7259

7360
$this->addNavigationBlock();
7461

75-
// Register html content element
76-
$this->component->getContext()->addComponentDefinition(
77-
'html_content',
78-
[
79-
'component' => 'Magento_Ui/js/form/components/html',
80-
'extends' => $this->namespace
81-
]
82-
);
83-
8462
// Initialization of structure components
8563
$this->initSections();
8664
$this->initAreas();
@@ -185,11 +163,11 @@ protected function addChildren(array &$topNode, UiComponentInterface $component,
185163
/**
186164
* Add wrapped layout block
187165
*
188-
* @param \Magento\Ui\Component\Wrapper\Block $childComponent
166+
* @param BlockWrapperInterface $childComponent
189167
* @param array $areas
190168
* @return void
191169
*/
192-
protected function addWrappedBlock(\Magento\Ui\Component\Wrapper\Block $childComponent, array &$areas)
170+
protected function addWrappedBlock(BlockWrapperInterface $childComponent, array &$areas)
193171
{
194172
$name = $childComponent->getName();
195173
/** @var TabInterface $block */

app/code/Magento/Ui/Component/Wrapper/Block.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
use Magento\Framework\View\Element\BlockInterface;
99
use Magento\Framework\View\Element\UiComponent\ContextInterface;
1010
use Magento\Ui\Component\AbstractComponent;
11+
use Magento\Framework\View\Element\UiComponent\BlockWrapperInterface;
1112

1213
/**
1314
* Class Block
1415
*/
15-
class Block extends AbstractComponent
16+
class Block extends AbstractComponent implements BlockWrapperInterface
1617
{
1718
const NAME = 'blockWrapper';
1819

@@ -66,4 +67,15 @@ public function render()
6667
{
6768
return $this->block->toHtml();
6869
}
70+
71+
/**
72+
* {@inheritdoc}
73+
*/
74+
public function getConfiguration()
75+
{
76+
return array_merge(
77+
(array) $this->block->getData('config'),
78+
(array) $this->getData('config')
79+
);
80+
}
6981
}

app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ protected function getWrappedComponentMock()
139139
->with('config', $this->logicalNot($this->isEmpty()));
140140
$wrappedComponentMock->expects($this->once())
141141
->method('prepare');
142-
$wrappedComponentMock->expects($this->once())
142+
$wrappedComponentMock->expects($this->atLeastOnce())
143143
->method('getChildComponents')
144144
->willReturn($this->getComponentsMock());
145145
$wrappedComponentMock->expects($this->any())

app/code/Magento/Ui/etc/data_source.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<xs:attribute type="referenceAttributeType" name="name" use="required"/>
4646
<xs:attribute type="textAttributeType" name="dataType" use="optional"/>
4747
<xs:attribute type="textAttributeType" name="formElement" use="optional"/>
48+
<xs:attribute type="textAttributeType" name="componentType" use="optional"/>
4849
<xs:attribute type="textAttributeType" name="displayArea" use="optional"/>
4950
<xs:attribute type="textAttributeType" name="fieldGroup" use="optional"/>
5051
<xs:attribute type="textAttributeType" name="source" use="optional"/>

app/code/Magento/Ui/etc/di.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,27 @@
162162
</argument>
163163
</arguments>
164164
</type>
165+
<type name="Magento\Framework\View\Layout\Generic">
166+
<arguments>
167+
<argument name="data" xsi:type="array">
168+
<item name="config" xsi:type="array">
169+
<item name="component" xsi:type="string">Magento_Ui/js/form/components/html</item>
170+
<item name="componentName" xsi:type="string">html_content</item>
171+
<item name="panelComponentName" xsi:type="string">fieldset</item>
172+
</item>
173+
</argument>
174+
</arguments>
175+
</type>
176+
<type name="Magento\Ui\Component\Layout\Tabs">
177+
<arguments>
178+
<argument name="data" xsi:type="array">
179+
<item name="config" xsi:type="array">
180+
<item name="component" xsi:type="string">Magento_Ui/js/form/components/html</item>
181+
<item name="componentName" xsi:type="string">html_content</item>
182+
</item>
183+
</argument>
184+
</arguments>
185+
</type>
165186
<virtualType name="arrayArgumentInterpreterProxy" type="Magento\Framework\Data\Argument\InterpreterInterface\Proxy">
166187
<arguments>
167188
<argument name="instanceName" xsi:type="string">Magento\Framework\Data\Argument\Interpreter\ArrayType</argument>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\View\Element\UiComponent;
7+
8+
use Magento\Framework\View\Element\UiComponentInterface;
9+
use Magento\Framework\View\Element\BlockInterface;
10+
11+
/**
12+
* Interface BlockWrapperInterface
13+
*/
14+
interface BlockWrapperInterface extends UiComponentInterface
15+
{
16+
/**
17+
* Get wrapped block
18+
*
19+
* @return BlockInterface
20+
*/
21+
public function getBlock();
22+
}

0 commit comments

Comments
 (0)