strapi-plugin-navigation 1.1.0 → 1.1.4
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/README.md
CHANGED
|
@@ -23,6 +23,11 @@ A plugin for [Strapi Headless CMS](https://github.com/strapi/strapi) that provid
|
|
|
23
23
|
|
|
24
24
|
<img src="public/assets/preview.png" alt="UI preview" />
|
|
25
25
|
|
|
26
|
+
### ⚙️ Versions
|
|
27
|
+
|
|
28
|
+
- **Strapi v4** - [v2.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation)
|
|
29
|
+
- **Strapi v3** - (current) - [v1.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation/tree/strapi-v3)
|
|
30
|
+
|
|
26
31
|
### ⏳ Installation
|
|
27
32
|
|
|
28
33
|
(Use **yarn** to install this plugin within your Strapi project (recommended). [Install yarn with these docs](https://yarnpkg.com/lang/en/docs/install/).)
|
|
@@ -73,40 +78,22 @@ Complete installation requirements are exact same as for Strapi itself and can b
|
|
|
73
78
|
|
|
74
79
|
## Content Type model relation to Navigation Item
|
|
75
80
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
inside the `attributes` section like in example below:
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
"attributes": {
|
|
92
|
-
...,
|
|
93
|
-
"navigation": {
|
|
94
|
-
"model": "navigationitem",
|
|
95
|
-
"plugin": "navigation",
|
|
96
|
-
"via": "related",
|
|
97
|
-
"configurable": false,
|
|
98
|
-
"hidden": true
|
|
99
|
-
},
|
|
100
|
-
...
|
|
101
|
-
},
|
|
81
|
+
We can define in `config/plugins.js`
|
|
82
|
+
```js
|
|
83
|
+
navigation: {
|
|
84
|
+
...
|
|
85
|
+
relatedContentTypes: [
|
|
86
|
+
'application::pages.pages'
|
|
87
|
+
],
|
|
88
|
+
...
|
|
89
|
+
},
|
|
102
90
|
```
|
|
103
91
|
|
|
104
92
|
## Configuration
|
|
105
|
-
To setup the plugin properly we recommend to put following snippet as part of `config/
|
|
93
|
+
To setup the plugin properly we recommend to put following snippet as part of `config/plugins.js` or `config/<env>/plugins.js` file. If you've got already configurations for other plugins stores by this way, use just the `navigation` part within exising `plugins` item.
|
|
106
94
|
|
|
107
95
|
```js
|
|
108
96
|
...
|
|
109
|
-
plugins: {
|
|
110
97
|
navigation: {
|
|
111
98
|
additionalFields: ['audience'],
|
|
112
99
|
allowedLevels: 2,
|
|
@@ -116,7 +103,6 @@ To setup the plugin properly we recommend to put following snippet as part of `c
|
|
|
116
103
|
},
|
|
117
104
|
gql: { ... }
|
|
118
105
|
},
|
|
119
|
-
},
|
|
120
106
|
...
|
|
121
107
|
```
|
|
122
108
|
|
|
@@ -427,7 +413,8 @@ For general help using Strapi, please refer to [the official Strapi documentatio
|
|
|
427
413
|
- [Slack](http://slack.strapi.io) We're present on official Strapi slack workspace. Look for @cyp3r and DM.
|
|
428
414
|
- [Slack - VirtusLab Open Source](https://virtuslab-oss.slack.com) We're present on a public channel #strapi-molecules
|
|
429
415
|
- [GitHub](https://github.com/VirtusLab/strapi-plugin-navigation/issues) (Bug reports, Contributions, Questions and Discussions)
|
|
416
|
+
- [E-mail](mailto:strapi@virtuslab.com) - we will respond back as soon as possible
|
|
430
417
|
|
|
431
418
|
## License
|
|
432
419
|
|
|
433
|
-
[MIT License](LICENSE.md) Copyright (c)
|
|
420
|
+
[MIT License](LICENSE.md) Copyright (c) [VirtusLab Sp. z o.o.](https://virtuslab.com/) & [Strapi Solutions](https://strapi.io/).
|
|
@@ -36,7 +36,6 @@ const DataManagerProvider = ({ children }) => {
|
|
|
36
36
|
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
|
37
37
|
const {
|
|
38
38
|
autoReload,
|
|
39
|
-
emitEvent,
|
|
40
39
|
currentEnvironment,
|
|
41
40
|
formatMessage,
|
|
42
41
|
} = useGlobalContext();
|
|
@@ -195,47 +194,36 @@ const DataManagerProvider = ({ children }) => {
|
|
|
195
194
|
};
|
|
196
195
|
|
|
197
196
|
const handleChangeNavigationPopupVisibility = (visible) => {
|
|
198
|
-
emitEvent("willChangeNavigationPopupVisibility");
|
|
199
197
|
dispatch({
|
|
200
198
|
type: CHANGE_NAVIGATION_POPUP_VISIBILITY,
|
|
201
199
|
navigationPopupOpened: visible,
|
|
202
200
|
});
|
|
203
|
-
emitEvent("didChangeNavigationPopupVisibility");
|
|
204
|
-
emitEvent(`navigationPopup${visible ? "Visible" : "Hidden"}`);
|
|
205
201
|
};
|
|
206
202
|
|
|
207
203
|
const handleChangeNavigationItemPopupVisibility = (visible) => {
|
|
208
|
-
emitEvent("willChangeNavigationItemPopupVisibility");
|
|
209
204
|
dispatch({
|
|
210
205
|
type: CHANGE_NAVIGATION_ITEM_POPUP_VISIBILITY,
|
|
211
206
|
navigationItemPopupOpened: visible,
|
|
212
207
|
});
|
|
213
|
-
emitEvent("didChangeNavigationItemPopupVisibility");
|
|
214
|
-
emitEvent(`navigationItemPopup${visible ? "Visible" : "Hidden"}`);
|
|
215
208
|
};
|
|
216
209
|
|
|
217
210
|
const handleChangeNavigationData = (payload, forceClosePopups) => {
|
|
218
|
-
emitEvent("willChangeNavigationData");
|
|
219
211
|
dispatch({
|
|
220
212
|
type: CHANGE_NAVIGATION_DATA,
|
|
221
213
|
changedActiveItem: payload,
|
|
222
214
|
forceClosePopups,
|
|
223
215
|
});
|
|
224
|
-
emitEvent("didChangeNavigationData");
|
|
225
216
|
};
|
|
226
217
|
|
|
227
218
|
const handleResetNavigationData = () => {
|
|
228
|
-
emitEvent("willResetNavigationChanges");
|
|
229
219
|
dispatch({
|
|
230
220
|
type: RESET_NAVIGATION_DATA,
|
|
231
221
|
activeItem,
|
|
232
222
|
});
|
|
233
|
-
emitEvent("didResetNavigationChanges");
|
|
234
223
|
};
|
|
235
224
|
|
|
236
225
|
const handleSubmitNavigation = async (formatMessage, payload = {}) => {
|
|
237
226
|
try {
|
|
238
|
-
emitEvent("willSubmitNavigation");
|
|
239
227
|
dispatch({
|
|
240
228
|
type: SUBMIT_NAVIGATION,
|
|
241
229
|
});
|
|
@@ -255,7 +243,6 @@ const DataManagerProvider = ({ children }) => {
|
|
|
255
243
|
items: prepareItemToViewPayload(navigation.items, null, config),
|
|
256
244
|
},
|
|
257
245
|
});
|
|
258
|
-
emitEvent("didSubmitNavigation");
|
|
259
246
|
|
|
260
247
|
strapi.notification.success(getTradId('notification.navigation.submit'));
|
|
261
248
|
} catch (err) {
|
|
@@ -264,7 +251,6 @@ const DataManagerProvider = ({ children }) => {
|
|
|
264
251
|
error: err.response.payload.data
|
|
265
252
|
});
|
|
266
253
|
console.error({ err: err.response });
|
|
267
|
-
emitEvent('didNotSubmitNavigation');
|
|
268
254
|
if (err.response.payload.data && err.response.payload.data.errorTitles) {
|
|
269
255
|
return strapi.notification.error(
|
|
270
256
|
formatMessage(
|
|
@@ -252,7 +252,7 @@ export const extractRelatedItemLabel = (item = {}, fields = {}, config = {}) =>
|
|
|
252
252
|
const { __collectionName } = item;
|
|
253
253
|
const contentType = contentTypes.find(_ => _.uid === __collectionName)
|
|
254
254
|
const { default: defaultFields = [] } = fields;
|
|
255
|
-
return get(fields, `${contentType ? contentType.collectionName :
|
|
255
|
+
return get(fields, `${contentType ? contentType.collectionName : __collectionName}`, defaultFields).map((_) => item[_]).filter((_) => _)[0] || '';
|
|
256
256
|
};
|
|
257
257
|
|
|
258
258
|
export const usedContentTypes = (items = []) => items.flatMap(
|
package/config/schema.graphql.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const {get} = require('lodash');
|
|
2
1
|
const NAVIGATION_DATE = `
|
|
3
2
|
# SQL
|
|
4
3
|
created_at: String
|
|
@@ -25,12 +24,12 @@ const NAVIGATION = `
|
|
|
25
24
|
`;
|
|
26
25
|
|
|
27
26
|
const getContentTypesNamesFields = () => {
|
|
28
|
-
const contentTypesNameFields = strapi.config.get('
|
|
27
|
+
const contentTypesNameFields = strapi.config.get('plugins.navigation.contentTypesNameFields');
|
|
29
28
|
return Object.keys(contentTypesNameFields || {}).map(key => `${key}: [String]!`).join('\n');
|
|
30
29
|
};
|
|
31
30
|
|
|
32
31
|
const getNavigationRelated = () => {
|
|
33
|
-
const related = strapi.config.get('
|
|
32
|
+
const related = strapi.config.get('plugins.navigation.gql.navigationItemRelated');
|
|
34
33
|
if (related) {
|
|
35
34
|
return related;
|
|
36
35
|
}
|
|
@@ -67,7 +66,7 @@ module.exports = {
|
|
|
67
66
|
parent: Int
|
|
68
67
|
master: Int
|
|
69
68
|
items: [NavigationItem]
|
|
70
|
-
related: NavigationRelated
|
|
69
|
+
related: [NavigationRelated]
|
|
71
70
|
audience: [String]
|
|
72
71
|
${NAVIGATION_DATE}
|
|
73
72
|
${NAVIGATION_USER}
|
|
@@ -149,6 +148,11 @@ module.exports = {
|
|
|
149
148
|
navigationUpdate(id: String!, navigation: CreateNavigation!): Navigation!
|
|
150
149
|
`,
|
|
151
150
|
resolver: {
|
|
151
|
+
NavigationRelated: {
|
|
152
|
+
__resolveType: (data) => {
|
|
153
|
+
return strapi.contentTypes[data.__contentType]?.globalId
|
|
154
|
+
}
|
|
155
|
+
},
|
|
152
156
|
Query: {
|
|
153
157
|
renderNavigation: {
|
|
154
158
|
resolverOf: 'plugins::navigation.navigation.render',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-navigation",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Strapi - Navigation plugin",
|
|
5
5
|
"strapi": {
|
|
6
6
|
"name": "Navigation",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"reactstrap": "8.4.1",
|
|
28
28
|
"redux-saga": "^0.16.0",
|
|
29
29
|
"request": "^2.83.0",
|
|
30
|
-
"strapi-helper-plugin": "3.6.
|
|
31
|
-
"strapi-utils": "3.6.
|
|
30
|
+
"strapi-helper-plugin": "3.6.8",
|
|
31
|
+
"strapi-utils": "3.6.8",
|
|
32
32
|
"uuidv4": "^6.2.6",
|
|
33
33
|
"slugify": "^1.4.5",
|
|
34
34
|
"pluralize": "^8.0.0"
|
|
@@ -40,6 +40,9 @@
|
|
|
40
40
|
"jest-styled-components": "^7.0.2",
|
|
41
41
|
"codecov": "^3.7.2"
|
|
42
42
|
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"strapi": "3.x"
|
|
45
|
+
},
|
|
43
46
|
"author": {
|
|
44
47
|
"name": "VirtusLab // Mateusz Ziarko",
|
|
45
48
|
"email": "mziarko@virtuslab.com",
|
package/services/navigation.js
CHANGED
|
@@ -36,9 +36,9 @@ const contentTypesNameFieldsDefaults = [
|
|
|
36
36
|
'subject',
|
|
37
37
|
'name',
|
|
38
38
|
];
|
|
39
|
-
const
|
|
39
|
+
const getContentTypesNameFields = () => get(
|
|
40
40
|
strapi.config,
|
|
41
|
-
'
|
|
41
|
+
'plugins.navigation.contentTypesNameFields',
|
|
42
42
|
{},
|
|
43
43
|
);
|
|
44
44
|
|
|
@@ -51,15 +51,15 @@ module.exports = {
|
|
|
51
51
|
// Get plugin configuration
|
|
52
52
|
async config() {
|
|
53
53
|
const { pluginName, service, audienceModel } = utilsFunctions.extractMeta(strapi.plugins);
|
|
54
|
-
const additionalFields = get(strapi.config, '
|
|
54
|
+
const additionalFields = get(strapi.config, 'plugins.navigation.additionalFields', []);
|
|
55
55
|
let extendedResult = {};
|
|
56
56
|
const result = {
|
|
57
57
|
contentTypes: await service.configContentTypes(),
|
|
58
58
|
contentTypesNameFields: {
|
|
59
59
|
default: contentTypesNameFieldsDefaults,
|
|
60
|
-
...(
|
|
60
|
+
...getContentTypesNameFields(),
|
|
61
61
|
},
|
|
62
|
-
allowedLevels: get(strapi.config, '
|
|
62
|
+
allowedLevels: get(strapi.config, 'plugins.navigation.allowedLevels'),
|
|
63
63
|
additionalFields,
|
|
64
64
|
};
|
|
65
65
|
|
|
@@ -185,7 +185,8 @@ module.exports = {
|
|
|
185
185
|
_limit: -1,
|
|
186
186
|
_sort: 'order:asc',
|
|
187
187
|
});
|
|
188
|
-
|
|
188
|
+
let entities = await this.getRelatedItems(entityItems);
|
|
189
|
+
entities = entities.map((_) => sanitizeEntity(_, { model: itemModel }));
|
|
189
190
|
return {
|
|
190
191
|
...sanitizeEntity(entity,
|
|
191
192
|
{ model: masterModel },
|
|
@@ -301,7 +302,8 @@ module.exports = {
|
|
|
301
302
|
if (!entities) {
|
|
302
303
|
return [];
|
|
303
304
|
}
|
|
304
|
-
|
|
305
|
+
let items = await this.getRelatedItems(entities);
|
|
306
|
+
items = items.map((_) => sanitizeEntity(_, { model: itemModel }));
|
|
305
307
|
const { contentTypes, contentTypesNameFields } = await service.config();
|
|
306
308
|
|
|
307
309
|
switch (type?.toLowerCase()) {
|
|
@@ -327,7 +329,7 @@ module.exports = {
|
|
|
327
329
|
external: isExternal,
|
|
328
330
|
related: isExternal || !lastRelated ? undefined : {
|
|
329
331
|
...lastRelated,
|
|
330
|
-
__templateName: getTemplateName(lastRelated.relatedType, lastRelated.id),
|
|
332
|
+
__templateName: getTemplateName(lastRelated.relatedType || lastRelated.__contentType, lastRelated.id),
|
|
331
333
|
},
|
|
332
334
|
audience: !isEmpty(item.audience) ? item.audience.map(aItem => aItem.key) : undefined,
|
|
333
335
|
items: isExternal ? undefined : service.renderTree({
|