@blaze-cms/react-page-builder 0.122.0 → 0.123.0-alpha.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 (37) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/lib/application/query/index.js +7 -1
  3. package/lib/application/query/index.js.map +1 -1
  4. package/lib/components/DataSummary/helpers/get-link-to-published-content.js +5 -2
  5. package/lib/components/DataSummary/helpers/get-link-to-published-content.js.map +1 -1
  6. package/lib/components/Menu/Menu.js +35 -4
  7. package/lib/components/Menu/Menu.js.map +1 -1
  8. package/lib/components/SearchContent/index.js +195 -0
  9. package/lib/components/SearchContent/index.js.map +1 -0
  10. package/lib/components/index.js +5 -5
  11. package/lib/components/index.js.map +1 -1
  12. package/lib/helpers/get-filter-props.js +3 -1
  13. package/lib/helpers/get-filter-props.js.map +1 -1
  14. package/lib-es/application/query/index.js +29 -1
  15. package/lib-es/application/query/index.js.map +1 -1
  16. package/lib-es/components/DataSummary/helpers/get-link-to-published-content.js +3 -2
  17. package/lib-es/components/DataSummary/helpers/get-link-to-published-content.js.map +1 -1
  18. package/lib-es/components/Menu/Menu.js +35 -5
  19. package/lib-es/components/Menu/Menu.js.map +1 -1
  20. package/lib-es/components/SearchContent/index.js +149 -0
  21. package/lib-es/components/SearchContent/index.js.map +1 -0
  22. package/lib-es/components/index.js +4 -4
  23. package/lib-es/components/index.js.map +1 -1
  24. package/lib-es/helpers/get-filter-props.js +2 -1
  25. package/lib-es/helpers/get-filter-props.js.map +1 -1
  26. package/package.json +2 -2
  27. package/src/application/query/index.js +29 -0
  28. package/src/components/DataSummary/helpers/get-link-to-published-content.js +4 -2
  29. package/src/components/Menu/Menu.js +32 -2
  30. package/src/components/SearchContent/index.js +146 -0
  31. package/src/components/index.js +4 -2
  32. package/src/helpers/get-filter-props.js +4 -1
  33. package/tests/helpers/mocks.js +6 -0
  34. package/tests/unit/src/components/DataSummary/helpers/get-link-to-published-content.test.js +18 -4
  35. package/tests/unit/src/components/Menu/__snapshots__/Menu.test.js.snap +11 -7
  36. package/tests/unit/src/components/__snapshots__/index.test.js.snap +4 -4
  37. package/tests/unit/src/helpers/get-filter-props.test.js +10 -0
