@blaze-cms/react-page-builder 0.122.0 → 0.122.2

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 (22) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/lib/components/DataSummary/helpers/get-link-to-published-content.js +5 -2
  3. package/lib/components/DataSummary/helpers/get-link-to-published-content.js.map +1 -1
  4. package/lib/components/SearchFilter/SearchFilter/SearchFilter.js +15 -50
  5. package/lib/components/SearchFilter/SearchFilter/SearchFilter.js.map +1 -1
  6. package/lib/helpers/get-filter-props.js +3 -1
  7. package/lib/helpers/get-filter-props.js.map +1 -1
  8. package/lib-es/components/DataSummary/helpers/get-link-to-published-content.js +3 -2
  9. package/lib-es/components/DataSummary/helpers/get-link-to-published-content.js.map +1 -1
  10. package/lib-es/components/SearchFilter/SearchFilter/SearchFilter.js +10 -40
  11. package/lib-es/components/SearchFilter/SearchFilter/SearchFilter.js.map +1 -1
  12. package/lib-es/helpers/get-filter-props.js +2 -1
  13. package/lib-es/helpers/get-filter-props.js.map +1 -1
  14. package/package.json +2 -2
  15. package/src/components/DataSummary/helpers/get-link-to-published-content.js +4 -2
  16. package/src/components/SearchFilter/SearchFilter/SearchFilter.js +113 -148
  17. package/src/helpers/get-filter-props.js +4 -1
  18. package/tests/helpers/mocks.js +6 -0
  19. package/tests/unit/src/components/DataSummary/helpers/get-link-to-published-content.test.js +18 -4
  20. package/tests/unit/src/components/SearchFilter/SearchFilter/SearchFilter.test.js +64 -86
  21. package/tests/unit/src/components/SearchFilter/SearchFilter/__snapshots__/SearchFilter.test.js.snap +133 -61
  22. package/tests/unit/src/helpers/get-filter-props.test.js +10 -0
