Skip to content

Commit 0630ab8

Browse files
OstafinLtbialcz
andauthored
IBX-10362: Fixed validation of matrix field without columns when creating content type (#77)
Co-authored-by: Tomasz Białczak <[email protected]>
1 parent 2ea28df commit 0630ab8

File tree

9 files changed

+58
-6
lines changed

9 files changed

+58
-6
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"ibexa/http-cache": "~4.6.0@dev",
4949
"ibexa/design-engine": "~4.6.0@dev",
5050
"ibexa/code-style": "^1.0",
51+
"ibexa/twig-components": "~4.6.x-dev",
5152
"friendsofphp/php-cs-fixer": "^3.0",
5253
"phpunit/phpunit": "^9.5",
5354
"phpstan/phpstan": "^2.0",

src/bundle/Command/MigrateLegacyMatrixCommand.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public function execute(InputInterface $input, OutputInterface $output)
107107
}
108108

109109
if ($isValidXml) {
110-
$columnList = $xml->xpath('//column-name');
110+
$columnList = $xml->xpath('//column-name') ?: [];
111111

112112
$columns = [];
113113

@@ -180,7 +180,8 @@ public function execute(InputInterface $input, OutputInterface $output)
180180
],
181181
]);
182182

183-
$rows = $this->convertCellsToRows($xml->xpath('c'), $columns);
183+
$cells = $xml->xpath('c') ?: [];
184+
$rows = $this->convertCellsToRows($cells, $columns);
184185

185186
$fieldValue->data['entries'] = $rows;
186187

src/bundle/Resources/public/js/scripts/admin.contenttype.matrix.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
const SELECTOR_ADD_COLUMN = '.ibexa-btn--add-column';
77
const SELECTOR_REMOVE_COLUMN = '.ibexa-btn--remove-column';
88
const SELECTOR_TEMPLATE = '.ibexa-matrix-settings__column-template';
9+
const ERROR_NODE_SELECTOR = '.ibexa-form-error';
910
const NUMBER_PLACEHOLDER = /__number__/g;
1011
const getNextIndex = (parentNode) => {
1112
return parentNode.dataset.nextIndex++;
@@ -36,9 +37,18 @@
3637
node.insertAdjacentHTML('beforeend', template.replace(NUMBER_PLACEHOLDER, getNextIndex(node)));
3738

3839
initColumns(settingsNode);
40+
validateColumnsNumber(settingsNode);
3941

4042
node.closest('.ibexa-table').dispatchEvent(new CustomEvent('ibexa-refresh-main-table-checkbox'));
43+
4144
doc.body.dispatchEvent(new CustomEvent('ibexa-inputs:added'));
45+
doc.body.dispatchEvent(
46+
new CustomEvent('ibexa-fieldtype-matrix:added-column', {
47+
detail: {
48+
columnNode: node.querySelector(`${SELECTOR_COLUMN}:last-of-type`),
49+
},
50+
}),
51+
);
4252
};
4353
const removeItems = (event) => {
4454
const settingsNode = event.target.closest(SELECTOR_SETTINGS_COLUMNS);
@@ -66,6 +76,7 @@
6676
});
6777

6878
node.closest('.ibexa-table').dispatchEvent(new CustomEvent('ibexa-refresh-main-table-checkbox'));
79+
validateColumnsNumber(settingsNode);
6980
}, 0);
7081

7182
initColumns(settingsNode);
@@ -91,6 +102,12 @@
91102

92103
initColumns(container);
93104
};
105+
const validateColumnsNumber = (settingsNode) => {
106+
const columns = settingsNode.querySelectorAll(SELECTOR_COLUMN);
107+
const errorNode = settingsNode.querySelector(ERROR_NODE_SELECTOR);
108+
109+
errorNode.toggleAttribute('hidden', columns.length > 0);
110+
};
94111

