diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c1c3b218e1..d84d5f564a 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -6,6 +6,7 @@ Changelog * Added Aging Pages report (Tidjani Dia) * Add more SketchFab oEmbed patterns for models (Tom Usher) + * Add collapse option to `StreamField`, `StreamBlock`, and `ListBlock` which will load all sub-blocks initially collapsed (Matt Westcott) * Fix: Accessibility fixes for Windows high contrast mode; Dashboard icons colour and contrast (Sakshi Uppoor) * Fix: Rename additional 'spin' CSS animations to avoid clashes with other libraries (Kevin GutiƩrrez) diff --git a/client/src/components/StreamField/blocks/ListBlock.js b/client/src/components/StreamField/blocks/ListBlock.js index bcc193141f..423b4e693d 100644 --- a/client/src/components/StreamField/blocks/ListBlock.js +++ b/client/src/components/StreamField/blocks/ListBlock.js @@ -98,6 +98,11 @@ export class ListBlock extends BaseSequenceBlock { this.sequenceContainer = dom.find('[data-streamfield-list-container]'); this.container = dom; this.setState(initialState || []); + if (this.blockDef.meta.collapsed) { + this.children.forEach(block => { + block.collapse(); + }); + } if (initialError) { this.setError(initialError); diff --git a/client/src/components/StreamField/blocks/StreamBlock.js b/client/src/components/StreamField/blocks/StreamBlock.js index ad1f55341a..0c2f021274 100644 --- a/client/src/components/StreamField/blocks/StreamBlock.js +++ b/client/src/components/StreamField/blocks/StreamBlock.js @@ -209,6 +209,11 @@ export class StreamBlock extends BaseSequenceBlock { // server-side form handler knows to skip it) this.sequenceContainer = dom.find('[data-streamfield-stream-container]'); this.setState(initialState || []); + if (this.blockDef.meta.collapsed) { + this.children.forEach(block => { + block.collapse(); + }); + } this.container = dom; if (initialError) { diff --git a/docs/reference/streamfield/blocks.rst b/docs/reference/streamfield/blocks.rst index a94b1b0faf..5e3f8a85e6 100644 --- a/docs/reference/streamfield/blocks.rst +++ b/docs/reference/streamfield/blocks.rst @@ -15,6 +15,7 @@ This document details the block types provided by Wagtail for use in :ref:`Strea :param min_num: Minimum number of sub-blocks that the stream must have. :param max_num: Maximum number of sub-blocks that the stream may have. :param block_counts: Specifies the minimum and maximum number of each block type, as a dictionary mapping block names to dicts with (optional) ``min_num`` and ``max_num`` fields. + :param collapsed: When true, all blocks are initially collapsed. .. code-block:: python @@ -447,6 +448,7 @@ Structural block types :param form_classname: An HTML ``class`` attribute to set on the root element of this block as displayed in the editing interface. :param min_num: Minimum number of sub-blocks that the list must have. :param max_num: Maximum number of sub-blocks that the list may have. + :param collapsed: When true, all sub-blocks are initially collapsed. .. class:: wagtail.core.blocks.StreamBlock @@ -501,6 +503,7 @@ Structural block types :param min_num: Minimum number of sub-blocks that the stream must have. :param max_num: Maximum number of sub-blocks that the stream may have. :param block_counts: Specifies the minimum and maximum number of each block type, as a dictionary mapping block names to dicts with (optional) ``min_num`` and ``max_num`` fields. + :param collapsed: When true, all sub-blocks are initially collapsed. :param form_classname: An HTML ``class`` attribute to set on the root element of this block as displayed in the editing interface. .. code-block:: python diff --git a/docs/releases/2.16.md b/docs/releases/2.16.md index 82eb0d29e9..e0594f2d59 100644 --- a/docs/releases/2.16.md +++ b/docs/releases/2.16.md @@ -13,6 +13,7 @@ * Added Aging Pages report (Tidjani Dia) * Add more SketchFab oEmbed patterns for models (Tom Usher) + * Add collapse option to `StreamField`, `StreamBlock`, and `ListBlock` which will load all sub-blocks initially collapsed (Matt Westcott) ### Bug fixes diff --git a/wagtail/core/blocks/list_block.py b/wagtail/core/blocks/list_block.py index 6a780c3f80..84636e61a6 100644 --- a/wagtail/core/blocks/list_block.py +++ b/wagtail/core/blocks/list_block.py @@ -184,6 +184,7 @@ class ListBlock(Block): form_classname = None min_num = None max_num = None + collapsed = False MUTABLE_META_ATTRIBUTES = ['min_num', 'max_num'] @@ -194,6 +195,7 @@ class ListBlockAdapter(Adapter): def js_args(self, block): meta = { 'label': block.label, 'icon': block.meta.icon, 'classname': block.meta.form_classname, + 'collapsed': block.meta.collapsed, 'strings': { 'MOVE_UP': _("Move up"), 'MOVE_DOWN': _("Move down"), diff --git a/wagtail/core/blocks/stream_block.py b/wagtail/core/blocks/stream_block.py index 14d9829dfa..2350d73f62 100644 --- a/wagtail/core/blocks/stream_block.py +++ b/wagtail/core/blocks/stream_block.py @@ -326,8 +326,9 @@ class BaseStreamBlock(Block): min_num = None max_num = None block_counts = {} + collapsed = False - MUTABLE_META_ATTRIBUTES = ['required', 'min_num', 'max_num', 'block_counts'] + MUTABLE_META_ATTRIBUTES = ['required', 'min_num', 'max_num', 'block_counts', 'collapsed'] class StreamBlock(BaseStreamBlock, metaclass=DeclarativeSubBlocksMetaclass): @@ -590,6 +591,7 @@ class StreamBlockAdapter(Adapter): 'classname': block.meta.form_classname, 'maxNum': block.meta.max_num, 'minNum': block.meta.min_num, 'blockCounts': block.meta.block_counts, + 'collapsed': block.meta.collapsed, 'strings': { 'MOVE_UP': _("Move up"), 'MOVE_DOWN': _("Move down"), diff --git a/wagtail/core/fields.py b/wagtail/core/fields.py index 63ce609bbb..93f2976069 100644 --- a/wagtail/core/fields.py +++ b/wagtail/core/fields.py @@ -63,7 +63,7 @@ class StreamField(models.Field): # extract kwargs that are to be passed on to the block, not handled by super block_opts = {} - for arg in ['min_num', 'max_num', 'block_counts']: + for arg in ['min_num', 'max_num', 'block_counts', 'collapsed']: if arg in kwargs: block_opts[arg] = kwargs.pop(arg) diff --git a/wagtail/core/tests/test_blocks.py b/wagtail/core/tests/test_blocks.py index f54da32231..db9033bbfc 100644 --- a/wagtail/core/tests/test_blocks.py +++ b/wagtail/core/tests/test_blocks.py @@ -2170,6 +2170,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase): 'label': 'Test listblock', 'icon': 'placeholder', 'classname': None, + 'collapsed': False, 'strings': { 'DELETE': 'Delete', 'DUPLICATE': 'Duplicate', @@ -2196,6 +2197,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase): 'label': 'Test listblock', 'icon': 'placeholder', 'classname': None, + 'collapsed': False, 'minNum': 2, 'maxNum': 5, 'strings': { @@ -2321,6 +2323,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase): 'label': 'Test listblock', 'icon': 'placeholder', 'classname': 'special-list-class', + 'collapsed': False, 'strings': { 'DELETE': 'Delete', 'DUPLICATE': 'Duplicate', @@ -2351,6 +2354,7 @@ class TestListBlock(WagtailTestUtils, SimpleTestCase): 'label': 'Test listblock', 'icon': 'placeholder', 'classname': 'custom-list-class', + 'collapsed': False, 'strings': { 'DELETE': 'Delete', 'DUPLICATE': 'Duplicate', @@ -2726,6 +2730,7 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase): 'label': 'Test streamblock', 'icon': 'placeholder', 'classname': None, + 'collapsed': False, 'maxNum': None, 'minNum': None, 'blockCounts': {}, @@ -3329,6 +3334,7 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase): 'minNum': None, 'maxNum': None, 'blockCounts': {}, + 'collapsed': False, 'required': True, 'classname': 'rocket-section', 'strings': { @@ -3360,6 +3366,7 @@ class TestStreamBlock(WagtailTestUtils, SimpleTestCase): 'minNum': None, 'maxNum': None, 'blockCounts': {}, + 'collapsed': False, 'required': True, 'classname': 'profile-block-large', 'strings': {