strapi-plugin-navigation 2.0.0 → 2.0.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.
Files changed (42) hide show
  1. package/README.md +50 -5
  2. package/__mocks__/strapi.js +30 -19
  3. package/admin/src/components/ConfirmationDialog/index.js +56 -0
  4. package/admin/src/components/Item/ItemCardBadge/index.js +1 -1
  5. package/admin/src/components/Item/ItemCardHeader/index.js +6 -12
  6. package/admin/src/components/Item/index.js +8 -10
  7. package/admin/src/components/RestartAlert/index.js +8 -0
  8. package/admin/src/hooks/useAllContentTypes.js +13 -0
  9. package/admin/src/hooks/useNavigationConfig.js +58 -0
  10. package/admin/src/index.js +24 -1
  11. package/admin/src/pages/SettingsPage/index.js +311 -0
  12. package/admin/src/pages/View/components/NavigationItemForm/index.js +36 -9
  13. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +3 -6
  14. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +2 -4
  15. package/admin/src/pages/View/components/NavigationItemPopup/index.js +2 -4
  16. package/admin/src/translations/en.json +48 -8
  17. package/admin/src/translations/fr.json +4 -4
  18. package/admin/src/utils/api.js +51 -0
  19. package/admin/src/utils/index.js +20 -0
  20. package/package.json +5 -5
  21. package/server/bootstrap.js +30 -1
  22. package/server/controllers/navigation.js +30 -5
  23. package/server/graphql/index.js +3 -4
  24. package/server/graphql/queries/render-navigation.js +4 -3
  25. package/server/graphql/types/content-types-name-fields.js +4 -2
  26. package/server/graphql/types/navigation-related.js +2 -2
  27. package/server/routes/admin.js +24 -1
  28. package/server/services/__tests__/functions.test.js +48 -0
  29. package/server/services/__tests__/navigation.test.js +26 -4
  30. package/server/services/navigation.js +56 -16
  31. package/server/services/utils/functions.js +41 -0
  32. package/strapi-server.js +0 -2
  33. package/yarn-error.log +5263 -0
  34. package/.circleci/config.yml +0 -48
  35. package/.eslintrc +0 -35
  36. package/.github/pull_request_template.md +0 -13
  37. package/.github/stale.yml +0 -15
  38. package/.nvmrc +0 -1
  39. package/codecov.yml +0 -3
  40. package/public/assets/logo.png +0 -0
  41. package/public/assets/preview.png +0 -0
  42. package/server/register.js +0 -5
@@ -0,0 +1,20 @@
1
+ import { useIntl } from 'react-intl';
2
+ import { isString } from 'lodash';
3
+
4
+ import pluginId from '../pluginId';
5
+
6
+ const getMessage = (input, defaultMessage = '', inPluginScope = true) => {
7
+ const { formatMessage } = useIntl();
8
+ let formattedId = ''
9
+ if (isString(input)) {
10
+ formattedId = input;
11
+ } else {
12
+ formattedId = input?.id;
13
+ }
14
+ return formatMessage({
15
+ id: `${inPluginScope ? pluginId : 'app.components'}.${formattedId}`,
16
+ defaultMessage,
17
+ }, input?.props || undefined)
18
+ };
19
+
20
+ export { getMessage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-navigation",
3
- "version": "2.0.0",
3
+ "version": "2.0.4",
4
4
  "description": "Strapi - Navigation plugin",
5
5
  "strapi": {
6
6
  "name": "navigation",
@@ -13,11 +13,11 @@
13
13
  "url": "https://github.com/VirtusLab/strapi-plugin-navigation"
14
14
  },
15
15
  "scripts": {
16
- "publish": "npm publish --tag latest",
16
+ "publish:latest": "npm publish --tag latest",
17
17
  "test:unit": "jest --verbose --coverage"
18
18
  },
19
19
  "dependencies": {
20
- "@strapi/utils": "^4.0.7",
20
+ "@strapi/utils": "^4.1.0",
21
21
  "uuid": "^8.3.0",
22
22
  "bad-words": "^3.0.3",
23
23
  "lodash": "^4.17.11",
@@ -44,8 +44,8 @@
44
44
  "@strapi/strapi": "4.x"
45
45
  },
46
46
  "author": {
47
- "name": "VirtusLab // Mateusz Ziarko",
48
- "email": "mziarko@virtuslab.com",
47
+ "name": "VirtusLab",
48
+ "email": "strapi@virtuslab.com",
49
49
  "url": "https://virtuslab.com"
50
50
  },
51
51
  "maintainers": [
@@ -23,7 +23,9 @@ module.exports = async ({ strapi }) => {
23
23
  pluginName: "navigation",
24
24
  },
25
25
  ];
26
+ await strapi.admin.services.permission.actionProvider.registerMany(actions);
26
27
 
28
+ // Initialize first navigation
27
29
  const navigations = await strapi
28
30
  .query("plugin::navigation.navigation")
29
31
  .findMany();
@@ -38,5 +40,32 @@ module.exports = async ({ strapi }) => {
38
40
  }
39
41
  });
