strapi-plugin-navigation 2.1.0 → 2.2.0
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 +17 -7
- package/admin/src/components/AdditionalFieldInput/index.d.ts +5 -0
- package/admin/src/components/AdditionalFieldInput/index.js +71 -0
- package/admin/src/components/AdditionalFieldInput/types.d.ts +14 -0
- package/admin/src/components/AdditionalFieldInput/types.js +3 -0
- package/admin/src/components/Item/index.js +2 -3
- package/admin/src/components/RestartAlert/index.d.ts +1 -1
- package/admin/src/components/TextArrayInput/index.d.ts +14 -0
- package/admin/src/components/TextArrayInput/index.js +45 -0
- package/admin/src/hooks/useAllContentTypes.d.ts +1 -4
- package/admin/src/hooks/useAllContentTypes.js +3 -7
- package/admin/src/hooks/useNavigationConfig.d.ts +1 -1
- package/admin/src/hooks/useNavigationConfig.js +6 -6
- package/admin/src/pages/DataManagerProvider/index.d.ts +1 -1
- package/admin/src/pages/DataManagerProvider/index.js +9 -11
- package/admin/src/pages/SettingsPage/components/CustomFieldForm/index.d.ts +12 -0
- package/admin/src/pages/SettingsPage/components/CustomFieldForm/index.js +112 -0
- package/admin/src/pages/SettingsPage/components/CustomFieldModal/index.d.ts +12 -0
- package/admin/src/pages/SettingsPage/components/CustomFieldModal/index.js +20 -0
- package/admin/src/pages/SettingsPage/components/CustomFieldTable/index.d.ts +11 -0
- package/admin/src/pages/SettingsPage/components/CustomFieldTable/index.js +105 -0
- package/admin/src/pages/SettingsPage/index.d.ts +2 -1
- package/admin/src/pages/SettingsPage/index.js +109 -74
- package/admin/src/pages/SettingsPage/types.d.ts +32 -0
- package/admin/src/pages/SettingsPage/types.js +3 -0
- package/admin/src/pages/SettingsPage/utils/form.d.ts +18 -0
- package/admin/src/pages/SettingsPage/utils/form.js +34 -0
- package/admin/src/pages/SettingsPage/utils/functions.d.ts +2 -2
- package/admin/src/pages/SettingsPage/utils/functions.js +1 -1
- package/admin/src/pages/View/components/NavigationItemForm/index.d.ts +3 -55
- package/admin/src/pages/View/components/NavigationItemForm/index.js +162 -177
- package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +90 -0
- package/admin/src/pages/View/components/NavigationItemForm/types.js +3 -0
- package/admin/src/pages/View/components/NavigationItemForm/utils/form.d.ts +24 -43
- package/admin/src/pages/View/components/NavigationItemForm/utils/form.js +78 -45
- package/admin/src/pages/View/components/NavigationItemPopup/index.js +1 -2
- package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.d.ts +4 -0
- package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.js +11 -0
- package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.d.ts +9 -0
- package/admin/src/pages/View/components/NavigationManager/{List → AllNavigations}/index.js +32 -31
- package/admin/src/pages/View/components/NavigationManager/DeletionConfirm/index.d.ts +9 -0
- package/admin/src/pages/View/components/NavigationManager/{Delete → DeletionConfirm}/index.js +18 -12
- package/admin/src/pages/View/components/NavigationManager/ErrorDetails/index.d.ts +9 -0
- package/admin/src/pages/View/components/NavigationManager/{Error → ErrorDetails}/index.js +10 -10
- package/admin/src/pages/View/components/NavigationManager/Footer/index.d.ts +24 -0
- package/admin/src/pages/View/components/NavigationManager/Footer/index.js +13 -0
- package/admin/src/pages/View/components/NavigationManager/Form/index.d.ts +3 -2
- package/admin/src/pages/View/components/NavigationManager/Form/index.js +7 -2
- package/admin/src/pages/View/components/NavigationManager/NavigationUpdate/index.d.ts +9 -0
- package/admin/src/pages/View/components/NavigationManager/{Edit → NavigationUpdate}/index.js +16 -11
- package/admin/src/pages/View/components/NavigationManager/NewNavigation/index.d.ts +10 -0
- package/admin/src/pages/View/components/NavigationManager/{Create → NewNavigation}/index.js +16 -11
- package/admin/src/pages/View/components/NavigationManager/index.d.ts +3 -2
- package/admin/src/pages/View/components/NavigationManager/index.js +22 -21
- package/admin/src/pages/View/components/NavigationManager/types.d.ts +2 -15
- package/admin/src/pages/View/index.d.ts +1 -1
- package/admin/src/pages/View/index.js +1 -1
- package/admin/src/pages/View/utils/parsers.d.ts +1 -0
- package/admin/src/pages/View/utils/parsers.js +8 -7
- package/admin/src/translations/en.json +37 -0
- package/admin/src/translations/index.d.ts +2 -1
- package/admin/src/translations/index.js +1 -1
- package/admin/src/utils/api.d.ts +8 -7
- package/admin/src/utils/api.js +6 -41
- package/admin/src/utils/enums.d.ts +25 -0
- package/admin/src/utils/enums.js +30 -0
- package/admin/src/utils/functions.d.ts +16 -0
- package/admin/src/utils/functions.js +46 -0
- package/admin/src/utils/index.d.ts +3 -17
- package/admin/src/utils/index.js +16 -39
- package/package.json +5 -5
- package/server/config/index.js +6 -4
- package/server/config/setupStrategy.js +13 -1
- package/server/content-types/index.d.ts +5 -25
- package/server/content-types/navigation/index.d.ts +0 -7
- package/server/content-types/navigation/index.js +0 -2
- package/server/content-types/navigation-item/index.d.ts +5 -13
- package/server/content-types/navigation-item/index.js +0 -2
- package/server/content-types/navigation-item/schema.d.ts +5 -0
- package/server/content-types/navigation-item/schema.js +5 -0
- package/server/content-types/navigations-items-related/index.d.ts +0 -5
- package/server/content-types/navigations-items-related/index.js +0 -2
- package/server/controllers/admin.js +1 -1
- package/server/controllers/client.js +2 -1
- package/server/graphql/types/navigation-item.d.ts +2 -1
- package/server/graphql/types/navigation-item.js +26 -2
- package/server/index.d.ts +5 -25
- package/server/services/admin.js +26 -14
- package/server/services/client.js +64 -21
- package/server/services/common.js +25 -6
- package/server/utils/constant.d.ts +0 -3
- package/server/utils/constant.js +1 -2
- package/server/utils/functions.d.ts +12 -12
- package/server/utils/functions.js +60 -22
- package/strapi-server.d.ts +5 -25
- package/tsconfig.tsbuildinfo +1 -1
- package/types/config.d.ts +6 -2
- package/types/contentTypes.d.ts +22 -1
- package/types/services.d.ts +14 -5
- package/types/utils.d.ts +6 -1
- package/types/utils.js +15 -1
- package/admin/src/pages/View/components/NavigationManager/Create/index.d.ts +0 -9
- package/admin/src/pages/View/components/NavigationManager/Delete/index.d.ts +0 -8
- package/admin/src/pages/View/components/NavigationManager/Edit/index.d.ts +0 -8
- package/admin/src/pages/View/components/NavigationManager/Error/index.d.ts +0 -8
- package/admin/src/pages/View/components/NavigationManager/List/index.d.ts +0 -8
- package/admin/src/pages/View/utils/enums.d.ts +0 -9
- package/admin/src/pages/View/utils/enums.js +0 -12
- package/admin/src/utils/getTrad.d.ts +0 -3
- package/admin/src/utils/getTrad.js +0 -9
- package/server/content-types/navigation/lifecycle.d.ts +0 -9
- package/server/content-types/navigation/lifecycle.js +0 -10
- package/server/content-types/navigation-item/lifecycle.d.ts +0 -16
- package/server/content-types/navigation-item/lifecycle.js +0 -31
- package/server/content-types/navigations-items-related/lifecycle.d.ts +0 -8
- package/server/content-types/navigations-items-related/lifecycle.js +0 -22
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const lodash_1 = require("lodash");
|
|
7
|
-
const slugify_1 = __importDefault(require("slugify"));
|
|
7
|
+
const slugify_1 = __importDefault(require("@sindresorhus/slugify"));
|
|
8
8
|
const uuid_1 = require("uuid");
|
|
9
9
|
const types_1 = require("../../types");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
@@ -12,13 +12,13 @@ const utils_2 = require("@strapi/utils");
|
|
|
12
12
|
const i18n_1 = require("../i18n");
|
|
13
13
|
const NavigationError_1 = require("../../utils/NavigationError");
|
|
14
14
|
const clientService = ({ strapi }) => ({
|
|
15
|
-
async render({ idOrSlug, type = utils_1.RENDER_TYPES.FLAT, menuOnly = false, rootPath = null, wrapRelated = false, locale, }) {
|
|
15
|
+
async render({ idOrSlug, type = utils_1.RENDER_TYPES.FLAT, menuOnly = false, rootPath = null, wrapRelated = false, locale, populate, }) {
|
|
16
16
|
const clientService = (0, utils_1.getPluginService)('client');
|
|
17
17
|
const findById = !isNaN((0, lodash_1.toNumber)(idOrSlug)) || (0, uuid_1.validate)(idOrSlug);
|
|
18
18
|
const criteria = findById ? { id: idOrSlug } : { slug: idOrSlug };
|
|
19
19
|
const itemCriteria = menuOnly ? { menuAttached: true } : {};
|
|
20
20
|
return await clientService.renderType({
|
|
21
|
-
type, criteria, itemCriteria, filter: null, rootPath, wrapRelated, locale,
|
|
21
|
+
type, criteria, itemCriteria, filter: null, rootPath, wrapRelated, locale, populate
|
|
22
22
|
});
|
|
23
23
|
},
|
|
24
24
|
async renderChildren({ idOrSlug, childUIKey, type = utils_1.RENDER_TYPES.FLAT, menuOnly = false, wrapRelated = false, locale, }) {
|
|
@@ -32,7 +32,7 @@ const clientService = ({ strapi }) => ({
|
|
|
32
32
|
};
|
|
33
33
|
return clientService.renderType({ type, criteria, itemCriteria, filter, rootPath: null, wrapRelated, locale });
|
|
34
34
|
},
|
|
35
|
-
renderRFR(items, parent = null, parentNavItem = null, contentTypes = []) {
|
|
35
|
+
renderRFR({ items, parent = null, parentNavItem = null, contentTypes = [], enabledCustomFieldsNames, }) {
|
|
36
36
|
const clientService = (0, utils_1.getPluginService)('client');
|
|
37
37
|
let pages = {};
|
|
38
38
|
let nav = {};
|
|
@@ -40,8 +40,8 @@ const clientService = ({ strapi }) => ({
|
|
|
40
40
|
items.forEach(item => {
|
|
41
41
|
const { items: itemChilds, ...itemProps } = item;
|
|
42
42
|
const itemNav = clientService.renderRFRNav(itemProps);
|
|
43
|
-
const itemPage = clientService.renderRFRPage(itemProps, parent);
|
|
44
|
-
if (item.type
|
|
43
|
+
const itemPage = clientService.renderRFRPage(itemProps, parent, enabledCustomFieldsNames);
|
|
44
|
+
if (item.type !== "EXTERNAL") {
|
|
45
45
|
pages = {
|
|
46
46
|
...pages,
|
|
47
47
|
[itemPage.id]: {
|
|
@@ -60,7 +60,7 @@ const clientService = ({ strapi }) => ({
|
|
|
60
60
|
}
|
|
61
61
|
else {
|
|
62
62
|
const navLevel = navItems
|
|
63
|
-
.filter(navItem => navItem.type
|
|
63
|
+
.filter(navItem => navItem.type !== "EXTERNAL");
|
|
64
64
|
if (!(0, lodash_1.isEmpty)(navLevel))
|
|
65
65
|
nav = {
|
|
66
66
|
...nav,
|
|
@@ -68,8 +68,20 @@ const clientService = ({ strapi }) => ({
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
if (!(0, lodash_1.isEmpty)(itemChilds)) {
|
|
71
|
-
const { nav: nestedNavs } = clientService.renderRFR(
|
|
72
|
-
|
|
71
|
+
const { nav: nestedNavs } = clientService.renderRFR({
|
|
72
|
+
items: itemChilds,
|
|
73
|
+
parent: itemPage.id,
|
|
74
|
+
parentNavItem: itemNav,
|
|
75
|
+
contentTypes,
|
|
76
|
+
enabledCustomFieldsNames,
|
|
77
|
+
});
|
|
78
|
+
const { pages: nestedPages } = clientService.renderRFR({
|
|
79
|
+
items: (itemChilds).filter(child => child.type !== "EXTERNAL"),
|
|
80
|
+
parent: itemPage.id,
|
|
81
|
+
parentNavItem: itemNav,
|
|
82
|
+
contentTypes,
|
|
83
|
+
enabledCustomFieldsNames,
|
|
84
|
+
});
|
|
73
85
|
pages = {
|
|
74
86
|
...pages,
|
|
75
87
|
...nestedPages,
|
|
@@ -105,9 +117,14 @@ const clientService = ({ strapi }) => ({
|
|
|
105
117
|
page: uiRouterKey,
|
|
106
118
|
};
|
|
107
119
|
}
|
|
120
|
+
if (type === "WRAPPER") {
|
|
121
|
+
return {
|
|
122
|
+
...itemCommon,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
108
125
|
throw new NavigationError_1.NavigationError("Unknown item type", item);
|
|
109
126
|
},
|
|
110
|
-
renderRFRPage(item, parent) {
|
|
127
|
+
renderRFRPage(item, parent, enabledCustomFieldsNames) {
|
|
111
128
|
const { uiRouterKey, title, path, slug, related, type, audience, menuAttached } = item;
|
|
112
129
|
const { __contentType, id, __templateName } = related || {};
|
|
113
130
|
const contentType = __contentType || '';
|
|
@@ -124,6 +141,7 @@ const clientService = ({ strapi }) => ({
|
|
|
124
141
|
parent,
|
|
125
142
|
audience,
|
|
126
143
|
menuAttached,
|
|
144
|
+
...enabledCustomFieldsNames.reduce((acc, field) => ({ ...acc, [field]: (0, lodash_1.get)(item, field) }), {})
|
|
127
145
|
};
|
|
128
146
|
},
|
|
129
147
|
renderTree(items = [], id = null, field = 'parent', path = '', itemParser = (i) => i) {
|
|
@@ -152,7 +170,7 @@ const clientService = ({ strapi }) => ({
|
|
|
152
170
|
return 0;
|
|
153
171
|
});
|
|
154
172
|
},
|
|
155
|
-
async renderType({ type = utils_1.RENDER_TYPES.FLAT, criteria = {}, itemCriteria = {}, filter = null, rootPath = null, wrapRelated = false, locale, }) {
|
|
173
|
+
async renderType({ type = utils_1.RENDER_TYPES.FLAT, criteria = {}, itemCriteria = {}, filter = null, rootPath = null, wrapRelated = false, locale, populate, }) {
|
|
156
174
|
const clientService = (0, utils_1.getPluginService)('client');
|
|
157
175
|
const adminService = (0, utils_1.getPluginService)('admin');
|
|
158
176
|
const commonService = (0, utils_1.getPluginService)('common');
|
|
@@ -160,7 +178,7 @@ const clientService = ({ strapi }) => ({
|
|
|
160
178
|
...criteria,
|
|
161
179
|
visible: true,
|
|
162
180
|
};
|
|
163
|
-
const { masterModel, itemModel } = (0, utils_1.
|
|
181
|
+
const { masterModel, itemModel } = (0, utils_1.getPluginModels)();
|
|
164
182
|
const entity = await (0, i18n_1.i18nAwareEntityReadHandler)({
|
|
165
183
|
entity: await strapi
|
|
166
184
|
.query(masterModel.uid)
|
|
@@ -185,8 +203,10 @@ const clientService = ({ strapi }) => ({
|
|
|
185
203
|
if (!entities) {
|
|
186
204
|
return [];
|
|
187
205
|
}
|
|
188
|
-
const items = await commonService.getRelatedItems(entities);
|
|
189
|
-
const { contentTypes, contentTypesNameFields } = await adminService.config(false);
|
|
206
|
+
const items = await commonService.getRelatedItems(entities, populate);
|
|
207
|
+
const { contentTypes, contentTypesNameFields, additionalFields, slugify: customSlugifyConfig } = await adminService.config(false);
|
|
208
|
+
const enabledCustomFieldsNames = (0, utils_1.getCustomFields)(additionalFields)
|
|
209
|
+
.reduce((acc, curr) => curr.enabled ? [...acc, curr.name] : acc, []);
|
|
190
210
|
const wrapContentType = (itemContentType) => wrapRelated && itemContentType ? {
|
|
191
211
|
id: itemContentType.id,
|
|
192
212
|
attributes: { ...itemContentType }
|
|
@@ -200,7 +220,7 @@ const clientService = ({ strapi }) => ({
|
|
|
200
220
|
const parentPath = isExternal ? undefined : `${path === '/' ? '' : path}/${(0, lodash_1.first)(item.path) === '/'
|
|
201
221
|
? item.path.substring(1)
|
|
202
222
|
: item.path}`;
|
|
203
|
-
const slug = (0, lodash_1.isString)(parentPath) ? (0, slugify_1.default)(((0, lodash_1.first)(parentPath) === '/' ? parentPath.substring(1) : parentPath).replace(/\//g, '-')) : undefined;
|
|
223
|
+
const slug = (0, lodash_1.isString)(parentPath) ? (0, slugify_1.default)(((0, lodash_1.first)(parentPath) === '/' ? parentPath.substring(1) : parentPath).replace(/\//g, '-'), customSlugifyConfig) : undefined;
|
|
204
224
|
const lastRelated = (0, lodash_1.isArray)(item.related) ? (0, lodash_1.last)(item.related) : item.related;
|
|
205
225
|
const relatedContentType = wrapContentType(lastRelated);
|
|
206
226
|
return {
|
|
@@ -211,14 +231,15 @@ const clientService = ({ strapi }) => ({
|
|
|
211
231
|
path: isExternal ? item.externalPath : parentPath,
|
|
212
232
|
type: item.type,
|
|
213
233
|
uiRouterKey: item.uiRouterKey,
|
|
214
|
-
slug: !slug && item.uiRouterKey ? (0, slugify_1.default)(item.uiRouterKey) : slug,
|
|
234
|
+
slug: !slug && item.uiRouterKey ? (0, slugify_1.default)(item.uiRouterKey, customSlugifyConfig) : slug,
|
|
215
235
|
external: isExternal,
|
|
216
236
|
related: isExternal || !lastRelated ? undefined : {
|
|
217
237
|
...relatedContentType,
|
|
218
238
|
__templateName: getTemplateName((lastRelated.relatedType || lastRelated.__contentType), lastRelated.id),
|
|
219
239
|
},
|
|
220
|
-
audience: !(0, lodash_1.isEmpty)(item.audience) ? item.audience.map(
|
|
240
|
+
audience: !(0, lodash_1.isEmpty)(item.audience) ? item.audience.map(({ key }) => key) : undefined,
|
|
221
241
|
items: isExternal ? undefined : clientService.renderTree(items, item.id, field, parentPath, itemParser),
|
|
242
|
+
...enabledCustomFieldsNames.reduce((acc, field) => ({ ...acc, [field]: (0, lodash_1.get)(item, `additionalFields.${field}`) }), {}),
|
|
222
243
|
};
|
|
223
244
|
};
|
|
224
245
|
const { items: itemsFilteredByPath, root: rootElement, } = (0, utils_1.filterByPath)(items, rootPath);
|
|
@@ -227,19 +248,41 @@ const clientService = ({ strapi }) => ({
|
|
|
227
248
|
? treeStructure.filter((item) => item.uiRouterKey === filter)
|
|
228
249
|
: treeStructure;
|
|
229
250
|
if (type === utils_1.RENDER_TYPES.RFR) {
|
|
230
|
-
return clientService.renderRFR(
|
|
251
|
+
return clientService.renderRFR({
|
|
252
|
+
items: filteredStructure,
|
|
253
|
+
contentTypes,
|
|
254
|
+
enabledCustomFieldsNames,
|
|
255
|
+
});
|
|
231
256
|
}
|
|
232
257
|
return filteredStructure;
|
|
233
258
|
default:
|
|
234
259
|
const publishedItems = items.filter(utils_1.filterOutUnpublished);
|
|
235
260
|
const result = (0, lodash_1.isNil)(rootPath) ? items : (0, utils_1.filterByPath)(publishedItems, rootPath).items;
|
|
236
|
-
|
|
261
|
+
const defaultCache = new Map();
|
|
262
|
+
const getNestedOrders = (id, cache = defaultCache) => {
|
|
263
|
+
const cached = cache.get(id);
|
|
264
|
+
if (!(0, lodash_1.isNil)(cached))
|
|
265
|
+
return cached;
|
|
266
|
+
const item = result.find(item => item.id === id);
|
|
267
|
+
if ((0, lodash_1.isNil)(item))
|
|
268
|
+
throw new Error("Item not found");
|
|
269
|
+
const { order, parent } = item;
|
|
270
|
+
const nestedOrders = parent
|
|
271
|
+
? getNestedOrders(parent.id, cache).concat(order)
|
|
272
|
+
: [order];
|
|
273
|
+
cache.set(id, nestedOrders);
|
|
274
|
+
return nestedOrders;
|
|
275
|
+
};
|
|
276
|
+
return result
|
|
277
|
+
.map(({ additionalFields, ...item }) => ({
|
|
237
278
|
...item,
|
|
238
279
|
audience: item.audience?.map(_ => (_).key),
|
|
239
|
-
title: (0, utils_1.composeItemTitle)(item, contentTypesNameFields, contentTypes) || '',
|
|
280
|
+
title: (0, utils_1.composeItemTitle)({ ...item, additionalFields }, contentTypesNameFields, contentTypes) || '',
|
|
240
281
|
related: wrapContentType(item.related),
|
|
241
282
|
items: null,
|
|
242
|
-
|
|
283
|
+
...enabledCustomFieldsNames.reduce((acc, name) => ({ ...acc, [name]: (0, lodash_1.get)(additionalFields, name, undefined) }), {}),
|
|
284
|
+
}))
|
|
285
|
+
.sort((a, b) => (0, utils_1.compareArraysOfNumbers)(getNestedOrders(a.id), getNestedOrders(b.id)));
|
|
243
286
|
}
|
|
244
287
|
}
|
|
245
288
|
throw new utils_2.errors.NotFoundError();
|
|
@@ -110,7 +110,7 @@ const commonService = ({ strapi }) => ({
|
|
|
110
110
|
},
|
|
111
111
|
async createBranch(items, masterEntity, parentItem, operations) {
|
|
112
112
|
const commonService = (0, utils_2.getPluginService)('common');
|
|
113
|
-
const { itemModel } = (0, utils_2.
|
|
113
|
+
const { itemModel } = (0, utils_2.getPluginModels)();
|
|
114
114
|
return await Promise.all(items.map(async (item) => {
|
|
115
115
|
operations.create = true;
|
|
116
116
|
const { parent, master, related, ...params } = item;
|
|
@@ -197,7 +197,7 @@ const commonService = ({ strapi }) => ({
|
|
|
197
197
|
async getPluginStore() {
|
|
198
198
|
return await strapi.store({ type: 'plugin', name: 'navigation' });
|
|
199
199
|
},
|
|
200
|
-
async getRelatedItems(entityItems) {
|
|
200
|
+
async getRelatedItems(entityItems, populate) {
|
|
201
201
|
const commonService = (0, utils_2.getPluginService)('common');
|
|
202
202
|
const pluginStore = await commonService.getPluginStore();
|
|
203
203
|
const config = await pluginStore.get({ key: 'config' });
|
|
@@ -207,7 +207,7 @@ const commonService = ({ strapi }) => ({
|
|
|
207
207
|
...(acc[relatedType] || []),
|
|
208
208
|
...entityItems
|
|
209
209
|
.filter((item => (0, lodash_1.get)(item.related, 'related_type') === relatedType))
|
|
210
|
-
.flatMap((item) => Object.assign(item.related, { navigationItemId: item.id })),
|
|
210
|
+
.flatMap((item) => Object.assign(item.related || {}, { navigationItemId: item.id })),
|
|
211
211
|
],
|
|
212
212
|
}), {});
|
|
213
213
|
const data = new Map((await Promise.all(Object.entries(groupedItems)
|
|
@@ -218,7 +218,7 @@ const commonService = ({ strapi }) => ({
|
|
|
218
218
|
where: {
|
|
219
219
|
id: { $in: (0, lodash_1.map)(related, 'related_id') },
|
|
220
220
|
},
|
|
221
|
-
populate: config.contentTypesPopulate[model] || []
|
|
221
|
+
populate: (0, lodash_1.isNil)(populate) ? config.contentTypesPopulate[model] || [] : (0, utils_2.parsePopulateQuery)(populate)
|
|
222
222
|
});
|
|
223
223
|
return relationData
|
|
224
224
|
.flatMap(_ => Object.assign(_, {
|
|
@@ -239,7 +239,7 @@ const commonService = ({ strapi }) => ({
|
|
|
239
239
|
},
|
|
240
240
|
removeBranch(items = [], operations = {}) {
|
|
241
241
|
const commonService = (0, utils_2.getPluginService)('common');
|
|
242
|
-
const { itemModel } = (0, utils_2.
|
|
242
|
+
const { itemModel } = (0, utils_2.getPluginModels)();
|
|
243
243
|
return Promise.all(items
|
|
244
244
|
.filter(item => item.id)
|
|
245
245
|
.map(async (item) => {
|
|
@@ -273,7 +273,7 @@ const commonService = ({ strapi }) => ({
|
|
|
273
273
|
},
|
|
274
274
|
async updateBranch(toUpdate, masterEntity, parentItem, operations) {
|
|
275
275
|
const commonService = (0, utils_2.getPluginService)('common');
|
|
276
|
-
const { itemModel } = (0, utils_2.
|
|
276
|
+
const { itemModel } = (0, utils_2.getPluginModels)();
|
|
277
277
|
const databaseModel = strapi.query(itemModel.uid);
|
|
278
278
|
return Promise.all(toUpdate.map(async (item) => {
|
|
279
279
|
operations.update = true;
|
|
@@ -307,6 +307,25 @@ const commonService = ({ strapi }) => ({
|
|
|
307
307
|
model: model.modelName,
|
|
308
308
|
entry: sanitizedEntity,
|
|
309
309
|
});
|
|
310
|
+
},
|
|
311
|
+
async pruneCustomFields(removedFields) {
|
|
312
|
+
const { itemModel } = (0, utils_2.getPluginModels)();
|
|
313
|
+
const databaseModel = strapi.query(itemModel.uid);
|
|
314
|
+
const removedFieldsNames = removedFields.map(({ name }) => name);
|
|
315
|
+
const navigationItems = await databaseModel.findMany({
|
|
316
|
+
where: {
|
|
317
|
+
additionalFields: {
|
|
318
|
+
$contains: [removedFieldsNames]
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
const navigationItemsToUpdate = removedFields.reduce((acc, curr) => {
|
|
323
|
+
return acc.map((item) => (0, lodash_1.omit)(item, [`additionalFields.${curr.name}`]));
|
|
324
|
+
}, navigationItems);
|
|
325
|
+
await Promise.all(navigationItemsToUpdate.map(async (item) => await databaseModel.update({
|
|
326
|
+
where: { id: item.id },
|
|
327
|
+
data: { additionalFields: item.additionalFields },
|
|
328
|
+
})));
|
|
310
329
|
}
|
|
311
330
|
});
|
|
312
331
|
exports.default = commonService;
|
|
@@ -10,9 +10,6 @@ export declare const ALLOWED_CONTENT_TYPES: readonly ["api::", "plugin::"];
|
|
|
10
10
|
export declare const RESTRICTED_CONTENT_TYPES: readonly ["plugin::users-permissions", "plugin::i18n.locale", "plugin::navigation"];
|
|
11
11
|
export declare const EXCLUDED_CONTENT_TYPES: string[];
|
|
12
12
|
export declare const CONTENT_TYPES_NAME_FIELDS_DEFAULTS: string[];
|
|
13
|
-
export declare const ADDITIONAL_FIELDS: {
|
|
14
|
-
AUDIENCE: string;
|
|
15
|
-
};
|
|
16
13
|
export declare const DEFAULT_POPULATE: "localizations"[];
|
|
17
14
|
export declare const DEFAULT_NAVIGATION_ITEM: {
|
|
18
15
|
readonly name: "Main navigation";
|
package/server/utils/constant.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.RENDER_TYPES = exports.DEFAULT_NAVIGATION_ITEM = exports.DEFAULT_POPULATE = exports.
|
|
3
|
+
exports.RENDER_TYPES = exports.DEFAULT_NAVIGATION_ITEM = exports.DEFAULT_POPULATE = exports.CONTENT_TYPES_NAME_FIELDS_DEFAULTS = exports.EXCLUDED_CONTENT_TYPES = exports.RESTRICTED_CONTENT_TYPES = exports.ALLOWED_CONTENT_TYPES = exports.KIND_TYPES = exports.MODEL_TYPES = exports.TEMPLATE_DEFAULT = void 0;
|
|
4
4
|
const i18n_1 = require("../i18n");
|
|
5
5
|
exports.TEMPLATE_DEFAULT = 'Generic';
|
|
6
6
|
exports.MODEL_TYPES = { CONTENT_TYPE: 'contentType' };
|
|
@@ -9,7 +9,6 @@ exports.ALLOWED_CONTENT_TYPES = ['api::', 'plugin::'];
|
|
|
9
9
|
exports.RESTRICTED_CONTENT_TYPES = ['plugin::users-permissions', 'plugin::i18n.locale', 'plugin::navigation'];
|
|
10
10
|
exports.EXCLUDED_CONTENT_TYPES = ['strapi::'];
|
|
11
11
|
exports.CONTENT_TYPES_NAME_FIELDS_DEFAULTS = ['title', 'subject', 'name'];
|
|
12
|
-
exports.ADDITIONAL_FIELDS = { AUDIENCE: 'audience' };
|
|
13
12
|
exports.DEFAULT_POPULATE = [...i18n_1.I18N_DEFAULT_POPULATE];
|
|
14
13
|
exports.DEFAULT_NAVIGATION_ITEM = {
|
|
15
14
|
name: "Main navigation",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { PopulateClause } from 'strapi-typed';
|
|
2
|
+
import { Id, IStrapi, Primitive, StrapiContentType, StringMap, StrapiContentTypeFullSchema } from "strapi-typed";
|
|
3
|
+
import { AuditLogContext, AuditLogParams, ContentTypeEntity, NavigationActions, NavigationItem, NavigationItemAdditionalField, NavigationItemCustomField, NavigationItemEntity, NavigationService, NavigationServiceName, NestedPath, NestedStructure, PluginConfigNameFields, PopulateQueryParam, ToBeFixed } from "../../types";
|
|
3
4
|
import { NavigationError } from '../../utils/NavigationError';
|
|
4
5
|
export declare const getPluginService: <T extends NavigationService>(name: NavigationServiceName) => T;
|
|
5
6
|
export declare const errorHandler: (ctx: ToBeFixed) => (error: NavigationError | string) => any;
|
|
7
|
+
export declare const getCustomFields: (additionalFields: NavigationItemAdditionalField[]) => NavigationItemCustomField[];
|
|
6
8
|
export declare const parseParams: <TParams extends StringMap<string> = StringMap<string>, TResult extends StringMap<Primitive> = StringMap<Primitive>>(params: TParams) => TResult;
|
|
7
9
|
export declare const templateNameFactory: (items: import("strapi-typed").TypeResult<{
|
|
8
10
|
path: string | null;
|
|
@@ -46,11 +48,13 @@ export declare const templateNameFactory: (items: import("strapi-typed").TypeRes
|
|
|
46
48
|
audience: import("../../types").Audience[];
|
|
47
49
|
externalPath: string | null;
|
|
48
50
|
related: import("../../types").NavigationItemRelated | null;
|
|
51
|
+
additionalFields: StringMap<string | boolean>;
|
|
49
52
|
}> | null;
|
|
50
53
|
master: import("../../types").Navigation;
|
|
51
54
|
audience: import("../../types").Audience[];
|
|
52
55
|
externalPath: string | null;
|
|
53
56
|
related: ContentTypeEntity | ContentTypeEntity[] | null;
|
|
57
|
+
additionalFields: StringMap<string | boolean>;
|
|
54
58
|
}>[] | undefined, strapi: IStrapi, contentTypes?: StrapiContentType<ToBeFixed>[]) => Promise<(contentType: ToBeFixed, id: Id) => any>;
|
|
55
59
|
export declare const getTemplateComponentFromTemplate: (strapi: IStrapi, template?: ToBeFixed[]) => any;
|
|
56
60
|
export declare const prepareAuditLog: (actions: NavigationActions[]) => string;
|
|
@@ -60,16 +64,6 @@ export declare const extractItemRelationTitle: (relatedItem: ContentTypeEntity,
|
|
|
60
64
|
export declare const filterOutUnpublished: (item: NavigationItemEntity<ContentTypeEntity | ContentTypeEntity[]>) => unknown;
|
|
61
65
|
export declare const checkDuplicatePath: (parentItem: ToBeFixed | null, checkData: NavigationItem[]) => Promise<void>;
|
|
62
66
|
export declare const singularize: (value?: string) => string;
|
|
63
|
-
export declare const extractMeta: (plugins: {
|
|
64
|
-
[uid: string]: StrapiPlugin;
|
|
65
|
-
}) => {
|
|
66
|
-
masterModel: any;
|
|
67
|
-
itemModel: any;
|
|
68
|
-
relatedModel: any;
|
|
69
|
-
audienceModel: any;
|
|
70
|
-
plugin: StrapiPlugin;
|
|
71
|
-
pluginName: string;
|
|
72
|
-
};
|
|
73
67
|
export declare const buildNestedStructure: (entities: NavigationItemEntity<ContentTypeEntity>[], id?: Id | null, field?: keyof NavigationItemEntity) => NestedStructure<NavigationItemEntity<ContentTypeEntity>>[];
|
|
74
68
|
export declare const buildNestedPaths: <T extends Pick<import("strapi-typed").TypeResult<{
|
|
75
69
|
path: string | null;
|
|
@@ -100,6 +94,7 @@ export declare const buildNestedPaths: <T extends Pick<import("strapi-typed").Ty
|
|
|
100
94
|
audience: import("../../types").Audience[];
|
|
101
95
|
externalPath: string | null;
|
|
102
96
|
related: import("../../types").NavigationItemRelated | null;
|
|
97
|
+
additionalFields: StringMap<string | boolean>;
|
|
103
98
|
}>, "id" | "path" | "parent">>(items: T[], id?: Id | null, parentPath?: string | null) => NestedPath[];
|
|
104
99
|
export declare const filterByPath: <T extends Pick<import("strapi-typed").TypeResult<{
|
|
105
100
|
path: string | null;
|
|
@@ -130,10 +125,15 @@ export declare const filterByPath: <T extends Pick<import("strapi-typed").TypeRe
|
|
|
130
125
|
audience: import("../../types").Audience[];
|
|
131
126
|
externalPath: string | null;
|
|
132
127
|
related: import("../../types").NavigationItemRelated | null;
|
|
128
|
+
additionalFields: StringMap<string | boolean>;
|
|
133
129
|
}>, "id" | "path" | "parent">>(items: T[], path: string | null) => {
|
|
134
130
|
root?: NestedPath | undefined;
|
|
135
131
|
items: T[];
|
|
136
132
|
};
|
|
137
133
|
export declare const isContentTypeEligible: (uid?: string) => boolean | "";
|
|
138
134
|
export declare const intercalate: <T, U extends T>(glue: T, arr: U[]) => (T | U)[];
|
|
135
|
+
export declare const compareArraysOfNumbers: (arrA: number[], arrB: number[]) => number;
|
|
136
|
+
export declare const getPluginModels: () => Record<'masterModel' | 'itemModel' | 'relatedModel' | 'audienceModel', StrapiContentTypeFullSchema>;
|
|
137
|
+
export declare const validateAdditionalFields: (additionalFields: NavigationItemAdditionalField[]) => void;
|
|
138
|
+
export declare const parsePopulateQuery: (populate: PopulateQueryParam) => PopulateClause;
|
|
139
139
|
//# sourceMappingURL=functions.d.ts.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.intercalate = exports.isContentTypeEligible = exports.filterByPath = exports.buildNestedPaths = exports.buildNestedStructure = exports.
|
|
3
|
+
exports.parsePopulateQuery = exports.validateAdditionalFields = exports.getPluginModels = exports.compareArraysOfNumbers = exports.intercalate = exports.isContentTypeEligible = exports.filterByPath = exports.buildNestedPaths = exports.buildNestedStructure = exports.singularize = exports.checkDuplicatePath = exports.filterOutUnpublished = exports.extractItemRelationTitle = exports.composeItemTitle = exports.sendAuditLog = exports.prepareAuditLog = exports.getTemplateComponentFromTemplate = exports.templateNameFactory = exports.parseParams = exports.getCustomFields = exports.errorHandler = exports.getPluginService = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
|
+
const types_1 = require("../../types");
|
|
5
6
|
const NavigationError_1 = require("../../utils/NavigationError");
|
|
6
7
|
const constant_1 = require("./constant");
|
|
7
8
|
const getPluginService = (name) => strapi.plugin("navigation").service(name);
|
|
@@ -13,6 +14,8 @@ const errorHandler = (ctx) => (error) => {
|
|
|
13
14
|
throw error;
|
|
14
15
|
};
|
|
15
16
|
exports.errorHandler = errorHandler;
|
|
17
|
+
const getCustomFields = (additionalFields) => additionalFields.filter(field => typeof field !== 'string');
|
|
18
|
+
exports.getCustomFields = getCustomFields;
|
|
16
19
|
const parseParams = (params) => Object.keys(params).reduce((prev, curr) => {
|
|
17
20
|
const value = params[curr];
|
|
18
21
|
const parsedValue = isNaN(Number(value)) ? value : parseInt(value, 10);
|
|
@@ -25,24 +28,21 @@ exports.parseParams = parseParams;
|
|
|
25
28
|
const templateNameFactory = async (items = [], strapi, contentTypes = []) => {
|
|
26
29
|
const flatRelated = (0, lodash_1.flatten)(items.map(i => i.related)).filter(_ => !!_);
|
|
27
30
|
const relatedMap = (flatRelated).reduce((acc, curr) => {
|
|
28
|
-
if (curr
|
|
31
|
+
if ((0, lodash_1.isNil)(curr) || typeof curr.__contentType !== "string")
|
|
29
32
|
return acc;
|
|
30
33
|
const index = curr.__contentType;
|
|
31
|
-
if (
|
|
32
|
-
return acc;
|
|
33
|
-
if (!acc[index]) {
|
|
34
|
+
if ((0, lodash_1.isNil)(acc[index]))
|
|
34
35
|
acc[index] = [];
|
|
35
|
-
}
|
|
36
|
-
acc[index].push(curr.id);
|
|
37
|
-
return acc;
|
|
36
|
+
return { ...acc, [index]: [...acc[index], curr.id] };
|
|
38
37
|
}, {});
|
|
39
38
|
const responses = await Promise.all(Object.entries(relatedMap)
|
|
40
39
|
.map(([contentType, ids]) => {
|
|
41
|
-
|
|
42
|
-
return strapi.query(
|
|
40
|
+
(0, types_1.assertNotEmpty)((0, lodash_1.find)(contentTypes, cnt => cnt.uid === contentType));
|
|
41
|
+
return strapi.query(contentType)
|
|
43
42
|
.findMany({
|
|
44
43
|
where: { id: { $in: ids } },
|
|
45
44
|
limit: Number.MAX_SAFE_INTEGER,
|
|
45
|
+
populate: ["template"],
|
|
46
46
|
})
|
|
47
47
|
.then(res => ({ [contentType]: res }));
|
|
48
48
|
}));
|
|
@@ -141,18 +141,6 @@ const singularize = (value = '') => {
|
|
|
141
141
|
return (0, lodash_1.last)(value) === 's' ? value.substr(0, value.length - 1) : value;
|
|
142
142
|
};
|
|
143
143
|
exports.singularize = singularize;
|
|
144
|
-
const extractMeta = (plugins) => {
|
|
145
|
-
const { navigation: plugin } = plugins;
|
|
146
|
-
return {
|
|
147
|
-
masterModel: plugin.contentType('navigation'),
|
|
148
|
-
itemModel: plugin.contentType('navigation-item'),
|
|
149
|
-
relatedModel: plugin.contentType('navigations-items-related'),
|
|
150
|
-
audienceModel: plugin.contentType('audience'),
|
|
151
|
-
plugin,
|
|
152
|
-
pluginName: 'navigation',
|
|
153
|
-
};
|
|
154
|
-
};
|
|
155
|
-
exports.extractMeta = extractMeta;
|
|
156
144
|
const buildNestedStructure = (entities, id = null, field = 'parent') => {
|
|
157
145
|
return entities
|
|
158
146
|
.filter(entity => {
|
|
@@ -223,4 +211,54 @@ const isContentTypeEligible = (uid = '') => {
|
|
|
223
211
|
exports.isContentTypeEligible = isContentTypeEligible;
|
|
224
212
|
const intercalate = (glue, arr) => arr.slice(1).reduce((acc, element) => acc.concat([glue, element]), arr.slice(0, 1));
|
|
225
213
|
exports.intercalate = intercalate;
|
|
214
|
+
const compareArraysOfNumbers = (arrA, arrB) => {
|
|
215
|
+
const diff = (0, lodash_1.zipWith)(arrA, arrB, (a, b) => {
|
|
216
|
+
if ((0, lodash_1.isNil)(a))
|
|
217
|
+
return -1;
|
|
218
|
+
if ((0, lodash_1.isNil)(b))
|
|
219
|
+
return 1;
|
|
220
|
+
return a - b;
|
|
221
|
+
});
|
|
222
|
+
return (0, lodash_1.find)(diff, a => a !== 0) || 0;
|
|
223
|
+
};
|
|
224
|
+
exports.compareArraysOfNumbers = compareArraysOfNumbers;
|
|
225
|
+
const getPluginModels = () => {
|
|
226
|
+
const plugin = strapi.plugin('navigation');
|
|
227
|
+
return {
|
|
228
|
+
masterModel: plugin.contentType('navigation'),
|
|
229
|
+
itemModel: plugin.contentType('navigation-item'),
|
|
230
|
+
relatedModel: plugin.contentType('navigations-items-related'),
|
|
231
|
+
audienceModel: plugin.contentType('audience'),
|
|
232
|
+
};
|
|
233
|
+
};
|
|
234
|
+
exports.getPluginModels = getPluginModels;
|
|
235
|
+
const validateAdditionalFields = (additionalFields) => {
|
|
236
|
+
const forbiddenNames = [
|
|
237
|
+
'title', 'type', 'path',
|
|
238
|
+
'externalPath', 'uiRouterKey', 'menuAttached',
|
|
239
|
+
'order', 'collapsed', 'related',
|
|
240
|
+
'parent', 'master', 'audience',
|
|
241
|
+
'additionalFields',
|
|
242
|
+
];
|
|
243
|
+
const customFields = (0, exports.getCustomFields)(additionalFields);
|
|
244
|
+
if (customFields.length !== (0, lodash_1.uniqBy)(customFields, 'name').length) {
|
|
245
|
+
throw new Error('All names of custom fields must be unique.');
|
|
246
|
+
}
|
|
247
|
+
if (!(0, lodash_1.isNil)((0, lodash_1.find)(customFields, item => (0, lodash_1.includes)(forbiddenNames, item.name)))) {
|
|
248
|
+
throw new Error(`Name of custom field cannot be one of: ${forbiddenNames.join(', ')}`);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
exports.validateAdditionalFields = validateAdditionalFields;
|
|
252
|
+
const parsePopulateQuery = (populate) => {
|
|
253
|
+
if (populate === "*") {
|
|
254
|
+
return true;
|
|
255
|
+
}
|
|
256
|
+
else if (typeof populate === "string") {
|
|
257
|
+
return [populate];
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
return populate;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
exports.parsePopulateQuery = parsePopulateQuery;
|
|
226
264
|
//# sourceMappingURL=functions.js.map
|
package/strapi-server.d.ts
CHANGED
|
@@ -28,13 +28,6 @@ declare const _default: () => {
|
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
30
|
navigation: {
|
|
31
|
-
lifecycle: {
|
|
32
|
-
renderType: {
|
|
33
|
-
FLAT: string;
|
|
34
|
-
TREE: string;
|
|
35
|
-
RFR: string;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
31
|
schema: {
|
|
39
32
|
collectionName: string;
|
|
40
33
|
info: {
|
|
@@ -90,19 +83,6 @@ declare const _default: () => {
|
|
|
90
83
|
};
|
|
91
84
|
};
|
|
92
85
|
"navigation-item": {
|
|
93
|
-
lifecycle: {
|
|
94
|
-
type: {
|
|
95
|
-
INTERNAL: string;
|
|
96
|
-
EXTERNAL: string;
|
|
97
|
-
WRAPPER: string;
|
|
98
|
-
};
|
|
99
|
-
additionalFields: {
|
|
100
|
-
AUDIENCE: string;
|
|
101
|
-
};
|
|
102
|
-
lifecycles: {
|
|
103
|
-
afterFind(results: any): void;
|
|
104
|
-
};
|
|
105
|
-
};
|
|
106
86
|
schema: {
|
|
107
87
|
collectionName: string;
|
|
108
88
|
info: {
|
|
@@ -196,15 +176,15 @@ declare const _default: () => {
|
|
|
196
176
|
relation: string;
|
|
197
177
|
target: string;
|
|
198
178
|
};
|
|
179
|
+
additionalFields: {
|
|
180
|
+
type: string;
|
|
181
|
+
require: boolean;
|
|
182
|
+
default: {};
|
|
183
|
+
};
|
|
199
184
|
};
|
|
200
185
|
};
|
|
201
186
|
};
|
|
202
187
|
"navigations-items-related": {
|
|
203
|
-
lifecycle: {
|
|
204
|
-
lifecycles: {
|
|
205
|
-
afterFind(results: any): void;
|
|
206
|
-
};
|
|
207
|
-
};
|
|
208
188
|
schema: {
|
|
209
189
|
collectionName: string;
|
|
210
190
|
info: {
|