@eeacms/volto-tabs-block 8.0.1 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +21 -30
  2. package/locales/de/LC_MESSAGES/volto.po +187 -182
  3. package/locales/en/LC_MESSAGES/volto.po +187 -182
  4. package/locales/es/LC_MESSAGES/volto.po +189 -184
  5. package/locales/it/LC_MESSAGES/volto.po +187 -182
  6. package/locales/pt_BR/LC_MESSAGES/volto.po +187 -182
  7. package/locales/ro/LC_MESSAGES/volto.po +187 -182
  8. package/locales/volto.pot +189 -184
  9. package/package.json +3 -3
  10. package/src/components/Edit.jsx +7 -7
  11. package/src/components/EditBlockWrapper.jsx +3 -3
  12. package/src/components/View.jsx +14 -9
  13. package/src/components/index.js +4 -4
  14. package/src/components/schema.js +15 -1
  15. package/src/components/{templates → variations}/accordion/Edit.jsx +2 -2
  16. package/src/components/{templates → variations}/accordion/View.jsx +4 -1
  17. package/src/components/{templates → variations}/carousel/HorizontalView.jsx +1 -1
  18. package/src/components/{templates → variations}/carousel/VerticalView.jsx +1 -1
  19. package/src/components/{templates → variations}/default/Edit.jsx +1 -1
  20. package/src/components/{templates → variations}/horizontal-responsive/Edit.jsx +1 -1
  21. package/src/helpers.js +40 -1
  22. package/src/helpers.test.js +14 -0
  23. /package/src/components/{templates → variations}/accordion/index.js +0 -0
  24. /package/src/components/{templates → variations}/accordion/schema.js +0 -0
  25. /package/src/components/{templates → variations}/carousel/index.js +0 -0
  26. /package/src/components/{templates → variations}/carousel/schema.js +0 -0
  27. /package/src/components/{templates → variations}/default/View.jsx +0 -0
  28. /package/src/components/{templates → variations}/default/index.js +0 -0
  29. /package/src/components/{templates → variations}/default/schema.js +0 -0
  30. /package/src/components/{templates → variations}/horizontal-responsive/View.jsx +0 -0
  31. /package/src/components/{templates → variations}/horizontal-responsive/index.js +0 -0
  32. /package/src/components/{templates → variations}/horizontal-responsive/schema.js +0 -0
@@ -12,7 +12,8 @@ import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
12
12
  import { empty, emptyTab } from '@eeacms/volto-tabs-block/helpers';
13
13
  import { StyleWrapperView } from '@eeacms/volto-block-style/StyleWrapper';
14
14
  import { BlockStyleWrapperEdit } from '@eeacms/volto-block-style/BlockStyleWrapper';
15
- import { DefaultEdit } from './templates/default';
15
+ import { getVariation } from '@eeacms/volto-tabs-block/helpers';
16
+ import { DefaultEdit } from './variations/default';
16
17
  import { useIntl } from 'react-intl';
17
18
 
18
19
  import '@eeacms/volto-tabs-block/less/edit.less';