40
42
  }
41
- await strapi.admin.services.permission.actionProvider.registerMany(actions);
43
+
44
+ // Initialize configuration
45
+ const pluginStore = strapi.store({
46
+ environment: '',
47
+ type: 'plugin',
48
+ name: 'navigation',
49
+ });
50
+
51
+ const config = await pluginStore.get({ key: 'config' });
52
+ const pluginDefaultConfig = await strapi.plugin('navigation').config
53
+ const defaultConfigValue = {
54
+ additionalFields: pluginDefaultConfig('additionalFields'),
55
+ contentTypes: pluginDefaultConfig('contentTypes'),
56
+ contentTypesNameFields: pluginDefaultConfig('contentTypesNameFields'),
57
+ allowedLevels: pluginDefaultConfig('allowedLevels'),
58
+ gql: pluginDefaultConfig('gql'),
59
+ }
60
+
61
+ if (!config) {
62
+ pluginStore.set({
63
+ key: 'config', value: defaultConfigValue
64
+ });
65
+ }
66
+
67
+ if (strapi.plugin('graphql')) {
68
+ const graphqlConfiguration = require('./graphql')
69
+ await graphqlConfiguration({ strapi, config: config || defaultConfigValue });
70
+ }
42
71
  };
@@ -19,10 +19,34 @@ const errorHandler = (ctx) => (error) => {
19
19
  throw error;
20
20
  };
21
21
 
22
- module.exports = {
22
+ module.exports = ({strapi}) => ({
23
23
  async config() {
24
24
  return getService().config();
25
25
  },
26
+
27
+ async updateConfig(ctx) {
28
+ await getService().updateConfig(ctx.request.body)
29
+ return ctx.send({ status: 200 });
30
+ },
31
+
32
+ async restoreConfig(ctx) {
33
+ await getService().restoreConfig()
34
+ return ctx.send({ status: 200 })
35
+ },
36
+
37
+ async settingsConfig() {
38
+ return getService().config(true);
39
+ },
40
+
41
+ async settingsRestart(ctx) {
42
+ try {
43
+ await getService().restart();
44
+ return ctx.send({ status: 200 });
45
+ } catch (e) {
46
+ errorHandler(ctx, e);
47
+ }
48
+ },
49
+
26
50
  async get() {
27
51
  return getService().get();
28
52
  },
@@ -50,13 +74,14 @@ module.exports = {
50
74
  },
51
75
  async render(ctx) {
52
76
  const { params, query = {} } = ctx;
53
- const { type, menu: menuOnly } = query;
77
+ const { type, menu: menuOnly, path: rootPath } = query;
54
78
  const { idOrSlug } = parseParams(params);
55
- return getService().render(
79
+ return getService().render({
56
80
  idOrSlug,
57
81
  type,
58
82
  menuOnly,
59
- );
83
+ rootPath
84
+ });
60
85
  },
61
86
  async renderChild(ctx) {
62
87
  const { params, query = {} } = ctx;
@@ -69,4 +94,4 @@ module.exports = {
69
94
  menuOnly
70
95
  );
71
96
  },
72
- };
97
+ });
@@ -2,16 +2,15 @@ const getTypes = require('./types');
2
2
  const getQueries = require('./queries');
