@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.
- package/CHANGELOG.md +27 -0
- package/lib/application/query/index.js +7 -1
- package/lib/application/query/index.js.map +1 -1
- package/lib/components/DataSummary/helpers/get-link-to-published-content.js +5 -2
- package/lib/components/DataSummary/helpers/get-link-to-published-content.js.map +1 -1
- package/lib/components/Menu/Menu.js +35 -4
- package/lib/components/Menu/Menu.js.map +1 -1
- package/lib/components/SearchContent/index.js +195 -0
- package/lib/components/SearchContent/index.js.map +1 -0
- package/lib/components/index.js +5 -5
- package/lib/components/index.js.map +1 -1
- package/lib/helpers/get-filter-props.js +3 -1
- package/lib/helpers/get-filter-props.js.map +1 -1
- package/lib-es/application/query/index.js +29 -1
- package/lib-es/application/query/index.js.map +1 -1
- package/lib-es/components/DataSummary/helpers/get-link-to-published-content.js +3 -2
- package/lib-es/components/DataSummary/helpers/get-link-to-published-content.js.map +1 -1
- package/lib-es/components/Menu/Menu.js +35 -5
- package/lib-es/components/Menu/Menu.js.map +1 -1
- package/lib-es/components/SearchContent/index.js +149 -0
- package/lib-es/components/SearchContent/index.js.map +1 -0
- package/lib-es/components/index.js +4 -4
- package/lib-es/components/index.js.map +1 -1
- package/lib-es/helpers/get-filter-props.js +2 -1
- package/lib-es/helpers/get-filter-props.js.map +1 -1
- package/package.json +2 -2
- package/src/application/query/index.js +29 -0
- package/src/components/DataSummary/helpers/get-link-to-published-content.js +4 -2
- package/src/components/Menu/Menu.js +32 -2
- package/src/components/SearchContent/index.js +146 -0
- package/src/components/index.js +4 -2
- package/src/helpers/get-filter-props.js +4 -1
- package/tests/helpers/mocks.js +6 -0
- package/tests/unit/src/components/DataSummary/helpers/get-link-to-published-content.test.js +18 -4
- package/tests/unit/src/components/Menu/__snapshots__/Menu.test.js.snap +11 -7
- package/tests/unit/src/components/__snapshots__/index.test.js.snap +4 -4
- 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;
|
package/src/components/index.js
CHANGED
|
@@ -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 = !!
|
|
27
|
+
const hasProperty = !!(
|
|
28
|
+
currentEntityProperties[filterName] || currentEntityDynamicProperties[filterName]
|
|
29
|
+
);
|
|
27
30
|
const relationEntityName = relationProp
|
|
28
31
|
? getFilterLocalKeys(relationName, currentEntityRelations)
|
|
29
32
|
: null;
|
package/tests/helpers/mocks.js
CHANGED
|
@@ -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: [
|
|
21
|
-
const result = getLinkToPublishedContent(
|
|
22
|
-
expect(result).toEqual(
|
|
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(
|
|
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
|
-
<
|
|
6
|
-
class="menu-
|
|
5
|
+
<div
|
|
6
|
+
class="menu--desktop-wrapper"
|
|
7
7
|
>
|
|
8
|
-
<
|
|
9
|
-
class="
|
|
8
|
+
<ul
|
|
9
|
+
class="menu-mod"
|
|
10
10
|
>
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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();
|