@@ -0,0 +1,146 @@
1
+ import { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { gql, useQuery } from '@apollo/client';
4
+ import { useRouter } from 'next/router';
5
+ import { getPublishedContent } from '../../application/query';
6
+
7
+ const SearchContent = ({ searchInputAlignment, entityName, entityField }) => {
8
+ const [collapsed, setCollapsed] = useState(true);
9
+ const [searchTerm, setSearchTerm] = useState(null);
10
+ const router = useRouter();
11
+
12
+ let alignmentModifier = '';
13
+
14
+ if (searchInputAlignment && searchInputAlignment !== '') {
15
+ alignmentModifier = searchInputAlignment === 'left' ? 'left-6' : 'right-16';
16
+ }
17
+
18
+ const rawQueryStringified = JSON.stringify({
19
+ size: 0,
20
+ query: {
21
+ bool: {
22
+ filter: {
23
+ bool: {
24
+ should: [
25
+ {
26
+ match: {
27
+ docType: entityField
28
+ }
29
+ }
30
+ ],
31
+ minimum_should_match: 1
32
+ }
33
+ }
34
+ }
35
+ }
36
+ });
37
+
38
+ const query = gql`
39
+ ${getPublishedContent(entityName)}
40
+ `;
41
+
42
+ const { loading, error, data } = useQuery(query, {
43
+ variables: { rawQueryStringified, offset: 0, limit: 5 }
44
+ });
45
+
46
+ if (loading) return null;
47
+ if (error) return `Error! ${error}`;
48
+
49
+ const renderResults = () => {
50
+ // eslint-disable-next-line no-undef
51
+ const { results } = data?.searchPublishedContent;
52
+
53
+ const handleClick = (e, url) => {
54
+ e.preventDefault();
55
+ router.push(url);
56
+ };
57
+
58
+ if (results && searchTerm && searchTerm !== '') {
59
+ return results.map(({ name, url }) => {
60
+ if (name.match(searchTerm)) {
61
+ return (
62
+ <a href={url} onClick={e => handleClick(e, url)}>
63
+ {name}
64
+ </a>
65
+ );
66
+ }
67
+
68
+ return null;
69
+ });
70
+ }
71
+
72
+ return [];
73
+ };
74
+
75
+ return collapsed ? (
76
+ <div className={`absolute rounded-3xl overflow-auto top-3 ${alignmentModifier}`}>
77
+ <div className="w-11 mx-auto">
78
+ <label className="relative block">
79
+ <span className="absolute inset-y-0 right-3 flex items-center pl-2 cursor-pointer">
80
+ <svg className="h-5 w-5 fill-slate-300" viewBox="0 0 20 20">
81
+ <path
82
+ fillRule="evenodd"
83
+ d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
84
+ clipRule="evenodd"
85
+ />
86
+ </svg>
87
+ </span>
88
+ <span className="sr-only">Search</span>
89
+ <input
90
+ onFocus={() => setCollapsed(false)}
91
+ onChange={e => setSearchTerm(e.target.value)}
92
+ type="text"
93
+ name="search"
94
+ value=""
95
+ className="disabled:bg-white block bg-white w-full rounded-full py-2 pl-5 pr-3 placeholder:italic placeholder:text-gray-400 focus:outline-none sm:text-sm"
96
+ />
97
+ </label>
98
+ </div>
99
+ </div>
100
+ ) : (
101
+ <>
102
+ <div className={`absolute overflow-auto top-3 ${alignmentModifier}`}>
103
+ <div className="w-96 mx-auto rounded-3xl">
104
+ <label className="relative block">
105
+ <span className="absolute inset-y-0 right-3 flex items-center pl-2">
106
+ <svg className="h-5 w-5 fill-slate-300" viewBox="0 0 20 20">
107
+ <path
108
+ fillRule="evenodd"
109
+ d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
110
+ clipRule="evenodd"
111
+ />
112
+ </svg>
113
+ </span>
114
+ <span className="sr-only">Search</span>
115
+ <input
116
+ type="text"
117
+ name="search"
118
+ onChange={e => setSearchTerm(e.target.value)}
119
+ className="block bg-white w-full rounded-full py-2 pl-3 pr-3 placeholder:italic placeholder:text-slate-400 focus:outline-none sm:text-sm"
120
+ placeholder="Search for anything..."
121
+ onBlur={() => setCollapsed(true)}
122
+ />
123
+ </label>
124
+ </div>
125
+ <div className="bg-white ml-3 mr-3 relative">
126
+ <div>Search Results</div>
127
+ {data && renderResults()}
128
+ </div>
129
+ </div>
130
+ </>
131
+ );
132
+ };
133
+
134
+ SearchContent.propTypes = {
135
+ searchInputAlignment: PropTypes.string,
136
+ entityName: PropTypes.string,
137
+ entityField: PropTypes.string
138
+ };
139
+
140
+ SearchContent.defaultProps = {
141
+ searchInputAlignment: '',
142
+ entityName: 'PublishedPage',
143
+ entityField: 'published_page'
144
+ };
145
+
146
+ export default SearchContent;
@@ -17,6 +17,9 @@ export default {
17
17
  textblock: dynamic(() => import(/* webpackChunkName: "blazePbTextBlock" */ './TextBlock')),
18
18
  video: dynamic(() => import(/* webpackChunkName: "blazePbVideo" */ './Video')),
19
19
  wrapper: dynamic(() => import(/* webpackChunkName: "blazePbWrapper" */ './Wrapper')),
20
+ searchcontent: dynamic(() =>
21
+ import(/* webpackChunkName: "blazePbSearchFilter" */ './SearchContent')
22
+ ),
20
23
  searchfilter: dynamic(() =>
21
24
  import(/* webpackChunkName: "blazePbSearchFilter" */ './SearchFilter')
22
25
  ),
@@ -37,6 +40,5 @@ export default {
37
40
  ),
38
41
  passwordresetrequest: dynamic(() =>
39
42
  import(/* webpackChunkName: "blazePbPasswordResetRequest" */ './PasswordResetRequest')
40
- ),
41
- breadcrumb: dynamic(() => import(/* webpackChunkName: "blazePbBreadcrumb" */ './Breadcrumb'))
43
+ )
42
44
  };
@@ -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
  });
@@ -2,14 +2,18 @@
2
2
 
3
3
  exports[`Menu component should render without throwing an error and match snapshot 1`] = `
4
4
  <DocumentFragment>
5
- <ul
6
- class="menu-mod"
5
+ <div
6
+ class="menu--desktop-wrapper"
7
7
  >
8
- <div
9
- class="child_1"
8
+ <ul
9
+ class="menu-mod"
10
10
  >
11
- only child
12
- </div>
13
- </ul>
11
+ <div
12
+ class="child_1"
13
+ >
14
+ only child
15
+ </div>
16
+ </ul>
17
+ </div>
14
18
  </DocumentFragment>
15
19
  `;
@@ -6,10 +6,6 @@ Object {
6
6
  "$$typeof": Symbol(react.forward_ref),
7
7
  "render": [Function],
8
8
  },
9
- "breadcrumb": Object {
10
- "$$typeof": Symbol(react.forward_ref),
11
- "render": [Function],
12
- },
13
9
  "button": Object {
14
10
  "$$typeof": Symbol(react.forward_ref),
15
11
  "render": [Function],
@@ -74,6 +70,10 @@ Object {
74
70
  "$$typeof": Symbol(react.forward_ref),
75
71
  "render": [Function],
76
72
  },
73
+ "searchcontent": Object {
74
+ "$$typeof": Symbol(react.forward_ref),
75
+ "render": [Function],
76
+ },
77
77
  "searchfilter": Object {
78
78
  "$$typeof": Symbol(react.forward_ref),
79
79
  "render": [Function],
@@ -55,6 +55,16 @@ describe('getFilterProps function', () => {
55
55
  expect(!!relationProp.relationEntityName).toBe(true);
56
56
  });
57
57
 
58
+ it('should return relationEntityName key as true if relationName exists and matches in schema', () => {
59
+ const dyanmicPropFilter = getFilterProps(
60
+ 'dynamicProp',
61
+ MOCKED_SCHEMA_FOR_FILTERS,
62
+ MOCKED_SCHEMA_FOR_FILTERS
63
+ );
64
+ expect(dyanmicPropFilter).toHaveProperty('hasProperty', true);
65
+ expect(dyanmicPropFilter).toHaveProperty('shouldIgnoreFilter', false);
66
+ });
67
+
58
68
  // todo: add test case
59
69
  // it('should return relationForeignKeys array with values if it isnt a schema or relation prop', () => {
60
70
  // expect(withRelationKeys.relationForeignKeys).toBeDefined();