3
3
  const getResolversConfig = require('./resolvers-config');
4
4
 
5
- module.exports = () => {
5
+ module.exports = async ({ strapi, config }) => {
6
6
  const extensionService = strapi.plugin('graphql').service('extension');
7
-
8
7
  extensionService.shadowCRUD('plugin::navigation.audience').disable();
9
8
  extensionService.shadowCRUD('plugin::navigation.navigation').disable();
10
9
  extensionService.shadowCRUD('plugin::navigation.navigation-item').disable();
11
10
  extensionService.shadowCRUD('plugin::navigation.navigations-items-related').disable();
12
11
 
13
- extensionService.use(({ nexus }) => {
14
- const types = getTypes({ strapi, nexus });
12
+ extensionService.use(({strapi, nexus}) => {
13
+ const types = getTypes({ strapi, nexus, config });
15
14
  const queries = getQueries({ strapi, nexus });
16
15
  const resolversConfig = getResolversConfig({ strapi });
17
16
 
@@ -5,11 +5,12 @@ module.exports = ({ strapi, nexus }) => {
5
5
  args: {
6
6
  navigationIdOrSlug: nonNull(stringArg()),
7
7
  type: 'NavigationRenderType',
8
- menuOnly: booleanArg()
8
+ menuOnly: booleanArg(),
9
+ path: stringArg(),
9
10
  },
10
11
  resolve(obj, args) {
11
- const { navigationIdOrSlug, type, menuOnly } = args;
12
- return strapi.plugin('navigation').service('navigation').render(navigationIdOrSlug, type, menuOnly);
12
+ const { navigationIdOrSlug: idOrSlug, type, menuOnly, path: rootPath } = args;
13
+ return strapi.plugin('navigation').service('navigation').render({idOrSlug, type, menuOnly, rootPath});
13
14
  },
14
15
  };
15
16
  }
@@ -1,8 +1,10 @@
1
1
  module.exports = ({ nexus }) => nexus.objectType({
2
2
  name: "ContentTypesNameFields",
3
- definition(t) {
3
+ async definition(t) {
4
4
  t.nonNull.list.nonNull.string("default")
5
- const contentTypesNameFields = strapi.plugin('navigation').config('contentTypesNameFields')
5
+ const pluginStore = strapi.store({ type: 'plugin', name: 'navigation' });
6
+ const config = await pluginStore.get({ key: 'config' });
7
+ const contentTypesNameFields = config.contentTypesNameFields;
6
8
  Object.keys(contentTypesNameFields || {}).forEach(key => t.nonNull.list.string(key))
7
9
  }
8
10
  })
@@ -1,5 +1,5 @@
1
- module.exports = ({ strapi, nexus }) => {
2
- const related = strapi.plugin('navigation').config('gql')?.navigationItemRelated;
1
+ module.exports = ({ strapi, nexus, config }) => {
2
+ const related = config.gql?.navigationItemRelated;
3
3
  const name = "NavigationRelated";
4
4
 
5
5
  if (related?.length) {
@@ -16,6 +16,16 @@ module.exports = {
16
16
  path: '/config',
17
17
  handler: 'navigation.config',
18
18
  },
19
+ {
20
+ method: 'PUT',
21
+ path: '/config',
22
+ handler: 'navigation.updateConfig',
23
+ },
24
+ {
25
+ method: 'DELETE',
26
+ path: '/config',
27
+ handler: 'navigation.restoreConfig',
28
+ },
19
29
  {
20
30
  method: 'GET',
21
31
  path: '/:id',
@@ -33,6 +43,19 @@ module.exports = {
33
43
  policies: [
34
44
  'admin::isAuthenticatedAdmin'
35
45
  ]
36
- }
46
+ },
47
+ {
48
+ method: 'GET',
49
+ path: '/settings/config',
50
+ handler: 'navigation.settingsConfig',
51
+ },
52
+ {
53
+ method: 'GET',
54
+ path: '/settings/restart',
55
+ handler: 'navigation.settingsRestart',
56
+ config: {
57
+ policies: [],
58
+ },
59
+ },
37
60
  ]
38
61
  }
@@ -0,0 +1,48 @@
1
+ const { setupStrapi } = require('../../../__mocks__/strapi');
2
+ const utilsFunctionsFactory = require('../utils/functions');
3
+
4
+ describe('Utilities functions', () => {
5
+ beforeAll(async () => {
6
+ setupStrapi();
7
+ });
8
+
9
+ describe('Path rendering functions', () => {
10
+ it('Can build nested path structure', async () => {
11
+ const utilsFunctions = utilsFunctionsFactory({ strapi });
12
+ const { itemModel } = utilsFunctions.extractMeta(strapi.plugins);
13
+ const rootPath = '/home/side';
14
+ const entities = await strapi
15
+ .query(itemModel.uid)
16
+ .findMany({
17
+ where: {
18
+ master: 1
19
+ }
20
+ });
21
+ const nested = utilsFunctions.buildNestedPaths({ items: entities });
22
+
23
+ expect(nested.length).toBe(2);
24
+ expect(nested[1].path).toBe(rootPath);
25
+ });
26
+
27
+ it('Can filter items by path', async () => {
28
+ const utilsFunctions = utilsFunctionsFactory({ strapi });
29
+ const { itemModel } = utilsFunctions.extractMeta(strapi.plugins);
30
+ const rootPath = '/home/side';
31
+ const entities = await strapi
32
+ .query(itemModel.uid)
33
+ .findMany({
34
+ where: {
35
+ master: 1
36
+ }
37
+ });
38
+ const {
39
+ root,
40
+ items
41
+ } = utilsFunctions.filterByPath(entities, rootPath);
42
+
43
+ expect(root).toBeDefined();
44
+ expect(root.path).toBe(rootPath);
45
+ expect(items.length).toBe(1)
46
+ });
47
+ });
48
+ });
@@ -26,7 +26,7 @@ describe('Navigation services', () => {
26
26
  describe('Render navigation', () => {
27
27
  it('Can render branch in flat format', async () => {
28
28
  const service = strapi.plugin('navigation').service('navigation');
29
- const result = await service.render(1);
29
+ const result = await service.render({ idOrSlug: 1 });
30
30
 
31
31
  expect(result).toBeDefined()
32
32
  expect(result.length).toBe(2)
@@ -34,7 +34,10 @@ describe('Navigation services', () => {
34
34
 
35
35
  it('Can render branch in tree format', async () => {
36
36
  const service = strapi.plugin('navigation').service('navigation');
37
- const result = await service.render(1, "TREE");
37
+ const result = await service.render({
38
+ idOrSlug: 1,
39
+ type: "TREE"
40
+ });
38
41
 
39
42
  expect(result).toBeDefined()
40
43
  expect(result.length).toBeGreaterThan(0)
@@ -42,7 +45,10 @@ describe('Navigation services', () => {
42
45
 
43
46
  it('Can render branch in rfr format', async () => {
44
47
  const service = strapi.plugin('navigation').service('navigation');
45
- const result = await service.render(1, "RFR");
48
+ const result = await service.render({
49
+ idOrSlug: 1,
50
+ type: "RFR"
51
+ });
46
52
 
47
53
  expect(result).toBeDefined()
48
54
  expect(result.length).toBeGreaterThan(0)
@@ -50,11 +56,27 @@ describe('Navigation services', () => {
50
56
 
51
57
  it('Can render only menu attached elements', async () => {
52
58
  const service = strapi.plugin('navigation').service('navigation');
53
- const result = await service.render(1, "FLAT", true);
59
+ const result = await service.render({
60
+ idOrSlug: 1,
61
+ type: "FLAT",
62
+ menuOnly: true.valueOf,
63
+ });
54
64
 
55
65
  expect(result).toBeDefined()
56
66
  expect(result.length).toBe(1)
57
67
  });
68
+
69
+ it('Can render branch by path', async () => {
70
+ const service = strapi.plugin('navigation').service('navigation');
71
+ const result = await service.render({
72
+ idOrSlug: 1,
73
+ type: "FLAT",
74
+ rootPath: '/home/side'
75
+ });
76
+
77
+ expect(result).toBeDefined();
78
+ expect(result.length).toBe(1);
79
+ });
58
80
  });
59
81
 
60
82
  describe('Render child', () => {
@@ -19,7 +19,7 @@ const { KIND_TYPES } = require('./utils/constant');
19
19
  const utilsFunctionsFactory = require('./utils/functions');
20
20
  const { renderType } = require('../content-types/navigation/lifecycle');
21
21
  const { type: itemType, additionalFields: configAdditionalFields } = require('../content-types/navigation-item').lifecycle;
22
- const { NotFoundError } = require('@strapi/utils').errors
22
+ const { NotFoundError } = require('@strapi/utils').errors
23
23
  const excludedContentTypes = ['strapi::'];
24
24
  const contentTypesNameFieldsDefaults = ['title', 'subject', 'name'];
25
25
 
@@ -56,7 +56,7 @@ module.exports = ({ strapi }) => {
56
56
  limit: -1,
57
57
  },
58
58
  sort: ['order:asc'],
59
- populate: ['related', 'parent']
59
+ populate: ['related', 'parent', 'audience']
60
60
  });
61
61
  const entities = await this.getRelatedItems(entityItems);
62
62
  return {
@@ -65,12 +65,19 @@ module.exports = ({ strapi }) => {
65
65
  };
66
66
  },
67
67
 
68
+ async restart() {
69
+ setImmediate(() => strapi.reload());
70
+ },
71
+
68
72
  // Get plugin config
69
- async config() {
70
- const { pluginName, audienceModel, service } = utilsFunctions.extractMeta(strapi.plugins);
71
- const additionalFields = strapi.plugin(pluginName).config('additionalFields')
72
- const contentTypesNameFields = strapi.plugin(pluginName).config('contentTypesNameFields');
73
- const allowedLevels = strapi.plugin(pluginName).config('allowedLevels');
73
+ async config(viaSettingsPage = false) {
74
+ const { audienceModel, service } = utilsFunctions.extractMeta(strapi.plugins);
75
+ const pluginStore = await strapi.store({ type: 'plugin', name: 'navigation' });
76
+ const config = await pluginStore.get({ key: 'config' });
77
+ const additionalFields = config.additionalFields;
78
+ const contentTypesNameFields = config.contentTypesNameFields;
79
+ const allowedLevels = config.allowedLevels;
80
+ const isGQLPluginEnabled = !isNil(strapi.plugin('graphql'));
74
81
 
75
82
  let extendedResult = {};
76
83
  const result = {
@@ -81,6 +88,7 @@ module.exports = ({ strapi }) => {
81
88
  },
82
89
  allowedLevels,
83
90
  additionalFields,
91
+ isGQLPluginEnabled: viaSettingsPage ? isGQLPluginEnabled : undefined,
84
92
  };
85
93
 
86
94
  if (additionalFields.includes(configAdditionalFields.AUDIENCE)) {
@@ -102,10 +110,33 @@ module.exports = ({ strapi }) => {
102
110
  };
103
111
  },
104
112
 
113
+ async updateConfig(newConfig) {
114
+ const pluginStore = await strapi.store({ type: 'plugin', name: 'navigation' });
115
+ await pluginStore.set({ key: 'config', value: newConfig });
116
+ },
117
+
118
+ async restoreConfig() {
119
+ const pluginStore = await strapi.store({ type: 'plugin', name: 'navigation' });
120
+ const defaultConfig = await strapi.plugin('navigation').config
121
+
122
+ await pluginStore.delete({ key: 'config' })
123
+ await pluginStore.set({
124
+ key: 'config', value: {
125
+ additionalFields: defaultConfig('additionalFields'),
126
+ contentTypes: defaultConfig('contentTypes'),
127
+ contentTypesNameFields: defaultConfig('contentTypesNameFields'),
128
+ allowedLevels: defaultConfig('allowedLevels'),
129
+ gql: defaultConfig('gql'),
130
+ }
131
+ });
132
+ },
133
+
105
134
  async configContentTypes() {
135
+ const pluginStore = strapi.store({ type: 'plugin', name: 'navigation' });
136
+ const config = await pluginStore.get({ key: 'config' });
106
137
  const eligibleContentTypes =
107
138
  await Promise.all(
108
- strapi.plugin('navigation').config('contentTypes')
139
+ config.contentTypes
109
140
  .filter(contentType => !!strapi.contentTypes[contentType])
110
141
  .map(
111
142
  async (key) => {
@@ -311,20 +342,20 @@ module.exports = ({ strapi }) => {
311
342
  ...(type === renderType.FLAT ? { uiRouterKey: childUIKey } : {}),
312
343
  };
313
344
 
314
- return service.renderType(type, criteria, itemCriteria, filter);
345
+ return service.renderType({ type, criteria, itemCriteria, filter });
315
346
  },
316
347
 
317
- async render(idOrSlug, type = renderType.FLAT, menuOnly = false) {
348
+ async render({ idOrSlug, type = renderType.FLAT, menuOnly = false, rootPath = null }) {
318
349
  const { service } = utilsFunctions.extractMeta(strapi.plugins);
319
350
 
320
351
  const findById = !isNaN(toNumber(idOrSlug)) || isUuid(idOrSlug);
321
352
  const criteria = findById ? { id: idOrSlug } : { slug: idOrSlug };
322
353
  const itemCriteria = menuOnly ? { menuAttached: true } : {};
323
354
 
324
- return service.renderType(type, criteria, itemCriteria);
355
+ return service.renderType({ type, criteria, itemCriteria, rootPath });
325
356
  },
326
357
 
327
- async renderType(type = renderType.FLAT, criteria = {}, itemCriteria = {}, filter = null) {
358
+ async renderType({ type = renderType.FLAT, criteria = {}, itemCriteria = {}, filter = null, rootPath = null }) {
328
359
  const { pluginName, service, masterModel, itemModel } = utilsFunctions.extractMeta(
329
360
  strapi.plugins,
330
361
  );
@@ -362,8 +393,8 @@ module.exports = ({ strapi }) => {
362
393
  const getTemplateName = await utilsFunctions.templateNameFactory(items, strapi, contentTypes);
363
394
  const itemParser = (item, path = '', field) => {
364
395
  const isExternal = item.type === itemType.EXTERNAL;
365
- const parentPath = isExternal ? undefined : `${path === '/' ? '' : path}/${item.path === '/'
366
- ? ''
396
+ const parentPath = isExternal ? undefined : `${path === '/' ? '' : path}/${first(item.path) === '/'
397
+ ? item.path.substring(1)
367
398
  : item.path}`;
368
399
  const slug = isString(parentPath) ? slugify(
369
400
  (first(parentPath) === '/' ? parentPath.substring(1) : parentPath).replace(/\//g, '-')) : undefined;
@@ -391,9 +422,17 @@ module.exports = ({ strapi }) => {
391
422
  }),
392
423
  };
393
424
  };
425
+
426
+ const {
427
+ items: itemsFilteredByPath,
428
+ root: rootElement,
429
+ } = utilsFunctions.filterByPath(items, rootPath);
430
+
394
431
  const treeStructure = service.renderTree({
395
- items,
432
+ items: isNil(rootPath) ? items : itemsFilteredByPath,
396
433
  field: 'parent',
434
+ id: get(rootElement, 'parent.id'),
435
+ path: get(rootElement, 'parent.path'),
397
436
  itemParser,
398
437
  });
399
438
 
@@ -409,7 +448,7 @@ module.exports = ({ strapi }) => {
409
448
  }
410
449
  return filteredStructure;
411
450
  default:
412
- return items
451
+ const publishedItems = items
413
452
  .filter(utilsFunctions.filterOutUnpublished)
414
453
  .map((item) => ({
415
454
  ...item,
@@ -418,6 +457,7 @@ module.exports = ({ strapi }) => {
418
457
  related: item.related?.map(({ localizations, ...item }) => item),
419
458
  items: null,
420
459
  }));
460
+ return isNil(rootPath) ? items : utilsFunctions.filterByPath(publishedItems, rootPath).items;
421
461
  }
422
462
  }
423
463
  throw new NotFoundError();
@@ -6,6 +6,8 @@ const {
6
6
  find,
7
7
  isString,
8
8
  get,
9
+ isNil,
10
+ isArray
9
11
  } = require('lodash');
10
12
 
11
13
  const { type: itemType } = require('../../content-types/navigation-item/lifecycle');
@@ -52,6 +54,45 @@ module.exports = ({ strapi }) => {
52
54
  });
53
55
  },
54
56
 
57
+ buildNestedPaths({items, id = null, field = 'parent', parentPath = null}){
58
+ return items
59
+ .filter(entity => {
60
+ if (entity[field] == null && id === null) {
61
+ return true;
62
+ }
63
+ let data = entity[field];
64
+ if (data && typeof id === 'string') {
65
+ data = data.toString();
66
+ }
67
+ return (data && data === id) || (isObject(entity[field]) && (entity[field].id === id));
68
+ })
69
+ .reduce((acc, entity) => {
70
+ const path = `${parentPath || ''}/${entity.path}`
71
+ return [
72
+ {
73
+ id: entity.id,
74
+ parent: parentPath && {
75
+ id: get(entity, 'parent.id'),
76
+ path: parentPath,
77
+ },
78
+ path
79
+ },
80
+ ...this.buildNestedPaths({items, id: entity.id, field, parentPath: path}),
81
+ ...acc,
82
+ ];
83
+ }, [])
84
+ },
85
+
86
+ filterByPath(items, path) {
87
+ const itemsWithPaths = this.buildNestedPaths({ items }).filter(({path: itemPath}) => itemPath.includes(path));
88
+ const root = itemsWithPaths.find(({ path: itemPath }) => itemPath === path);
89
+
90
+ return {
91
+ root,
92
+ items: isNil(root) ? [] : items.filter(({ id }) => (itemsWithPaths.find(v => v.id === id))),
93
+ }
94
+ },
95
+
55
96
  prepareAuditLog(actions) {
56
97
  return [
57
98
  ...new Set(
package/strapi-server.js CHANGED
@@ -4,7 +4,6 @@ const routes = require('./server/routes');
4
4
  const controllers = require('./server/controllers');
5
5
  const contentTypes = require('./server/content-types');
6
6
  const config = require('./server/config');
7
- const register = require('./server/register');
8
7
 
9
8
 
10
9
  module.exports = () => {
@@ -15,6 +14,5 @@ module.exports = () => {
15
14
  controllers,
16
15
  services,
17
16
  contentTypes,
18
- register,
19
17
  };
20
18
  };