@@ -44,8 +44,6 @@ const SearchFilter = ({
44
44
  groupAfterDesktop,
45
45
  groupAfterMobile
46
46
  }) => {
47
- const [isDesktop, setIsDesktop] = useState(true);
48
- const [pageWidth, setPageWidth] = useState(null);
49
47
  const [moreFiltersMobileCollapsed, setMoreFiltersMobileCollapsed] = useState(true);
50
48
  const [moreFiltersDesktopCollapsed, setMoreFiltersDesktopCollapsed] = useState(true);
51
49
  const [filterValues, dispatch] = useReducer(reducer, initialFilterValues);
@@ -55,27 +53,6 @@ const SearchFilter = ({
55
53
  handleSearch(newQuery);
56
54
  }, 200);
57
55
 
58
- useEffect(
59
- () => {
60
- if (window && !pageWidth) {
61
- setPageWidth(window.innerWidth);
62
- setIsDesktop(isDeviceDesktop());
63
- }
64
-
65
- const handleResize = ({ target: { innerWidth } }) => {
66
- setIsDesktop(isDeviceDesktop());
67
- setPageWidth(innerWidth);
68
- if (isDesktop) setDisplaySearchFilter(false);
69
- };
70
-
71
- window.addEventListener('resize', handleResize);
72
- return () => {
73
- window.removeEventListener('resize', handleResize);
74
- };
75
- },
76
- [isDesktop, pageWidth, setDisplaySearchFilter]
77
- );
78
-
79
56
  useEffect(
80
57
  () => {
81
58
  if (filterValues.shouldSearch) {
@@ -86,16 +63,9 @@ const SearchFilter = ({
86
63
  [filterValues, handleSubmit]
87
64
  );
88
65
 
89
- let isDesktopFormDisplayed = true;
90
- let isMobileFormDisplayed = false;
91
-
92
- if (!isDesktop && isCollapsedOnResponsive) {
93
- isMobileFormDisplayed = displaySearchFilter;
94
- isDesktopFormDisplayed = false;
95
- }
96
-
97
- const formClass = classnames({
98
- 'filter__form filter__form--mobile': isMobileFormDisplayed
66
+ const formClass = classnames('filter__form filter__form--initial', {
67
+ 'filter__form--mobile': isCollapsedOnResponsive && displaySearchFilter,
68
+ 'filter__form--collapsible': isCollapsedOnResponsive
99
69
  });
100
70
 
101
71
  const {
@@ -122,143 +92,138 @@ const SearchFilter = ({
122
92
 
123
93
  return (
124
94
  <>
125
- {isDesktopFormDisplayed || isMobileFormDisplayed ? (
126
- <form
127
- ref={searchFilterRef}
128
- className={formClass}
129
- data-testid={formId}
130
- id={formId}
131
- onSubmit={e => {
132
- e.preventDefault();
133
- const newQuery = buildQuery(filterValues, filters);
134
- handleSearch(newQuery);
135
- }}>
136
- {isMobileFormDisplayed && (
137
- <CloseMobileForm handleClose={() => setDisplaySearchFilter(false)} />
138
- )}
139
-
140
- <div className="filter filter--search-refine">
141
- {isDesktopFormDisplayed && <ResetDesktopForm handleReset={handleReset} />}
142
-
143
- <div className="filter__wrapper filter__wrapper--search-refine">
144
- {!shouldGroup && (
95
+ <form
96
+ ref={searchFilterRef}
97
+ className={formClass}
98
+ data-testid={formId}
99
+ id={formId}
100
+ onSubmit={e => {
101
+ e.preventDefault();
102
+ const newQuery = buildQuery(filterValues, filters);
103
+ handleSearch(newQuery);
104
+ }}>
105
+ {displaySearchFilter && (
106
+ <CloseMobileForm handleClose={() => setDisplaySearchFilter(false)} />
107
+ )}
108
+
109
+ <div className="filter filter--search-refine">
110
+ <ResetDesktopForm handleReset={handleReset} />
111
+
112
+ <div className="filter__wrapper filter__wrapper--search-refine">
113
+ {!shouldGroup && (
114
+ <FiltersList
115
+ shouldSearch={shouldSearch}
116
+ data={data}
117
+ filters={filters}
118
+ hasUrl={hasUrl}
119
+ entity={entity}
120
+ filterValues={filterValues}
121
+ updateFilterValues={updateFilterValues}
122
+ />
123
+ )}
124
+
125
+ {shouldGroup && (
126
+ <>
145
127
  <FiltersList
146
128
  shouldSearch={shouldSearch}
147
129
  data={data}
148
- filters={filters}
130
+ filters={filters.slice(0, groupAfterMobile)}
149
131
  hasUrl={hasUrl}
150
132
  entity={entity}
151
133
  filterValues={filterValues}
152
134
  updateFilterValues={updateFilterValues}
153
135
  />
154
- )}
155
-
156
- {shouldGroup && (
157
- <>
158
- <FiltersList
159
- shouldSearch={shouldSearch}
160
- data={data}
161
- filters={filters.slice(0, groupAfterMobile)}
162
- hasUrl={hasUrl}
163
- entity={entity}
164
- filterValues={filterValues}
165
- updateFilterValues={updateFilterValues}
166
- />
167
136
 
168
- {!!groupAfterMobile && (
169
- <button
170
- className={moreFiltersMobileTogglerClass}
171
- type="button"
172
- onClick={() => setMoreFiltersMobileCollapsed(!moreFiltersMobileCollapsed)}>
173
- Filters
174
- </button>
175
- )}
176
-
177
- <div className={moreFiltersMobileWrapperClass}>
178
- <div className={MORE_FILTERS_CLASSES.MOBILE_CONTENT}>
179
- <FiltersList
180
- shouldSearch={shouldSearch && isDeviceDesktop()}
181
- data={data}
182
- filters={filters.slice(
183
- groupAfterMobile,
184
- groupAfterDesktop ? groupAfterDesktop - 1 : 0
185
- )}
186
- hasUrl={hasUrl}
187
- entity={entity}
188
- filterValues={filterValues}
189
- updateFilterValues={updateFilterValues}
190
- />
191
-
192
- {!!groupAfterDesktop && (
193
- <button
194
- className={moreFiltersDesktopTogglerClass}
195
- type="button"
196
- onClick={() =>
197
- setMoreFiltersDesktopCollapsed(!moreFiltersDesktopCollapsed)
198
- }>
199
- More filters
200
- </button>
137
+ {!!groupAfterMobile && (
138
+ <button
139
+ className={moreFiltersMobileTogglerClass}
140
+ type="button"
141
+ onClick={() => setMoreFiltersMobileCollapsed(!moreFiltersMobileCollapsed)}>
142
+ Filters
143
+ </button>
144
+ )}
145
+
146
+ <div className={moreFiltersMobileWrapperClass}>
147
+ <div className={MORE_FILTERS_CLASSES.MOBILE_CONTENT}>
148
+ <FiltersList
149
+ shouldSearch={shouldSearch && isDeviceDesktop()}
150
+ data={data}
151
+ filters={filters.slice(
152
+ groupAfterMobile,
153
+ groupAfterDesktop ? groupAfterDesktop - 1 : 0
201
154
  )}
155
+ hasUrl={hasUrl}
156
+ entity={entity}
157
+ filterValues={filterValues}
158
+ updateFilterValues={updateFilterValues}
159
+ />
160
+
161
+ {!!groupAfterDesktop && (
162
+ <button
163
+ className={moreFiltersDesktopTogglerClass}
164
+ type="button"
165
+ onClick={() =>
166
+ setMoreFiltersDesktopCollapsed(!moreFiltersDesktopCollapsed)
167
+ }>
168
+ More filters
169
+ </button>
170
+ )}
171
+
172
+ <div className={moreFiltersDesktopWrapperClass}>
173
+ <div className={MORE_FILTERS_CLASSES.DESKTOP_CONTENT}>
174
+ <FiltersList
175
+ shouldSearch={false}
176
+ data={data}
177
+ filters={filters.slice(groupAfterDesktop)}
178
+ hasUrl={hasUrl}
179
+ entity={entity}
180
+ filterValues={filterValues}
181
+ updateFilterValues={updateFilterValues}
182
+ />
183
+ </div>
202
184
 
203
- <div className={moreFiltersDesktopWrapperClass}>
204
- <div className={MORE_FILTERS_CLASSES.DESKTOP_CONTENT}>
205
- <FiltersList
206
- shouldSearch={false}
207
- data={data}
208
- filters={filters.slice(groupAfterDesktop)}
209
- hasUrl={hasUrl}
210
- entity={entity}
211
- filterValues={filterValues}
212
- updateFilterValues={updateFilterValues}
213
- />
214
- </div>
215
-
216
- <div className={MORE_FILTERS_CLASSES.DESKTOP_BUTTONS}>
217
- <ResetDesktopForm handleReset={handleReset} />
185
+ <div className={MORE_FILTERS_CLASSES.DESKTOP_BUTTONS}>
186
+ <ResetDesktopForm handleReset={handleReset} />
218
187
 
219
- <button className="button button--full-width" type="submit">
220
- {SEARCH}
221
- </button>
222
- </div>
188
+ <button className="button button--full-width" type="submit">
189
+ {SEARCH}
190
+ </button>
223
191
  </div>
224
192
  </div>
193
+ </div>
225
194
 
226
- <div className={MORE_FILTERS_CLASSES.MOBILE_BUTTONS}>
227
- <ResetDesktopForm handleReset={handleReset} />
195
+ <div className={MORE_FILTERS_CLASSES.MOBILE_BUTTONS}>
196
+ <ResetDesktopForm handleReset={handleReset} />
228
197
 
229
- <button className="button button--full-width" type="submit">
230
- {SEARCH}
231
- </button>
232
- </div>
198
+ <button className="button button--full-width" type="submit">
199
+ {SEARCH}
200
+ </button>
233
201
  </div>
234
- </>
235
- )}
202
+ </div>
203
+ </>
204
+ )}
236
205
 
237
- <br />
206
+ <br />
238
207
 
239
- {isDesktopFormDisplayed && (
240
- <button className="button button--full-width" type="submit">
241
- {SEARCH}
242
- </button>
243
- )}
244
- </div>
208
+ {!displaySearchFilter && (
209
+ <button className="button button--full-width" type="submit">
210
+ {SEARCH}
211
+ </button>
212
+ )}
245
213
  </div>
214
+ </div>
215
+
216
+ {displaySearchFilter && <MobileFormToolbar formId={formId} handleReset={handleReset} />}
217
+ </form>
246
218
 
247
- {isMobileFormDisplayed && <MobileFormToolbar formId={formId} handleReset={handleReset} />}
248
- </form>
249
- ) : (
250
- <>
251
- {isCollapsedOnResponsive && (
252
- <div
253
- className="filter__refine filter__refine--mobile-close"
254
- data-testid="refine-mobile">
255
- <div role="button" onClick={() => setDisplaySearchFilter(true)}>
256
- {REFINE}
257
- </div>
219
+ {isCollapsedOnResponsive &&
220
+ !displaySearchFilter && (
221
+ <div className="filter__refine filter__refine--mobile-close" data-testid="refine-mobile">
222
+ <div role="button" onClick={() => setDisplaySearchFilter(true)}>
223
+ {REFINE}
258
224
  </div>
259
- )}
260
- </>
261
- )}
225
+ </div>
226
+ )}
262
227
  </>
263
228
  );
264
229
  };
@@ -17,13 +17,16 @@ const getFilterProps = (
17
17
  {
18
18
  relations: currentEntityRelations = [],
19
19
  properties: currentEntityProperties = {},
20
+ dynamicProperties: currentEntityDynamicProperties = {},
20
21
  identifier: currentEntityId
21
22
  } = {},
22
23
  { relations: filterEntityRelations = [], identifier: filteryEntityId } = {}
23
24
  ) => {
24
25
  const [filterName] = filter.split('/');
25
26
  const [relationName, relationProp] = filterName.split('.');
26
- const hasProperty = !!currentEntityProperties[filterName];
27
+ const hasProperty = !!(
28
+ currentEntityProperties[filterName] || currentEntityDynamicProperties[filterName]
29
+ );
27
30
  const relationEntityName = relationProp
28
31
  ? getFilterLocalKeys(relationName, currentEntityRelations)
29
32
  : null;
@@ -20,6 +20,12 @@ const GTM_CLASSNAME = 'gtm-classname';
20
20
 
21
21
  const MOCKED_SCHEMA_FOR_FILTERS = {
22
22
  identifier: 'page',
23
+ dynamicProperties: {
24
+ dynamicProp: {
25
+ type: 'string',
26
+ searchable: true
27
+ }
28
+ },
23
29
  relations: [
24
30
  {
25
31
  relationType: 'hasOne',
@@ -2,6 +2,8 @@ import '@testing-library/jest-dom/extend-expect';
2
2
  import { getLinkToPublishedContent } from '../../../../../../src/components/DataSummary/helpers';
3
3
 
4
4
  describe('get link to published content', () => {
5
+ const publishedKey = 'content.published';
6
+ const content = { url: 'url' };
5
7
  it('should be a function', () => {
6
8
  expect(typeof getLinkToPublishedContent).toEqual('function');
7
9
  });
@@ -17,14 +19,26 @@ describe('get link to published content', () => {
17
19
  });
18
20
 
19
21
  it('should return url if key does include "published" and there is related content published', () => {
20
- const props = { content: [{ url: 'url' }] };
21
- const result = getLinkToPublishedContent('content.published', props);
22
- expect(result).toEqual('url');
22
+ const props = { content: [content] };
23
+ const result = getLinkToPublishedContent(publishedKey, props);
24
+ expect(result).toEqual(content.url);
23
25
  });
24
26
 
25
27
  it('should return blank string if key does include "published" but there is no related content published', () => {
28
+ const props = { content: [] };
29
+ const result = getLinkToPublishedContent(publishedKey, props);
30
+ expect(result).toEqual('');
31
+ });
32
+
33
+ it('should return url if key does include "published" and content is not an array', () => {
34
+ const props = { content };
35
+ const result = getLinkToPublishedContent(publishedKey, props);
36
+ expect(result).toEqual(content.url);
37
+ });
38
+
39
+ it('should return blank string if key does include "published" but there is no url', () => {
26
40
  const props = { content: {} };
27
- const result = getLinkToPublishedContent('content.published', props);
41
+ const result = getLinkToPublishedContent(publishedKey, props);
28
42
  expect(result).toEqual('');
29
43
  });
30
44
  });
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
- import { render, screen, fireEvent } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom';
4
4
  import SearchFilter from '../../../../../../src/components/SearchFilter/SearchFilter';
5
- import { TABLET_WIDTH } from '../../../../../../src/components/SearchFilter/constants';
6
5
 
7
6
  // TODO DELETE WHEN UTIL WILL BE MERGED & USE IMPORT COMMENTED ABOVE
8
7
  const renderComponent = (Component, props) => {
@@ -28,118 +27,97 @@ const mockedProps = {
28
27
  displaySearchFilter: false
29
28
  };
30
29
 
31
- const customGlobal = global;
32
- const defaultWidth = global.innerWidth;
33
-
34
- afterAll(() => {
35
- customGlobal.innerWidth = defaultWidth;
36
- });
37
-
38
30
  describe('SearchFilter component', () => {
39
31
  it('should be defined', () => {
40
32
  expect(SearchFilter).toBeDefined();
41
33
  });
42
34
 
43
- describe('when the device is mobile', () => {
44
- beforeEach(() => {
45
- customGlobal.innerWidth = TABLET_WIDTH;
46
- fireEvent(customGlobal, new Event('resize'));
35
+ describe('when isCollapsedOnResponsive = true, displaySearchFilter = false', () => {
36
+ const specificMockedProps = {
37
+ ...mockedProps,
38
+ isCollapsedOnResponsive: true,
39
+ displaySearchFilter: false
40
+ };
41
+
42
+ it('should NOT render form', () => {
43
+ renderComponent(SearchFilter, specificMockedProps);
44
+ expect(screen.queryByRole('form')).not.toBeInTheDocument();
47
45
  });
48
46
 
49
- describe('when isCollapsedOnResponsive = true, displaySearchFilter = false', () => {
50
- const specificMockedProps = {
51
- ...mockedProps,
52
- isCollapsedOnResponsive: true,
53
- displaySearchFilter: false
54
- };
55
-
56
- it('should NOT render form', () => {
57
- renderComponent(SearchFilter, specificMockedProps);
58
- expect(screen.queryByRole('form')).not.toBeInTheDocument();
59
- });
60
-
61
- it('should render the mobile refine button', () => {
62
- renderComponent(SearchFilter, specificMockedProps);
63
- expect(screen.queryByTestId('refine-mobile')).toBeInTheDocument();
64
- });
47
+ it('should render the mobile refine button', () => {
48
+ renderComponent(SearchFilter, specificMockedProps);
49
+ expect(screen.queryByTestId('refine-mobile')).toBeInTheDocument();
65
50
  });
51
+ });
66
52
 
67
- describe('when isCollapsedOnResponsive = false, displaySearchFilter = true', () => {
68
- const specificMockedProps = {
69
- ...mockedProps,
70
- isCollapsedOnResponsive: false,
71
- displaySearchFilter: true
72
- };
73
-
74
- it('should NOT render form', () => {
75
- renderComponent(SearchFilter, specificMockedProps);
76
- expect(screen.queryByRole('form')).not.toBeInTheDocument();
77
- });
53
+ describe('when isCollapsedOnResponsive = false, displaySearchFilter = true', () => {
54
+ const specificMockedProps = {
55
+ ...mockedProps,
56
+ isCollapsedOnResponsive: false,
57
+ displaySearchFilter: true
58
+ };
59
+
60
+ it('should NOT render form', () => {
61
+ renderComponent(SearchFilter, specificMockedProps);
62
+ expect(screen.queryByRole('form')).not.toBeInTheDocument();
78
63
  });
64
+ });
65
+
66
+ describe('when isCollapsedOnResponsive = false, displaySearchFilter = false', () => {
67
+ const specificMockedProps = {
68
+ ...mockedProps,
69
+ isCollapsedOnResponsive: false,
70
+ displaySearchFilter: false
71
+ };
79
72
 
80
- describe('when isCollapsedOnResponsive = false, displaySearchFilter = false', () => {
81
- const specificMockedProps = {
82
- ...mockedProps,
83
- isCollapsedOnResponsive: false,
84
- displaySearchFilter: false
85
- };
86
-
87
- it('should render without throwing error and match snapshot', () => {
88
- const { asFragment } = renderComponent(SearchFilter, specificMockedProps);
89
- expect(asFragment()).toMatchSnapshot();
90
- });
91
-
92
- it('should render form', () => {
93
- renderComponent(SearchFilter, specificMockedProps);
94
-
95
- const formId = `filter-${specificMockedProps.name}-form`;
96
- const form = screen.getByTestId(formId);
97
- expect(form).toBeInTheDocument();
98
- });
73
+ it('should render without throwing error and match snapshot', () => {
74
+ const { asFragment } = renderComponent(SearchFilter, specificMockedProps);
75
+ expect(asFragment()).toMatchSnapshot();
99
76
  });
100
77
 
101
- describe('when isCollapsedOnResponsive = true, displaySearchFilter = true', () => {
102
- const specificMockedProps = {
103
- ...mockedProps,
104
- isCollapsedOnResponsive: true,
105
- displaySearchFilter: true
106
- };
107
-
108
- it('should render without throwing error and match snapshot', () => {
109
- const { asFragment } = renderComponent(SearchFilter, specificMockedProps);
110
- expect(asFragment()).toMatchSnapshot();
111
- });
112
-
113
- it('should render form', () => {
114
- renderComponent(SearchFilter, specificMockedProps);
115
-
116
- const formId = `filter-${specificMockedProps.name}-form`;
117
- const form = screen.getByTestId(formId);
118
- expect(form).toBeInTheDocument();
119
- });
78
+ it('should render form', () => {
79
+ renderComponent(SearchFilter, specificMockedProps);
80
+
81
+ const formId = `filter-${specificMockedProps.name}-form`;
82
+ const form = screen.getByTestId(formId);
83
+ expect(form).toBeInTheDocument();
120
84
  });
121
85
  });
122
86
 
123
- describe('when the device is desktop', () => {
124
- beforeEach(() => {
125
- customGlobal.innerWidth = TABLET_WIDTH + 10;
126
- fireEvent(customGlobal, new Event('resize'));
127
- });
87
+ describe('when isCollapsedOnResponsive = true, displaySearchFilter = true', () => {
88
+ const specificMockedProps = {
89
+ ...mockedProps,
90
+ isCollapsedOnResponsive: true,
91
+ displaySearchFilter: true
92
+ };
128
93
 
129
94
  it('should render without throwing error and match snapshot', () => {
130
- const { asFragment } = renderComponent(SearchFilter, mockedProps);
95
+ const { asFragment } = renderComponent(SearchFilter, specificMockedProps);
131
96
  expect(asFragment()).toMatchSnapshot();
132
97
  });
133
98
 
134
99
  it('should render form', () => {
135
- renderComponent(SearchFilter, mockedProps);
100
+ renderComponent(SearchFilter, specificMockedProps);
136
101
 
137
- const formId = `filter-${mockedProps.name}-form`;
102
+ const formId = `filter-${specificMockedProps.name}-form`;
138
103
  const form = screen.getByTestId(formId);
139
104
  expect(form).toBeInTheDocument();
140
105
  });
141
106
  });
142
107
 
108
+ it('should render without throwing error and match snapshot', () => {
109
+ const { asFragment } = renderComponent(SearchFilter, mockedProps);
110
+ expect(asFragment()).toMatchSnapshot();
111
+ });
112
+
113
+ it('should render form', () => {
114
+ renderComponent(SearchFilter, mockedProps);
115
+
116
+ const formId = `filter-${mockedProps.name}-form`;
117
+ const form = screen.getByTestId(formId);
118
+ expect(form).toBeInTheDocument();
119
+ });
120
+
143
121
  describe('when groupAfterMobile > 0 and groupAfterDesktop = 0', () => {
144
122
  const specificMockedProps = {
145
123
  ...mockedProps,