strapi-plugin-navigation 2.0.8 → 2.0.11

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.
@@ -55,7 +55,8 @@ const Item = (props) => {
55
55
  const { contentTypes, contentTypesNameFields } = config;
56
56
  const isExternal = type === navigationItemType.EXTERNAL;
57
57
  const isWrapper = type === navigationItemType.WRAPPER;
58
- const isPublished = relatedRef && relatedRef?.publishedAt;
58
+ const isHandledByPublishFlow = relatedRef && typeof relatedRef.publishedAt !== 'undefined';
59
+ const isPublished = isHandledByPublishFlow && relatedRef.publishedAt;
59
60
  const isNextMenuAllowedLevel = isNumber(allowedLevels) ? level < (allowedLevels - 1) : true;
60
61
  const isMenuAllowedLevel = isNumber(allowedLevels) ? level < allowedLevels : true;
61
62
  const hasChildren = !isEmpty(item.items) && !isExternal && !displayChildren;
@@ -121,6 +122,13 @@ const Item = (props) => {
121
122
  previewRef: dragPreview(previewRef),
122
123
  }
123
124
 
125
+ const contentTypeUid = relatedRef?.__collectionUid;
126
+ const contentType = contentTypes.find(_ => _.uid === contentTypeUid) || {};
127
+ const generatePreviewUrl = entity => {
128
+ const { isSingle } = contentType;
129
+ return `/content-manager/${ isSingle ? 'singleType' : 'collectionType'}/${entity?.__collectionUid}${!isSingle ? '/' + entity?.id : ''}`
130
+ }
131
+
124
132
  return (
125
133
  <Wrapper level={level} isLast={isLast} style={{ opacity: isDragging ? 0.2 : 1 }} ref={refs ? refs.dropRef : null} >
126
134
  <Card style={{ width: "728px", zIndex: 1, position: "relative", overflow: 'hidden' }}>
@@ -167,20 +175,20 @@ const Item = (props) => {
167
175
  </Flex>
168
176
  {relatedItemLabel && (
169
177
  <Flex justifyContent='center' alignItems='center'>
170
- <ItemCardBadge
178
+ {isHandledByPublishFlow && <ItemCardBadge
171
179
  borderColor={`${relatedBadgeColor}200`}
172
180
  backgroundColor={`${relatedBadgeColor}100`}
173
181
  textColor={`${relatedBadgeColor}600`}
174
182
  className="action"
175
183
  small
176
184
  >
177
- {getMessage({id: `components.navigationItem.badge.${isPublished ? 'published' : 'draft'}`})}
178
- </ItemCardBadge>
185
+ {getMessage({ id: `components.navigationItem.badge.${isPublished ? 'published' : 'draft'}` })}
186
+ </ItemCardBadge>}
179
187
  <Typography variant="omega" textColor='neutral600'>{relatedTypeLabel}&nbsp;/&nbsp;</Typography>
180
188
  <Typography variant="omega" textColor='neutral800'>{relatedItemLabel}</Typography>
181
- <Link
182
- to={`/content-manager/collectionType/${relatedRef?.__collectionUid}/${relatedRef?.id}`}
183
- endIcon={<ArrowRight />}>&nbsp;</Link>
189
+ { contentType?.visible && (<Link
190
+ to={generatePreviewUrl(relatedRef)}
191
+ endIcon={<ArrowRight />}>&nbsp;</Link>) }
184
192
  </Flex>)
185
193
  }
186
194
  </Flex>
@@ -94,8 +94,8 @@ const DataManagerProvider = ({ children }) => {
94
94
  } catch (err) {
95
95
  console.error({ err });
96
96
  toggleNotification({
97
- type: 'error',
98
- message: { id: 'notification.error' },
97
+ type: 'warning',
98
+ message: { id: getTrad('notification.error') },
99
99
  });
100
100
  }
101
101
  };
@@ -133,8 +133,8 @@ const DataManagerProvider = ({ children }) => {
133
133
  } catch (err) {
134
134
  console.error({ err });
135
135
  toggleNotification({
136
- type: 'error',
137
- message: { id: 'notification.error' },
136
+ type: 'warning',
137
+ message: { id: getTrad('notification.error') },
138
138
  });
139
139
  }
140
140
  };
@@ -254,7 +254,7 @@ const DataManagerProvider = ({ children }) => {
254
254
 
255
255
  if (err.response.payload.data && err.response.payload.data.errorTitles) {
256
256
  return toggleNotification({
257
- type: 'error',
257
+ type: 'warning',
258
258
  message: {
259
259
  id: formatMessage(
260
260
  getTrad('notification.navigation.error'),
@@ -264,7 +264,7 @@ const DataManagerProvider = ({ children }) => {
264
264
  });
265
265
  }
266
266
  toggleNotification({
267
- type: 'error',
267
+ type: 'warning',
268
268
  message: { id: getTrad('notification.error') },
269
269
  });
270
270
  }
@@ -31,6 +31,7 @@ import { navigationItemAdditionalFields } from '../View/utils/enums';
31
31
  import ConfirmationDialog from '../../components/ConfirmationDialog';
32
32
  import RestartAlert from '../../components/RestartAlert';
33
33
  import { getMessage } from '../../utils';
34
+ import { isContentTypeEligible, resolveGlobalLikeId } from './utils/functions';
34
35
 
35
36
  const SettingsPage = () => {
36
37
  const { lockApp, unlockApp } = useOverlayBlocker();
@@ -56,7 +57,7 @@ const SettingsPage = () => {
56
57
  additionalFields: audienceFieldChecked ? [navigationItemAdditionalFields.AUDIENCE] : [],
57
58
  allowedLevels: allowedLevels,
58
59
  gql: {
59
- navigationItemRelated: selectedContentTypes.map(uid => allContentTypes.find(ct => ct.uid === uid).info.displayName.replace(/\s+/g, ''))
60
+ navigationItemRelated: selectedContentTypes.map(uid => resolveGlobalLikeId(uid)),
60
61
  }
61
62
  });
62
63
 
@@ -108,7 +109,10 @@ const SettingsPage = () => {
108
109
  )
109
110
  }
110
111
 
111
- const allContentTypes = !isLoading && Object.values(allContentTypesData).filter(item => item.uid.includes('api::'));
112
+ const allContentTypes = !isLoading && Object.values(allContentTypesData).filter(({ uid }) => isContentTypeEligible(uid, {
113
+ allowedContentTypes: navigationConfigData?.allowedContentTypes,
114
+ restrictedContentTypes: navigationConfigData?.restrictedContentTypes,
115
+ }));
112
116
  const selectedContentTypes = navigationConfigData?.contentTypes.map(item => item.uid);
113
117
  const audienceFieldChecked = navigationConfigData?.additionalFields.includes(navigationItemAdditionalFields.AUDIENCE);
114
118
  const allowedLevels = navigationConfigData?.allowedLevels || 2;
@@ -0,0 +1,30 @@
1
+ 'use strict';
2
+
3
+ const { capitalize } = require("lodash");
4
+
5
+ const UID_REGEX = /^(?<type>[a-z0-9-]+)\:{2}(?<api>[a-z0-9-]+)\.{1}(?<contentType>[a-z0-9-]+)$/i;
6
+
7
+ const splitTypeUid = (uid = '') => {
8
+ return uid.split(UID_REGEX).filter((s) => s && s.length > 0);
9
+ };
10
+
11
+ module.exports = {
12
+ resolveGlobalLikeId(uid = '') {
13
+ const parse = (str) => str.split('-')
14
+ .map(_ => capitalize(_))
15
+ .join('');
16
+
17
+ const [type, scope, contentTypeName] = splitTypeUid(uid);
18
+ if (type === 'api') {
19
+ return parse(contentTypeName);
20
+ }
21
+ return `${parse(scope)}${parse(contentTypeName)}`;
22
+ },
23
+
24
+ isContentTypeEligible(uid = '', config = {}) {
25
+ const { allowedContentTypes = [], restrictedContentTypes = []} = config;
26
+ const isOneOfAllowedType = allowedContentTypes.filter(_ => uid.includes(_) || (uid === _)).length > 0;
27
+ const isNoneOfRestricted = restrictedContentTypes.filter(_ => uid.includes(_) || (uid === _)).length === 0;
28
+ return uid && isOneOfAllowedType && isNoneOfRestricted;
29
+ },
30
+ }
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useMemo, useState, useCallback } from 'react';
2
- import { debounce, find, get, isEmpty, isEqual, isNil, isString } from 'lodash';
2
+ import { debounce, find, get, first, isEmpty, isEqual, isNil, isString } from 'lodash';
3
3
  import PropTypes from 'prop-types';
4
4
  import { Formik } from 'formik'
5
5
  import slugify from 'slugify';
@@ -75,9 +75,11 @@ const NavigationItemForm = ({
75
75
 
76
76
  const sanitizePayload = (payload = {}) => {
77
77
  const { onItemClick, onItemLevelAddClick, related, relatedType, menuAttached, type, ...purePayload } = payload;
78
- const relatedId = related
78
+ const relatedId = related;
79
+ const singleRelatedItem = isSingleSelected ? first(contentTypeEntities) : undefined;
79
80
  const relatedCollectionType = relatedType;
80
- const title = payload.title || relatedSelectOptions.find(v => v.key == relatedId)?.label
81
+ const title = payload.title;
82
+
81
83
  return {
82
84
  ...purePayload,
83
85
  title,
@@ -88,7 +90,8 @@ const NavigationItemForm = ({
88
90
  related: type === navigationItemType.INTERNAL ? relatedId : undefined,
89
91
  relatedType: type === navigationItemType.INTERNAL ? relatedCollectionType : undefined,
90
92
  isSingle: isSingleSelected,
91
- uiRouterKey: generateUiRouterKey(purePayload.title, relatedId, relatedCollectionType),
93
+ singleRelatedItem,
94
+ uiRouterKey: generateUiRouterKey(title, relatedId, relatedCollectionType),
92
95
  };
93
96
  };
94
97
 
@@ -134,6 +137,7 @@ const NavigationItemForm = ({
134
137
  return undefined;
135
138
  };
136
139
 
140
+ const initialRelatedTypeSelected = data?.relatedType?.value;
137
141
  const relatedTypeSelectValue = form.relatedType;
138
142
  const relatedSelectValue = form.related;
139
143
 
@@ -219,6 +223,9 @@ const NavigationItemForm = ({
219
223
  () => contentTypes
220
224
  .filter((contentType) => {
221
225
  if (contentType.isSingle) {
226
+ if (relatedTypeSelectValue && [relatedTypeSelectValue, initialRelatedTypeSelected].includes(contentType.uid)) {
227
+ return true;
228
+ }
222
229
  return !usedContentTypesData.some((_) => _.__collectionUid === contentType.uid && _.__collectionUid !== form.relatedType);
223
230
  }
224
231
  return true;
@@ -232,9 +239,9 @@ const NavigationItemForm = ({
232
239
  }
233
240
  },
234
241
  value: get(item, 'uid'),
235
- label: appendLabelPublicationStatus(get(item, 'label', get(item, 'name')), item, true),
242
+ label: get(item, 'label', get(item, 'name')),
236
243
  })),
237
- [contentTypes, usedContentTypesData],
244
+ [contentTypes, usedContentTypesData, relatedTypeSelectValue],
238
245
  );
239
246
 
240
247
  const thereAreNoMoreContentTypes = isEmpty(relatedSelectOptions) && !contentTypeSearchQuery;
@@ -89,10 +89,12 @@ const linkRelations = (item, config) => {
89
89
 
90
90
  if (isSingle && relatedType) {
91
91
  const relatedContentType = contentTypes.find(_ => relatedType === _.uid) || {};
92
+ const { singleRelatedItem = {} } = item;
92
93
  return {
93
94
  ...item,
94
95
  relatedType,
95
96
  relatedRef: {
97
+ ...singleRelatedItem,
96
98
  ...omit(relatedContentType, 'collectionName'),
97
99
  isSingle,
98
100
  __collectionUid: relatedContentType.uid,
@@ -122,7 +124,7 @@ const linkRelations = (item, config) => {
122
124
 
123
125
  const shouldFindRelated = (isNumber(related) || isUuid(related) || isString(related)) && !relatedRef;
124
126
  const shouldBuildRelated = !relatedRef || (relatedRef && (relatedRef.id !== relatedId));
125
-
127
+
126
128
  if (shouldBuildRelated && !shouldFindRelated) {
127
129
  const relatedContentType = find(contentTypes,
128
130
  ct => ct.uid === relatedItem.__contentType, {});
@@ -295,9 +297,10 @@ export const isRelationPublished = ({ relatedRef, relatedType = {}, type, isColl
295
297
 
296
298
  export const validateNavigationStructure = (items = []) =>
297
299
  items.map(item =>
298
- (item.removed || isRelationCorrect({
299
- related: item.related,
300
- type: item.type,
301
- })) &&
300
+ (
301
+ item.removed ||
302
+ isRelationCorrect({ related: item.related, type: item.type }) ||
303
+ (item.isSingle && isRelationCorrect({ related: item.relatedType, type: item.type }))
304
+ ) &&
302
305
  validateNavigationStructure(item.items)
303
306
  ).filter(item => !item).length === 0;
@@ -74,9 +74,9 @@
74
74
  "pages.settings.notification.submit.error": "Config update has failed",
75
75
  "pages.settings.notification.restore.error": "Config restore has failed",
76
76
  "pages.settings.notification.restart.error": "Failed to restart your application. Try to do it manually.",
77
- "pages.settings.form.contentTypes.label": "Enable for Collection(s)",
77
+ "pages.settings.form.contentTypes.label": "Enable navigation for",
78
78
  "pages.settings.form.contentTypes.placeholder": "eg. Pages, Posts",
79
- "pages.settings.form.contentTypes.hint": "Content types that can be related with navigation items. This configuration is applicable both for REST & GraphQL",
79
+ "pages.settings.form.contentTypes.hint": "If none is selected, also none of the content types are enabled",
80
80
  "pages.settings.form.allowedLevels.label": "Allowed levels",
81
81
  "pages.settings.form.allowedLevels.placeholder": "eg. 2",
82
82
  "pages.settings.form.allowedLevels.hint": "Maximum level for which you're able to mark item as \"Menu attached\"",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-navigation",
3
- "version": "2.0.8",
3
+ "version": "2.0.11",
4
4
  "description": "Strapi - Navigation plugin",
5
5
  "strapi": {
6
6
  "name": "navigation",
@@ -25,12 +25,20 @@ module.exports = ({strapi}) => ({
25
25
  },
26
26
 
27
27
  async updateConfig(ctx) {
28
- await getService().updateConfig(ctx.request.body)
28
+ try {
29
+ await getService().updateConfig(ctx.request.body);
30
+ } catch (e) {
31
+ errorHandler(ctx)(e);
32
+ }
29
33
  return ctx.send({ status: 200 });
30
34
  },
31
35
 
32
36
  async restoreConfig(ctx) {
33
- await getService().restoreConfig()
37
+ try {
38
+ await getService().restoreConfig();
39
+ } catch (e) {
40
+ errorHandler(ctx)(e);
41
+ }
34
42
  return ctx.send({ status: 200 })
35
43
  },
36
44
 
@@ -43,7 +51,7 @@ module.exports = ({strapi}) => ({
43
51
  await getService().restart();
44
52
  return ctx.send({ status: 200 });
45
53
  } catch (e) {
46
- errorHandler(ctx, e);
54
+ errorHandler(ctx)(e);
47
55
  }
48
56
  },
49
57
 
@@ -8,7 +8,9 @@ module.exports = ({ strapi, nexus, config }) => {
8
8
  definition(t) {
9
9
  t.members(...related)
10
10
  },
11
- resolveType: (item) => strapi.contentTypes[item.__contentType]?.globalId
11
+ resolveType: (item) => {
12
+ return strapi.contentTypes[item.__contentType]?.globalId
13
+ }
12
14
  });
13
15
  }
14
16
 
@@ -11,16 +11,14 @@ const {
11
11
  toNumber,
12
12
  isString,
13
13
  first,
14
-
15
14
  } = require('lodash');
16
15
  const { validate: isUuid } = require('uuid');
17
16
  const slugify = require('slugify');
18
- const { KIND_TYPES } = require('./utils/constant');
17
+ const { KIND_TYPES, ALLOWED_CONTENT_TYPES, RESTRICTED_CONTENT_TYPES } = require('./utils/constant');
19
18
  const utilsFunctionsFactory = require('./utils/functions');
20
19
  const { renderType } = require('../content-types/navigation/lifecycle');
21
20
  const { type: itemType, additionalFields: configAdditionalFields } = require('../content-types/navigation-item').lifecycle;
22
21
  const { NotFoundError } = require('@strapi/utils').errors
23
- const excludedContentTypes = ['strapi::'];
24
22
  const contentTypesNameFieldsDefaults = ['title', 'subject', 'name'];
25
23
 
26
24
  module.exports = ({ strapi }) => {
@@ -33,9 +31,7 @@ module.exports = ({ strapi }) => {
33
31
  const entities = await strapi
34
32
  .query(masterModel.uid)
35
33
  .findMany({
36
- paggination: {
37
- limit: -1,
38
- }
34
+ limit: Number.MAX_SAFE_INTEGER,
39
35
  });
40
36
  return entities;
41
37
  },
@@ -52,9 +48,7 @@ module.exports = ({ strapi }) => {
52
48
  where: {
53
49
  master: id,
54
50
  },
55
- paggination: {
56
- limit: -1,
57
- },
51
+ limit: Number.MAX_SAFE_INTEGER,
58
52
  sort: ['order:asc'],
59
53
  populate: ['related', 'parent', 'audience']
60
54
  });
@@ -71,8 +65,8 @@ module.exports = ({ strapi }) => {
71
65
 
72
66
  // Get plugin config
73
67
  async config(viaSettingsPage = false) {
74
- const { audienceModel, service } = utilsFunctions.extractMeta(strapi.plugins);
75
- const pluginStore = await strapi.plugin('navigation').service('navigation').getPluginStore()
68
+ const { audienceModel } = utilsFunctions.extractMeta(strapi.plugins);
69
+ const pluginStore = await this.getPluginStore()
76
70
  const config = await pluginStore.get({ key: 'config' });
77
71
  const additionalFields = config.additionalFields;
78
72
  const contentTypesNameFields = config.contentTypesNameFields;
@@ -80,9 +74,12 @@ module.exports = ({ strapi }) => {
80
74
  const allowedLevels = config.allowedLevels;
81
75
  const isGQLPluginEnabled = !isNil(strapi.plugin('graphql'));
82
76
 
83
- let extendedResult = {};
77
+ let extendedResult = {
78
+ allowedContentTypes: ALLOWED_CONTENT_TYPES,
79
+ restrictedContentTypes: RESTRICTED_CONTENT_TYPES,
80
+ };
84
81
  const result = {
85
- contentTypes: await service.configContentTypes(),
82
+ contentTypes: await this.configContentTypes(),
86
83
  contentTypesNameFields: {
87
84
  default: contentTypesNameFieldsDefaults,
88
85
  ...(isObject(contentTypesNameFields) ? contentTypesNameFields : {}),
@@ -99,9 +96,7 @@ module.exports = ({ strapi }) => {
99
96
  const audienceItems = await strapi
100
97
  .query(audienceModel.uid)
101
98
  .findMany({
102
- paggination: {
103
- limit: -1,
104
- }
99
+ limit: Number.MAX_SAFE_INTEGER,
105
100
  });
106
101
  extendedResult = {
107
102
  ...extendedResult,
@@ -115,7 +110,7 @@ module.exports = ({ strapi }) => {
115
110
  },
116
111
 
117
112
  async updateConfig(newConfig) {
118
- const pluginStore = await strapi.plugin('navigation').service('navigation').getPluginStore()
113
+ const pluginStore = await this.getPluginStore()
119
114
  await pluginStore.set({ key: 'config', value: newConfig });
120
115
  },
121
116
 
@@ -124,7 +119,7 @@ module.exports = ({ strapi }) => {
124
119
  },
125
120
 
126
121
  async setDefaultConfig() {
127
- const pluginStore = await strapi.plugin('navigation').service('navigation').getPluginStore()
122
+ const pluginStore = await this.getPluginStore()
128
123
  const config = await pluginStore.get({ key: 'config' });
129
124
  const pluginDefaultConfig = await strapi.plugin('navigation').config
130
125
 
@@ -133,10 +128,10 @@ module.exports = ({ strapi }) => {
133
128
  const defaultConfigValue = {
134
129
  additionalFields: get(config, 'additionalFields', pluginDefaultConfig('additionalFields')),
135
130
  contentTypes: get(config, 'contentTypes', pluginDefaultConfig('contentTypes')),
136
- contentTypesNameFields: get(config, 'contentTypesNameFields', pluginDefaultConfig('contentTypesNameFields')),
137
- contentTypesPopulate: get(config, 'contentTypesPopulate', pluginDefaultConfig('contentTypesPopulate')),
138
- allowedLevels: get(config, 'allowedLevels', pluginDefaultConfig('allowedLevels')),
139
- gql: get(config, 'gql', pluginDefaultConfig('gql')),
131
+ contentTypesNameFields: get(config, 'contentTypesNameFields', pluginDefaultConfig('contentTypesNameFields')),
132
+ contentTypesPopulate: get(config, 'contentTypesPopulate', pluginDefaultConfig('contentTypesPopulate')),
133
+ allowedLevels: get(config, 'allowedLevels', pluginDefaultConfig('allowedLevels')),
134
+ gql: get(config, 'gql', pluginDefaultConfig('gql')),
140
135
  }
141
136
  pluginStore.set({ key: 'config', value: defaultConfigValue });
142
137
 
@@ -144,23 +139,20 @@ module.exports = ({ strapi }) => {
144
139
  },
145
140
 
146
141
  async restoreConfig() {
147
- const pluginStore = await strapi.plugin('navigation').service('navigation').getPluginStore()
142
+ const pluginStore = await this.getPluginStore()
148
143
  await pluginStore.delete({ key: 'config' });
149
144
  await strapi.plugin('navigation').service('navigation').setDefaultConfig();
150
145
  },
151
146
 
152
147
  async configContentTypes() {
153
- const pluginStore = await strapi.plugin('navigation').service('navigation').getPluginStore()
148
+ const pluginStore = await this.getPluginStore()
154
149
  const config = await pluginStore.get({ key: 'config' });
155
150
  const eligibleContentTypes =
156
151
  await Promise.all(
157
152
  config.contentTypes
158
- .filter(contentType => !!strapi.contentTypes[contentType])
153
+ .filter(contentType => !!strapi.contentTypes[contentType] && utilsFunctions.isContentTypeEligible(contentType))
159
154
  .map(
160
155
  async (key) => {
161
- if (find(excludedContentTypes, name => key.includes(name))) { // exclude internal content types
162
- return;
163
- }
164
156
  const item = strapi.contentTypes[key];
165
157
  const { kind, options, uid } = item;
166
158
  const { draftAndPublish } = options;
@@ -194,9 +186,10 @@ module.exports = ({ strapi }) => {
194
186
  .map(({ key, available }) => {
195
187
  const item = strapi.contentTypes[key];
196
188
  const relatedField = (item.associations || []).find(_ => _.model === 'navigationitem');
197
- const { uid, options, info, collectionName, modelName, apiName, plugin, kind } = item;
189
+ const { uid, options, info, collectionName, modelName, apiName, plugin, kind, pluginOptions } = item;
190
+ const { visible = true } = pluginOptions['content-manager'] || {};
198
191
  const { name, description } = info;
199
- const { isManaged, hidden, templateName } = options;
192
+ const { hidden, templateName } = options;
200
193
  const findRouteConfig = find(get(strapi.api, `[${modelName}].config.routes`, []),
201
194
  route => route.handler.includes('.find'));
202
195
  const findRoutePath = findRouteConfig && findRouteConfig.path.split('/')[1];
@@ -221,12 +214,12 @@ module.exports = ({ strapi }) => {
221
214
  labelSingular: utilsFunctions.singularize(labelSingular),
222
215
  endpoint,
223
216
  plugin,
224
- available,
225
- visible: (isManaged || isNil(isManaged)) && !hidden,
217
+ available: available && !hidden,
218
+ visible,
226
219
  templateName,
227
220
  };
228
221
  })
229
- .filter((item) => item && item.visible);
222
+ .filter((item) => item && item.available);
230
223
  },
231
224
 
232
225
  async getRelatedItems(entityItems) {
@@ -399,9 +392,7 @@ module.exports = ({ strapi }) => {
399
392
  master: entity.id,
400
393
  ...itemCriteria,
401
394
  },
402
- paggination: {
403
- limit: -1,
404
- },
395
+ limit: Number.MAX_SAFE_INTEGER,
405
396
  sort: ['order:asc'],
406
397
  populate: ['related', 'audience', 'parent'],
407
398
  });
@@ -428,6 +419,7 @@ module.exports = ({ strapi }) => {
428
419
  id: item.id,
429
420
  title: utilsFunctions.composeItemTitle(item, contentTypesNameFields, contentTypes),
430
421
  menuAttached: item.menuAttached,
422
+ order: item.order,
431
423
  path: isExternal ? item.externalPath : parentPath,
432
424
  type: item.type,
433
425
  uiRouterKey: item.uiRouterKey,
@@ -511,7 +503,10 @@ module.exports = ({ strapi }) => {
511
503
  .filter(utilsFunctions.filterOutUnpublished)
512
504
  .map(item => itemParser({
513
505
  ...item,
514
- }, path, field));
506
+ }, path, field))
507
+ .sort((x, y) => {
508
+ return x.order - y.order;
509
+ });
515
510
  },
516
511
 
517
512
  renderRFR({ items, parent = null, parentNavItem = null, contentTypes = [] }) {
@@ -632,7 +627,7 @@ module.exports = ({ strapi }) => {
632
627
  }
633
628
  const navigationItem = await strapi
634
629
  .query(itemModel.uid)
635
- .create({ data });
630
+ .create({ data, populate: ['related', 'items'] });
636
631
  return !isEmpty(item.items)
637
632
  ? service.createBranch(
638
633
  item.items,
@@ -735,7 +730,6 @@ module.exports = ({ strapi }) => {
735
730
  if (relatedItems) {
736
731
  return Promise.all(relatedItems.map(async relatedItem => {
737
732
  try {
738
-
739
733
  const model = strapi.query('plugin::navigation.navigations-items-related');
740
734
  const entity = await model
741
735
  .findOne({
@@ -8,5 +8,14 @@ module.exports = {
8
8
 
9
9
  MODEL_TYPES: {
10
10
  CONTENT_TYPE: 'contentType'
11
- }
11
+ },
12
+ ALLOWED_CONTENT_TYPES: [
13
+ 'api::',
14
+ 'plugin::'
15
+ ],
16
+ RESTRICTED_CONTENT_TYPES: [
17
+ 'plugin::users-permissions',
18
+ 'plugin::i18n.locale',
19
+ 'plugin::navigation',
20
+ ],
12
21
  };
@@ -13,7 +13,7 @@ const {
13
13
 
14
14
  const { type: itemType } = require('../../content-types/navigation-item/lifecycle');
15
15
  const { NavigationError } = require('../../../utils/NavigationError');
16
- const { TEMPLATE_DEFAULT } = require('./constant');
16
+ const { TEMPLATE_DEFAULT, ALLOWED_CONTENT_TYPES, RESTRICTED_CONTENT_TYPES } = require('./constant');
17
17
 
18
18
  module.exports = ({ strapi }) => {
19
19
  return {
@@ -216,5 +216,11 @@ module.exports = ({ strapi }) => {
216
216
  }
217
217
  return (item.type !== itemType.INTERNAL) || relatedItem;
218
218
  },
219
+
220
+ isContentTypeEligible(uid = '') {
221
+ const isOneOfAllowedType = ALLOWED_CONTENT_TYPES.filter(_ => uid.includes(_)).length > 0;
222
+ const isNoneOfRestricted = RESTRICTED_CONTENT_TYPES.filter(_ => uid.includes(_) || (uid === _)).length === 0;
223
+ return uid && isOneOfAllowedType && isNoneOfRestricted;
224
+ },
219
225
  };
220
226
  }