@@ -23,7 +24,7 @@ const Edit = (props) => {
23
24
  const intl = useIntl();
24
25
  const { onChangeBlock, onChangeField } = props;
25
26
  const { data = {}, block = null } = props;
26
- const template = data.variation || 'default';
27
+ const variation = getVariation(data);
27
28
  const tabsData = data.data || {};
28
29
  const tabsList = tabsData.blocks_layout?.items || [];
29
30
  const tabs = tabsData.blocks || {};
@@ -38,11 +39,11 @@ const Edit = (props) => {
38
39
  const verticalAlign = data.verticalAlign || 'flex-start';
39
40
  const tabsBlockConfig = config.blocks.blocksConfig[TABS_BLOCK];
40
41
 
41
- const activeTemplate = config.blocks.blocksConfig[
42
+ const activeVariation = config.blocks.blocksConfig[
42
43
  TABS_BLOCK
43
- ].variations.filter((v, _i) => v.id === template);
44
+ ].variations.filter((v, _i) => v.id === variation);
44
45
 
45
- const TabsEdit = activeTemplate?.[0]?.edit || DefaultEdit;
46
+ const TabsEdit = activeVariation?.[0]?.edit || DefaultEdit;
46
47
 
47
48
  const schemaObject = tabsBlockConfig.blockSchema(props);
48
49
 
@@ -168,7 +169,7 @@ const Edit = (props) => {
168
169
  Tabs
169
170
  </legend>
170
171
  <div
171
- className={cx('tabs-block edit', theme, verticalAlign, template)}
172
+ className={cx('tabs-block edit', theme, verticalAlign, variation)}
172
173
  ref={view}
173
174
  role="presentation"
174
175
  onKeyDown={(e) => {
@@ -200,7 +201,6 @@ const Edit = (props) => {
200
201
  tabsData={tabsData}
201
202
  tabsList={tabsList}
202
203
  node={view}
203
- template={template}
204
204
  onChangeTabData={onChangeTabData}
205
205
  onSelectBlock={onSelectBlock}
206
206
  setActiveBlock={setActiveBlock}
@@ -122,9 +122,9 @@ class EditBlockWrapper extends React.Component {
122
122
  basic
123
123
  title="Add block"
124
124
  onClick={() => {
125
- this.setState({
126
- addNewBlockOpened: !this.state.addNewBlockOpened,
127
- });
125
+ this.setState((prevState) => ({
126
+ addNewBlockOpened: !prevState.addNewBlockOpened,
127
+ }));
128
128
  }}
129
129
  className="column-block-add-button"
130
130
  >
@@ -4,8 +4,12 @@ import { compose } from 'redux';
4
4
  import { withRouter } from 'react-router';
5
5
  import { StyleWrapperView } from '@eeacms/volto-block-style/StyleWrapper';
6
6
  import { TABS_BLOCK } from '@eeacms/volto-tabs-block/constants';
7
- import { getParentTabFromHash } from '@eeacms/volto-tabs-block/helpers';
8
- import { DefaultView } from './templates/default';
7
+ import {
8
+ getVariation,
9
+ isTabEmpty,
10
+ getParentTabFromHash,
11
+ } from '@eeacms/volto-tabs-block/helpers';
12
+ import { DefaultView } from './variations/default';
9
13
  import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
10
14
 
11
15
  import config from '@plone/volto/registry';
@@ -17,21 +21,23 @@ const View = (props) => {
17
21
  const view = React.useRef(null);
18
22
  const { data = {}, uiContainer = '', location, history } = props;
19
23
  const metadata = props.metadata || props.properties;
20
- const template = data.variation || 'default';
24
+ const variation = getVariation(data);
21
25
  const tabsData = data.data || {};
22
- const tabsList = tabsData.blocks_layout?.items || [];
23
26
  const tabs = tabsData.blocks || {};
27
+ const tabsList = (tabsData.blocks_layout?.items || []).filter((tab) => {
28
+ return data.hideEmptyTabs ? !isTabEmpty(tabs[tab]) : true;
29
+ });
24
30
  const [activeTab, setActiveTab] = React.useState(tabsList?.[0]);
25
31
  const activeTabIndex = tabsList.indexOf(activeTab);
26
32
  const tabData = tabs[activeTab] || {};
27
33
  const theme = data.theme || 'light';
28
34
  const verticalAlign = data.verticalAlign || 'flex-start';
29
35
 
30
- const activeTemplate = config.blocks.blocksConfig[
36
+ const activeVariation = config.blocks.blocksConfig[
31
37
  TABS_BLOCK
32
- ].variations.filter((v, _i) => v.id === template);
38
+ ].variations.filter((v, _i) => v.id === variation);
33
39
 
34
- const TabsView = activeTemplate?.[0]?.view || DefaultView;
40
+ const TabsView = activeVariation?.[0]?.view || DefaultView;
35
41
 
36
42
  const query = React.useMemo(() => {
37
43
  const { search } = location;
@@ -90,7 +96,7 @@ const View = (props) => {
90
96
  styled={true}
91
97
  >
92
98
  <div
93
- className={cx('tabs-block', template, theme, verticalAlign)}
99
+ className={cx('tabs-block', variation, theme, verticalAlign)}
94
100
  id={props.id}
95
101
  ref={view}
96
102
  >
@@ -112,7 +118,6 @@ const View = (props) => {
112
118
  tabData={tabData}
113
119
  tabsData={tabsData}
114
120
  tabsList={tabsList}
115
- template={template}
116
121
  uiContainer={uiContainer}
117
122
  setActiveTab={handleActiveTabChange}
118
123
  />
@@ -7,7 +7,7 @@ export { TabsEdit, TabsView };
7
7
  export { layoutSchema };
8
8
 
9
9
  export * from './schema';
10
- export * from './templates/default';
11
- export * from './templates/accordion';
12
- export * from './templates/horizontal-responsive';
13
- export * from './templates/carousel';
10
+ export * from './variations/default';
11
+ export * from './variations/accordion';
12
+ export * from './variations/horizontal-responsive';
13
+ export * from './variations/carousel';
@@ -86,6 +86,10 @@ const messages = defineMessages({
86
86
  id: 'hideTitle',
87
87
  defaultMessage: 'Hide tab title?',
88
88
  },
89
+ HideEmptyTabs: {
90
+ id: 'hideEmptyTabs',
91
+ defaultMessage: 'Hide empty tabs in view?',
92
+ },
89
93
  Large: {
90
94
  id: 'large',
91
95
  defaultMessage: 'Large',
@@ -191,7 +195,13 @@ export const blockSchema = (props) => {
191
195
  {
192
196
  id: 'default',
193
197
  title: intl.formatMessage(messages.Default),
194
- fields: ['title', 'description', 'verticalAlign', 'data'],
198
+ fields: [
199
+ 'title',
200
+ 'description',
201
+ 'verticalAlign',
202
+ 'hideEmptyTabs',
203
+ 'data',
204
+ ],
195
205
  },
196
206
  ],
197
207
  properties: {
@@ -216,6 +226,10 @@ export const blockSchema = (props) => {
216
226
  ],
217
227
  default: 'flex-start',
218
228
  },
229
+ hideEmptyTabs: {
230
+ title: intl.formatMessage(messages.HideEmptyTabs),
231
+ type: 'boolean',
232
+ },
219
233
  },
220
234
  required: [],
221
235
  };
@@ -1,5 +1,5 @@
1
- import Edit from '@eeacms/volto-tabs-block/components/templates/default/Edit';
2
- import { accordionSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/accordion/schema';
1
+ import Edit from '@eeacms/volto-tabs-block/components/variations/default/Edit';
2
+ import { accordionSchemaEnhancer } from '@eeacms/volto-tabs-block/components/variations/accordion/schema';
3
3
  import cx from 'classnames';
4
4
 
5
5
  const AccordionEdit = (props) => {
@@ -17,6 +17,7 @@ import { getParentTabFromHash } from '@eeacms/volto-tabs-block/helpers';
17
17
  import { withScrollToTarget } from '@eeacms/volto-tabs-block/hocs';
18
18
 
19
19
  import '@eeacms/volto-tabs-block/less/menu.less';
20
+ import { getVariation } from '../../../helpers';
20
21
 
21
22
  class Tab extends React.Component {
22
23
  render() {
@@ -39,9 +40,11 @@ const View = (props) => {
39
40
  id,
40
41
  } = props;
41
42
 
43
+ const variation = getVariation(data);
44
+
42
45
  const accordionConfig = config.blocks.blocksConfig[
43
46
  TABS_BLOCK
44
- ].variations.filter((v, _i) => v.id === data.variation);
47
+ ].variations.filter((v, _i) => v.id === variation);
45
48
  const {
46
49
  icons,
47
50
  semanticIcon,
@@ -6,7 +6,7 @@ import { Icon, RenderBlocks } from '@plone/volto/components';
6
6
 
7
7
  import rightArrowSVG from '@eeacms/volto-tabs-block/icons/right-key.svg';
8
8
  import leftArrowSVG from '@eeacms/volto-tabs-block/icons/left-key.svg';
9
- import { carouselSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/carousel/schema';
9
+ import { carouselSchemaEnhancer } from '@eeacms/volto-tabs-block/components/variations/carousel/schema';
10
10
 
11
11
  import 'slick-carousel/slick/slick.css';
12
12
  import 'slick-carousel/slick/slick-theme.css';
@@ -6,7 +6,7 @@ import { RenderBlocks } from '@plone/volto/components';
6
6
  import 'slick-carousel/slick/slick.css';
7
7
  import 'slick-carousel/slick/slick-theme.css';
8
8
  import '@eeacms/volto-tabs-block/less/carousel.less';
9
- import { carouselSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/carousel/schema';
9
+ import { carouselSchemaEnhancer } from '@eeacms/volto-tabs-block/components/variations/carousel/schema';
10
10
 
11
11
  const Slider = loadable(() => import('react-slick'));
12
12
 
@@ -7,7 +7,7 @@ import { Menu, Tab, Input, Container } from 'semantic-ui-react';
7
7
  import { BlocksForm } from '@plone/volto/components';
8
8
  import { emptyBlocksForm } from '@plone/volto/helpers';
9
9
  import EditBlockWrapper from '@eeacms/volto-tabs-block/components/EditBlockWrapper';
10
- import { defaultSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/default/schema';
10
+ import { defaultSchemaEnhancer } from '@eeacms/volto-tabs-block/components/variations/default/schema';
11
11
  import { AssetTab } from '@eeacms/volto-tabs-block/components';
12
12
  import {
13
13
  SimpleMarkdown,
@@ -10,7 +10,7 @@ import { Menu, Tab, Container, Dropdown, Input } from 'semantic-ui-react';
10
10
  import { emptyBlocksForm } from '@plone/volto/helpers';
11
11
  import { BlocksForm } from '@plone/volto/components';
12
12
  import EditBlockWrapper from '@eeacms/volto-tabs-block/components/EditBlockWrapper';
13
- import { defaultSchemaEnhancer } from '@eeacms/volto-tabs-block/components/templates/default/schema';
13
+ import { defaultSchemaEnhancer } from '@eeacms/volto-tabs-block/components/variations/default/schema';
14
14
  import {
15
15
  SimpleMarkdown,
16
16
  getMenuPosition,
package/src/helpers.js CHANGED
@@ -1,7 +1,27 @@
1
1
  import { v4 as uuid } from 'uuid';
2
- import { emptyBlocksForm, applySchemaDefaults } from '@plone/volto/helpers';
2
+ import {
3
+ emptyBlocksForm,
4
+ applySchemaDefaults,
5
+ getBlocksFieldname,
6
+ getBlocksLayoutFieldname,
7
+ } from '@plone/volto/helpers';
3
8
  import { visitBlocks, toSlug } from '@eeacms/volto-anchors/helpers';
4
9
 
10
+ const variationsMapping = {
11
+ carousel: 'carousel-horizontal',
12
+ carousel_vertical: 'carousel-vertical',
13
+ };
14
+
15
+ export const getVariation = (data) => {
16
+ const { variation, template } = data;
17
+ return (
18
+ variationsMapping[variation || template] ||
19
+ variation ||
20
+ template ||
21
+ 'default'
22
+ );
23
+ };
24
+
5
25
  export const empty = ({ schema, intl }) => {
6
26
  const tabId = uuid();
7
27
  const data = {
@@ -56,3 +76,22 @@ export const getParentTabFromHash = (tabsBlockData, urlHash) => {
56
76
  }
57
77
  return null;
58
78
  };
79
+
80
+ export const isTabEmpty = (content) => {
81
+ const blocks_field = getBlocksFieldname(content);
82
+ const blocks_layout_field = getBlocksLayoutFieldname(content);
83
+ const blocks = content[blocks_field] || {};
84
+ const blocksNo = content[blocks_layout_field]?.items?.length || 0;
85
+
86
+ if (blocksNo === 1) {
87
+ const blockId = content[blocks_layout_field].items[0];
88
+ const block = blocks[blockId];
89
+ if (block['@type'] === 'slate' && !block['plaintext']) {
90
+ return true;
91
+ }
92
+ }
93
+ if (blocksNo === 0) {
94
+ return true;
95
+ }
96
+ return false;
97
+ };
@@ -3,6 +3,7 @@ import {
3
3
  emptyTab,
4
4
  scrollToTarget,
5
5
  getParentTabFromHash,
6
+ isTabEmpty,
6
7
  } from './helpers';
7
8
  // import { emptyBlocksForm } from '@plone/volto/helpers';
8
9
  import { visitBlocks, toSlug } from '@eeacms/volto-anchors/helpers';
@@ -42,6 +43,19 @@ describe('emptyTab function', () => {
42
43
  });
43
44
  });
44
45
 
46
+ describe('isTabEmpty function', () => {
47
+ it('returns if a tab is empty', () => {
48
+ // emptyBlocksForm.mockReturnValue({});
49
+ const result = isTabEmpty({
50
+ blocks: {},
51
+ blocks_layout: {
52
+ items: [],
53
+ },
54
+ });
55
+ expect(result).toEqual(true);
56
+ });
57
+ });
58
+
45
59
  describe('scrollToTarget', () => {
46
60
  it('should call window.scrollTo with the correct arguments', () => {
47
61
  window.scrollTo = jest.fn();