95112
doc.querySelectorAll(SELECTOR_SETTINGS_COLUMNS).forEach((container) => {
96113
initComponent(container);

src/bundle/Resources/public/scss/_matrix-settings.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
.ibexa-matrix-settings {
2+
&__columns {
3+
margin-top: calculateRem(16px);
4+
}
5+
26
&__column {
37
.form-check {
48
padding-left: 0;

src/bundle/Resources/translations/ibexa_matrix_fieldtype.en.xliff

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@
2626
<target state="new">Delete</target>
2727
<note>key: field.column.delete</note>
2828
</trans-unit>
29+
<trans-unit id="5e712908b00d328e0ae52c2b063ea2186335e029" resname="field.column.error.quantity">
30+
<source>At least one column is required for matrix field.</source>
31+
<target state="new">At least one column is required for matrix field.</target>
32+
<note>key: field.column.error.quantity</note>
33+
</trans-unit>
2934
<trans-unit id="fa41ae6cab6d74c6548f4052c02c0c5129a27f1d" resname="field.column.identifier">
3035
<source>Identifier</source>
3136
<target state="new">Identifier</target>

src/bundle/Resources/views/themes/admin/matrix_fieldtype/field_types.html.twig

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,21 @@
2121
body_row_cols: [
2222
{ has_checkbox: true, content: col_checkbox, raw: true },
2323
{ content: form_widget(form.columns.vars.prototype.name), raw: true },
24-
{ content: form_widget(form.columns.vars.prototype.identifier), raw: true },
24+
{ content: form_widget(form.columns.vars.prototype.identifier, {
25+
attr: {
26+
class: 'ibexa-input--matrix-column-identifier'
27+
}
28+
}), raw: true },
2529
],
2630
class: 'ibexa-matrix-settings__column',
2731
} %}
2832
</script>
33+
2934
{{ form_label(form.columns, null, { 'label_attr': { 'class': 'ibexa-label' } }) }}
3035
{{ form_errors(form.columns) }}
36+
3137
{% set body_rows = [] %}
38+
3239
{% for column in form.columns %}
3340
{% set col_checkbox %}
3441
<div class="form-check">
@@ -40,7 +47,11 @@
4047
cols: [
4148
{ has_checkbox: true, content: col_checkbox, raw: true },
4249
{ content: form_widget(column.name), raw: true },
43-
{ content: form_widget(column.identifier), raw: true },
50+
{ content: form_widget(column.identifier, {
51+
attr: {
52+
class: 'ibexa-input--matrix-column-identifier'
53+
}
54+
}), raw: true },
4455
],
4556
class: 'ibexa-matrix-settings__column',
4657
}]) %}
@@ -82,5 +93,14 @@
8293
{% endembed %}
8394
{% endblock %}
8495
{% endembed %}
96+
97+
<div class="ibexa-form-error" hidden>
98+
<em class="ibexa-form-error__row">
99+
<svg class="ibexa-icon ibexa-icon--small ibexa-form-error__icon">
100+
<use xlink:href="{{ ibexa_icon_path('notice') }}"></use>
101+
</svg>
102+
{{ 'field.column.error.quantity'|trans|desc('At least one column is required for matrix field.') }}
103+
</em>
104+
</div>
85105
</div>
86106
{% endblock %}

src/lib/FieldType/Mapper/MatrixFormMapper.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ public function mapFieldDefinitionForm(FormInterface $fieldDefinitionForm, Field
4343
])
4444
->add('columns', CollectionType::class, [
4545
'entry_type' => ColumnType::class,
46-
'entry_options' => ['required' => false],
46+
'entry_options' => ['required' => true],
4747
'allow_add' => true,
4848
'allow_delete' => true,
4949
'delete_empty' => false,
5050
'prototype' => true,
5151
'prototype_name' => '__number__',
52-
'required' => false,
52+
'required' => true,
5353
'property_path' => 'fieldSettings[columns]',
5454
'label' => false,
5555
'translation_domain' => 'ibexa_matrix_fieldtype',

src/lib/Form/Type/ColumnType.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
2020
$builder
2121
->add('name', TextType::class, [
2222
'label' => /** @Desc("Name") */ 'fieldtype.column.name',
23+
'required' => false,
2324
])
2425
->add('identifier', TextType::class, [
2526
'label' => /** @Desc("Identifier") */ 'fieldtype.column.identifier',
27+
'required' => true,
2628
]);
2729
}
2830

tests/integration/Kernel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Ibexa\Bundle\Notifications\IbexaNotificationsBundle;
1818
use Ibexa\Bundle\Rest\IbexaRestBundle;
1919
use Ibexa\Bundle\Search\IbexaSearchBundle;
20+
use Ibexa\Bundle\TwigComponents\IbexaTwigComponentsBundle;
2021
use Ibexa\Bundle\User\IbexaUserBundle;
2122
use Ibexa\Contracts\Test\Core\IbexaTestKernel;
2223
use Knp\Bundle\MenuBundle\KnpMenuBundle;
@@ -47,6 +48,7 @@ public function registerBundles(): iterable
4748
yield new IbexaAdminUiBundle();
4849
yield new IbexaNotificationsBundle();
4950
yield new IbexaGraphQLBundle();
51+
yield new IbexaTwigComponentsBundle();
5052

5153
yield new IbexaFieldTypeMatrixBundle();
5254
}

0 commit comments

Comments
 (0)