Show error when StreamBlock falls below min_num

pull/12023/head
Matt Westcott 2024-06-07 18:19:12 +01:00 zatwierdzone przez Sage Abdullah
rodzic 23df591435
commit 14325d4615
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: EB1A33CC51CC0217
2 zmienionych plików z 182 dodań i 13 usunięć

Wyświetl plik

@ -274,22 +274,43 @@ export class StreamBlock extends BaseSequenceBlock {
errorMessages.push(message);
}
const minNum = this.blockDef.meta.minNum;
if (typeof minNum === 'number' && this.children.length < minNum) {
const message = gettext(
'The minimum number of items is %(min_num)d',
).replace('%(min_num)d', `${minNum}`);
errorMessages.push(message);
}
// Check if there are any block types that have count limits
for (const blockType in this.blockDef.meta.blockCounts) {
if (hasOwn(this.blockDef.meta.blockCounts, blockType)) {
const blockMaxNum = this.getBlockMax(blockType);
for (const [blockType, constraints] of Object.entries(
this.blockDef.meta.blockCounts,
)) {
const blockMaxNum = constraints.max_num;
if (typeof blockMaxNum === 'number') {
const currentBlockCount = this.getBlockCount(blockType);
if (typeof blockMaxNum === 'number') {
const currentBlockCount = this.getBlockCount(blockType);
if (currentBlockCount > blockMaxNum) {
const childBlockDef = this.blockDef.childBlockDefsByName[blockType];
const message = gettext(
'The maximum number of items is %(max_num)d',
).replace('%(max_num)d', `${blockMaxNum}`);
const messageWithPrefix = `${childBlockDef.meta.label}: ${message}`;
errorMessages.push(messageWithPrefix);
}
}
if (currentBlockCount > blockMaxNum) {
const childBlockDef = this.blockDef.childBlockDefsByName[blockType];
const message = gettext(
'The maximum number of items is %(max_num)d',
).replace('%(max_num)d', `${blockMaxNum}`);
const messageWithPrefix = `${childBlockDef.meta.label}: ${message}`;
errorMessages.push(messageWithPrefix);
}
const blockMinNum = constraints.min_num;
if (typeof blockMinNum === 'number') {
const currentBlockCount = this.getBlockCount(blockType);
if (currentBlockCount < blockMinNum) {
const childBlockDef = this.blockDef.childBlockDefsByName[blockType];
const message = gettext(
'The minimum number of items is %(min_num)d',
).replace('%(min_num)d', `${blockMinNum}`);
const messageWithPrefix = `${childBlockDef.meta.label}: ${message}`;
errorMessages.push(messageWithPrefix);
}
}
}

Wyświetl plik

@ -722,6 +722,154 @@ describe('telepath: wagtail.blocks.StreamBlock with maxNum set', () => {
});
});
describe('telepath: wagtail.blocks.StreamBlock with minNum set', () => {
// Define a test block
const blockDef = new StreamBlockDefinition(
'',
[
[
'',
[
new FieldBlockDefinition(
'test_block_a',
new DummyWidgetDefinition('Block A widget'),
{
label: 'Test Block <A>',
required: true,
icon: 'placeholder',
classname: 'w-field w-field--char_field w-field--text_input',
},
),
new FieldBlockDefinition(
'test_block_b',
new DummyWidgetDefinition('Block B widget'),
{
label: 'Test Block <B>',
required: true,
icon: 'pilcrow',
classname:
'w-field w-field--char_field w-field--admin_auto_height_text_input',
},
),
],
],
],
{
test_block_a: 'Block A options',
test_block_b: 'Block B options',
},
{
label: '',
required: true,
icon: 'placeholder',
classname: null,
helpText: 'use <strong>plenty</strong> of these',
helpIcon: '<svg></svg>',
maxNum: null,
minNum: 2,
blockCounts: {},
strings: {
MOVE_UP: 'Move up',
MOVE_DOWN: 'Move down',
DELETE: 'Delete & kill with fire',
DUPLICATE: 'Duplicate',
ADD: 'Add',
},
},
);
const assertShowingErrorMessage = () => {
expect(document.querySelector('p.help-block.help-critical').innerHTML).toBe(
'The minimum number of items is 2',
);
};
const assertNotShowingErrorMessage = () => {
expect(document.querySelector('p.help-block.help-critical')).toBe(null);
};
test('test no error message when at lower limit', () => {
document.body.innerHTML = '<div id="placeholder"></div>';
const boundBlock = blockDef.render($('#placeholder'), 'the-prefix', [
{
id: '1',
type: 'test_block_a',
value: 'First value',
},
{
id: '2',
type: 'test_block_b',
value: 'Second value',
},
]);
boundBlock.inserters[0].open();
assertNotShowingErrorMessage();
});
test('initialising under minNum shows error message', () => {
document.body.innerHTML = '<div id="placeholder"></div>';
const boundBlock = blockDef.render($('#placeholder'), 'the-prefix', [
{
id: '1',
type: 'test_block_a',
value: 'First value',
},
]);
boundBlock.inserters[0].open();
assertShowingErrorMessage();
});
test('inserting to reach lower limit removes error', () => {
document.body.innerHTML = '<div id="placeholder"></div>';
const boundBlock = blockDef.render($('#placeholder'), 'the-prefix', [
{
id: '1',
type: 'test_block_a',
value: 'First value',
},
]);
boundBlock.inserters[0].open();
assertShowingErrorMessage();
boundBlock.insert(
{
id: '2',
type: 'test_block_b',
value: 'Second value',
},
1,
);
assertNotShowingErrorMessage();
});
test('deleting to under lower limit shows error mesage', () => {
document.body.innerHTML = '<div id="placeholder"></div>';
const boundBlock = blockDef.render($('#placeholder'), 'the-prefix', [
{
id: '1',
type: 'test_block_a',
value: 'First value',
},
{
id: '2',
type: 'test_block_b',
value: 'Second value',
},
]);
boundBlock.inserters[0].open();
assertNotShowingErrorMessage();
boundBlock.deleteBlock(1);
assertShowingErrorMessage();
});
});
describe('telepath: wagtail.blocks.StreamBlock with blockCounts.max_num set', () => {
// Define a test block
const blockDef = new StreamBlockDefinition(