strapi-plugin-navigation 2.0.0-rc.1 → 2.0.3
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 +55 -8
- package/__mocks__/pages.settings.json +25 -0
- package/__mocks__/strapi.js +207 -0
- package/admin/src/components/ConfirmationDialog/index.js +56 -0
- package/admin/src/components/Item/ItemCardBadge/index.js +2 -1
- package/admin/src/components/Item/ItemCardHeader/index.js +8 -13
- package/admin/src/components/Item/index.js +10 -13
- package/admin/src/components/RestartAlert/index.js +8 -0
- package/admin/src/components/Search/index.js +21 -23
- package/admin/src/hooks/useAllContentTypes.js +13 -0
- package/admin/src/hooks/useNavigationConfig.js +58 -0
- package/admin/src/index.js +24 -1
- package/admin/src/pages/SettingsPage/index.js +311 -0
- package/admin/src/pages/View/components/NavigationHeader/index.js +39 -23
- package/admin/src/pages/View/components/NavigationItemForm/index.js +49 -9
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +3 -6
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +3 -7
- package/admin/src/pages/View/components/NavigationItemPopup/index.js +3 -5
- package/admin/src/pages/View/index.js +29 -20
- package/admin/src/pages/View/utils/parsers.js +7 -3
- package/admin/src/translations/en.json +52 -10
- package/admin/src/translations/fr.json +4 -4
- package/admin/src/utils/api.js +51 -0
- package/admin/src/utils/index.js +20 -0
- package/package.json +7 -6
- package/server/bootstrap.js +30 -1
- package/server/content-types/navigation/schema.json +45 -0
- package/server/content-types/navigation-item/schema.json +1 -1
- package/server/controllers/navigation.js +30 -5
- package/server/graphql/index.js +3 -4
- package/server/graphql/queries/render-navigation.js +4 -3
- package/server/graphql/types/content-types-name-fields.js +4 -2
- package/server/graphql/types/navigation-related.js +2 -2
- package/server/routes/admin.js +24 -1
- package/server/services/__tests__/functions.test.js +48 -0
- package/server/services/__tests__/navigation.test.js +84 -77
- package/server/services/navigation.js +58 -18
- package/server/services/utils/functions.js +45 -12
- package/strapi-server.js +0 -2
- package/yarn-error.log +5263 -0
- package/.circleci/config.yml +0 -48
- package/.eslintrc +0 -35
- package/.github/pull_request_template.md +0 -13
- package/.github/stale.yml +0 -15
- package/.nvmrc +0 -1
- package/codecov.yml +0 -3
- package/public/assets/logo.png +0 -0
- package/public/assets/preview.png +0 -0
- package/server/content-types/navigation/schema.js +0 -45
- package/server/register.js +0 -5
package/server/routes/admin.js
CHANGED
|
@@ -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
|
+
});
|
|
@@ -1,84 +1,91 @@
|
|
|
1
|
-
const { setupStrapi } = require('
|
|
1
|
+
const { setupStrapi } = require('../../../__mocks__/strapi');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
describe('Navigation services', () => {
|
|
4
|
+
beforeAll(async () => {
|
|
5
|
+
setupStrapi();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
describe('Correct config', () => {
|
|
9
|
+
it('Declares Strapi instance', () => {
|
|
10
|
+
expect(strapi).toBeDefined()
|
|
11
|
+
expect(strapi.plugin('navigation').service('navigation')).toBeDefined()
|
|
12
|
+
});
|
|
4
13
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
it('Defines proper content types', () => {
|
|
15
|
+
expect(strapi.contentTypes).toBeDefined()
|
|
16
|
+
expect(strapi.plugin('navigation').contentTypes).toBeDefined()
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('Can read and return plugins config', () => {
|
|
20
|
+
expect(strapi.plugin('navigation').config('contentTypes')).toBeDefined()
|
|
21
|
+
expect(strapi.plugin('navigation').config('allowedLevels')).toBeDefined()
|
|
22
|
+
expect(strapi.plugin('navigation').config()).not.toBeDefined()
|
|
23
|
+
});
|
|
10
24
|
});
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
isSingle: true,
|
|
38
|
-
contentTypeName: 'MyHomepage',
|
|
39
|
-
endpoint: 'my-homepage',
|
|
40
|
-
label: 'My Homepage',
|
|
41
|
-
labelSingular: 'My Homepage',
|
|
42
|
-
name: 'my-homepage',
|
|
43
|
-
visible: true,
|
|
44
|
-
}, {
|
|
45
|
-
uid: 'application::page-homes.home-page',
|
|
46
|
-
collectionName: 'page_homes',
|
|
47
|
-
isSingle: true,
|
|
48
|
-
contentTypeName: 'HomePage',
|
|
49
|
-
endpoint: 'custom-api',
|
|
50
|
-
label: 'Page Home',
|
|
51
|
-
labelSingular: 'Page Home',
|
|
52
|
-
name: 'home-page',
|
|
53
|
-
visible: true,
|
|
54
|
-
}, {
|
|
55
|
-
uid: 'plugins::another-plugin.pages',
|
|
56
|
-
collectionName: 'pages',
|
|
57
|
-
isSingle: false,
|
|
58
|
-
contentTypeName: 'Plugin-pages',
|
|
59
|
-
endpoint: 'plugin-pages',
|
|
60
|
-
label: 'Pages',
|
|
61
|
-
labelSingular: 'Page',
|
|
62
|
-
name: 'plugin-page',
|
|
63
|
-
visible: true,
|
|
64
|
-
plugin: 'another-plugin',
|
|
65
|
-
}, {
|
|
66
|
-
uid: 'plugins::another-plugin.blog-post',
|
|
67
|
-
collectionName: 'blog_posts',
|
|
68
|
-
isSingle: false,
|
|
69
|
-
contentTypeName: 'BlogPost',
|
|
70
|
-
endpoint: 'plugin-blog-posts',
|
|
71
|
-
label: 'Blog posts',
|
|
72
|
-
labelSingular: 'Blog post',
|
|
73
|
-
name: 'plugin-blog-post',
|
|
74
|
-
visible: true,
|
|
75
|
-
plugin: 'another-plugin',
|
|
76
|
-
}];
|
|
77
|
-
return configContentTypes().then(types => {
|
|
78
|
-
types.map(type => {
|
|
79
|
-
const result = results.find(({ uid }) => uid === type.uid);
|
|
80
|
-
expect(type).toMatchObject(result);
|
|
25
|
+
|
|
26
|
+
describe('Render navigation', () => {
|
|
27
|
+
it('Can render branch in flat format', async () => {
|
|
28
|
+
const service = strapi.plugin('navigation').service('navigation');
|
|
29
|
+
const result = await service.render({ idOrSlug: 1 });
|
|
30
|
+
|
|
31
|
+
expect(result).toBeDefined()
|
|
32
|
+
expect(result.length).toBe(2)
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('Can render branch in tree format', async () => {
|
|
36
|
+
const service = strapi.plugin('navigation').service('navigation');
|
|
37
|
+
const result = await service.render({
|
|
38
|
+
idOrSlug: 1,
|
|
39
|
+
type: "TREE"
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
expect(result).toBeDefined()
|
|
43
|
+
expect(result.length).toBeGreaterThan(0)
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('Can render branch in rfr format', async () => {
|
|
47
|
+
const service = strapi.plugin('navigation').service('navigation');
|
|
48
|
+
const result = await service.render({
|
|
49
|
+
idOrSlug: 1,
|
|
50
|
+
type: "RFR"
|
|
81
51
|
});
|
|
52
|
+
|
|
53
|
+
expect(result).toBeDefined()
|
|
54
|
+
expect(result.length).toBeGreaterThan(0)
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('Can render only menu attached elements', async () => {
|
|
58
|
+
const service = strapi.plugin('navigation').service('navigation');
|
|
59
|
+
const result = await service.render({
|
|
60
|
+
idOrSlug: 1,
|
|
61
|
+
type: "FLAT",
|
|
62
|
+
menuOnly: true.valueOf,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
expect(result).toBeDefined()
|
|
66
|
+
expect(result.length).toBe(1)
|
|
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
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('Render child', () => {
|
|
83
|
+
it('Can render child', async () => {
|
|
84
|
+
const service = strapi.plugin('navigation').service('navigation');
|
|
85
|
+
const result = await service.renderChildren(1, "home");
|
|
86
|
+
|
|
87
|
+
expect(result).toBeDefined();
|
|
88
|
+
expect(result.length).toBe(1);
|
|
82
89
|
});
|
|
83
90
|
});
|
|
84
91
|
});
|
|
@@ -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 } =
|
|
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,27 +65,35 @@ 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 {
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const
|
|
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 = {
|
|
77
|
-
contentTypes: await
|
|
84
|
+
contentTypes: await service.configContentTypes(),
|
|
78
85
|
contentTypesNameFields: {
|
|
79
86
|
default: contentTypesNameFieldsDefaults,
|
|
80
87
|
...(isObject(contentTypesNameFields) ? contentTypesNameFields : {}),
|
|
81
88
|
},
|
|
82
89
|
allowedLevels,
|
|
83
90
|
additionalFields,
|
|
91
|
+
isGQLPluginEnabled: viaSettingsPage ? isGQLPluginEnabled : undefined,
|
|
84
92
|
};
|
|
85
93
|
|
|
86
94
|
if (additionalFields.includes(configAdditionalFields.AUDIENCE)) {
|
|
87
95
|
const audienceItems = await strapi
|
|
88
|
-
.query(
|
|
96
|
+
.query(audienceModel.uid)
|
|
89
97
|
.findMany({
|
|
90
98
|
paggination: {
|
|
91
99
|
limit: -1,
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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,7 @@ const {
|
|
|
6
6
|
find,
|
|
7
7
|
isString,
|
|
8
8
|
get,
|
|
9
|
+
isNil,
|
|
9
10
|
} = require('lodash');
|
|
10
11
|
|
|
11
12
|
const { type: itemType } = require('../../content-types/navigation-item/lifecycle');
|
|
@@ -20,19 +21,12 @@ module.exports = ({ strapi }) => {
|
|
|
20
21
|
|
|
21
22
|
extractMeta(plugins) {
|
|
22
23
|
const { navigation: plugin } = plugins;
|
|
23
|
-
const { navigation: service } = plugin.services;
|
|
24
|
-
const {
|
|
25
|
-
navigation: masterModel,
|
|
26
|
-
'navigation-item': itemModel,
|
|
27
|
-
audience: audienceModel,
|
|
28
|
-
'navigations-items-related': relatedModel,
|
|
29
|
-
} = plugin.contentTypes;
|
|
30
24
|
return {
|
|
31
|
-
masterModel,
|
|
32
|
-
itemModel,
|
|
33
|
-
relatedModel,
|
|
34
|
-
audienceModel,
|
|
35
|
-
service,
|
|
25
|
+
masterModel: plugin.contentType('navigation'),
|
|
26
|
+
itemModel: plugin.contentType('navigation-item'),
|
|
27
|
+
relatedModel: plugin.contentType('navigations-items-related'),
|
|
28
|
+
audienceModel: plugin.contentType('audience'),
|
|
29
|
+
service: plugin.service('navigation'),
|
|
36
30
|
plugin,
|
|
37
31
|
pluginName: 'navigation',
|
|
38
32
|
};
|
|
@@ -59,6 +53,45 @@ module.exports = ({ strapi }) => {
|
|
|
59
53
|
});
|
|
60
54
|
},
|
|
61
55
|
|
|
56
|
+
buildNestedPaths({items, id = null, field = 'parent', parentPath = null}){
|
|
57
|
+
return items
|
|
58
|
+
.filter(entity => {
|
|
59
|
+
if (entity[field] == null && id === null) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
let data = entity[field];
|
|
63
|
+
if (data && typeof id === 'string') {
|
|
64
|
+
data = data.toString();
|
|
65
|
+
}
|
|
66
|
+
return (data && data === id) || (isObject(entity[field]) && (entity[field].id === id));
|
|
67
|
+
})
|
|
68
|
+
.reduce((acc, entity) => {
|
|
69
|
+
const path = `${parentPath || ''}/${entity.path}`
|
|
70
|
+
return [
|
|
71
|
+
{
|
|
72
|
+
id: entity.id,
|
|
73
|
+
parent: parentPath && {
|
|
74
|
+
id: get(entity, 'parent.id'),
|
|
75
|
+
path: parentPath,
|
|
76
|
+
},
|
|
77
|
+
path
|
|
78
|
+
},
|
|
79
|
+
...this.buildNestedPaths({items, id: entity.id, field, parentPath: path}),
|
|
80
|
+
...acc,
|
|
81
|
+
];
|
|
82
|
+
}, [])
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
filterByPath(items, path) {
|
|
86
|
+
const itemsWithPaths = this.buildNestedPaths({ items }).filter(({path: itemPath}) => itemPath.includes(path));
|
|
87
|
+
const root = itemsWithPaths.find(({ path: itemPath }) => itemPath === path);
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
root,
|
|
91
|
+
items: isNil(root) ? [] : items.filter(({ id }) => (itemsWithPaths.find(v => v.id === id))),
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
|
|
62
95
|
prepareAuditLog(actions) {
|
|
63
96
|
return [
|
|
64
97
|
...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
|
};
|