strapi-plugin-navigation 2.2.1 → 2.3.0-beta.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.
Files changed (38) hide show
  1. package/README.md +31 -5
  2. package/admin/src/pages/DataManagerProvider/index.js +2 -0
  3. package/admin/src/pages/DataManagerProvider/reducer.d.ts +1 -0
  4. package/admin/src/pages/DataManagerProvider/reducer.js +1 -0
  5. package/admin/src/pages/SettingsPage/components/CustomFieldForm/index.js +2 -0
  6. package/admin/src/pages/SettingsPage/index.js +17 -8
  7. package/admin/src/pages/SettingsPage/types.d.ts +2 -1
  8. package/admin/src/pages/SettingsPage/utils/form.d.ts +2 -0
  9. package/admin/src/pages/SettingsPage/utils/form.js +3 -1
  10. package/admin/src/pages/View/components/NavigationItemForm/index.js +36 -20
  11. package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +6 -0
  12. package/admin/src/pages/View/components/NavigationItemForm/utils/form.js +2 -2
  13. package/admin/src/pages/View/components/NavigationItemPopup/index.d.ts +3 -1
  14. package/admin/src/pages/View/components/NavigationItemPopup/index.js +3 -2
  15. package/admin/src/pages/View/index.js +7 -2
  16. package/admin/src/pages/View/utils/parsers.js +1 -1
  17. package/admin/src/translations/en.json +3 -0
  18. package/package.json +2 -2
  19. package/server/config/index.js +1 -1
  20. package/server/config/setupStrategy.js +1 -9
  21. package/server/content-types/index.d.ts +2 -0
  22. package/server/content-types/navigation/index.d.ts +1 -0
  23. package/server/content-types/navigation/schema.d.ts +1 -0
  24. package/server/content-types/navigation/schema.js +2 -1
  25. package/server/content-types/navigation-item/index.d.ts +1 -0
  26. package/server/content-types/navigation-item/schema.d.ts +1 -0
  27. package/server/content-types/navigation-item/schema.js +2 -1
  28. package/server/controllers/admin.js +13 -0
  29. package/server/index.d.ts +2 -0
  30. package/server/routes/admin.js +10 -0
  31. package/server/services/admin.js +4 -10
  32. package/server/services/client.js +10 -14
  33. package/server/services/common.js +27 -1
  34. package/strapi-server.d.ts +2 -0
  35. package/tsconfig.tsbuildinfo +1 -1
  36. package/types/config.d.ts +1 -1
  37. package/types/controllers.d.ts +5 -0
  38. package/types/services.d.ts +1 -0
package/README.md CHANGED
@@ -149,6 +149,9 @@ Config for this plugin is stored as a part of the `config/plugins.js` or `config
149
149
  > *Note v2.0.3 and newer only*
150
150
  > Changing this file will not automatically change plugin configuration. To synchronize plugin's config with plugins.js file, it is necessary to restore configuration through the settings page
151
151
 
152
+ > *Note for newer than v2.2.0*
153
+ > `slugify` as been removed. **THIS A BREAKING CHANGE**
154
+
152
155
  ```js
153
156
  module.exports = ({ env }) => ({
154
157
  // ...
@@ -162,11 +165,6 @@ Config for this plugin is stored as a part of the `config/plugins.js` or `config
162
165
  },
163
166
  allowedLevels: 2,
164
167
  gql: {...},
165
- slugify: {
166
- customReplacements: [
167
- ["🤔", "thinking"],
168
- ],
169
- }
170
168
  }
171
169
  }
172
170
  });
@@ -179,6 +177,7 @@ Config for this plugin is stored as a part of the `config/plugins.js` or `config
179
177
  - `contentTypesNameFields` - Definition of content type title fields like `'api::<collection name>.<content type name>': ['field_name_1', 'field_name_2']`, if not set titles are pulled from fields like `['title', 'subject', 'name']`. **TIP** - Proper content type uid you can find in the URL of Content Manager where you're managing relevant entities like: `admin/content-manager/collectionType/< THE UID HERE >?page=1&pageSize=10&sort=Title:ASC&plugins[i18n][locale]=en`
180
178
  - `gql` - If you're using GraphQL that's the right place to put all necessary settings. More **[ here ](#gql-configuration)**
181
179
  - `i18nEnabled` - should you want to manage multi-locale content via navigation set this value `Enabled`. More **[ here ](#i18n-internationalization)**
180
+ - `cascadeMenuAttached` - If you don't want "Menu attached" to cascade on child items set this value `Disabled`.
182
181
  - `slugify` - allows to extend configuration of our "slugging" solution of choice. To learn more visit the [documentation](https://github.com/sindresorhus/slugify#api). It can be left unset since it's optional. **This option can only be handled by configuration in config file**.
183
182
 
184
183
  ### Properties
@@ -631,6 +630,33 @@ module.exports = {
631
630
 
632
631
  If you already got it, make sure that `navigation` plugin is inserted before `graphql`. That should do the job.
633
632
 
633
+ ### Slug generation
634
+
635
+ #### Customisation
636
+
637
+ Slug generation is available as a controller and service. If you have custom requirements outside of what this plugin provides you can add your own logic with [plugins extensions](https://docs.strapi.io/developer-docs/latest/development/plugins-extension.html).
638
+
639
+ For example:
640
+
641
+ ```ts
642
+ // path: ./src/index.js
643
+
644
+ module.exports = {
645
+ // ...
646
+ bootstrap({ strapi }) {
647
+ const navigationCommonService = strapi.plugin("navigation").service("common");
648
+ const originalGetSlug = navigationCommonService.getSlug;
649
+ const preprocess = (q) => {
650
+ return q + "suffix";
651
+ };
652
+
653
+ navigationCommonService.getSlug = (query) => {
654
+ return originalGetSlug(preprocess(query));
655
+ };
656
+ },
657
+ };
658
+ ```
659
+
634
660
  ## 🤝 Contributing
635
661
 
636
662
  <div>
@@ -287,6 +287,7 @@ const DataManagerProvider = ({ children }) => {
287
287
  method: "DELETE",
288
288
  signal,
289
289
  });
290
+ const slugify = (query) => (0, helper_plugin_1.request)(`/${pluginId_1.default}/slug?q=${query}`, { method: "GET", signal });
290
291
  const hardReset = () => getDataRef.current();
291
292
  return (react_1.default.createElement(DataManagerContext_1.default.Provider, { value: {
292
293
  items: passedActiveItems,
@@ -316,6 +317,7 @@ const DataManagerProvider = ({ children }) => {
316
317
  readNavigationItemFromLocale,
317
318
  handleNavigationsDeletion,
318
319
  hardReset,
320
+ slugify,
319
321
  } }, isLoading ? react_1.default.createElement(helper_plugin_1.LoadingIndicatorPage, null) : children));
320
322
  };
321
323
  DataManagerProvider.propTypes = {
@@ -14,6 +14,7 @@ export namespace initialState {
14
14
  const isLoadingForSubmit: boolean;
15
15
  const error: undefined;
16
16
  const i18nEnabled: boolean;
17
+ const cascadeMenuAttached: boolean;
17
18
  const availableLocale: never[];
18
19
  }
19
20
  //# sourceMappingURL=reducer.d.ts.map
@@ -20,6 +20,7 @@ const initialState = {
20
20
  isLoadingForSubmit: false,
21
21
  error: undefined,
22
22
  i18nEnabled: false,
23
+ cascadeMenuAttached: true,
23
24
  availableLocale: [],
24
25
  };
25
26
  exports.initialState = initialState;
@@ -64,6 +64,7 @@ const CustomFieldForm = ({ isEditForm, customField, onSubmit, onClose, usedCusto
64
64
  required: customField.required || formDefinition.defaultValues.required,
65
65
  options: customField.options || formDefinition.defaultValues.options,
66
66
  multi: customField.multi || formDefinition.defaultValues.multi,
67
+ enabled: customField.enabled,
67
68
  };
68
69
  }
69
70
  else {
@@ -74,6 +75,7 @@ const CustomFieldForm = ({ isEditForm, customField, onSubmit, onClose, usedCusto
74
75
  required: customField.required || formDefinition.defaultValues.required,
75
76
  options: [],
76
77
  multi: false,
78
+ enabled: customField.enabled,
77
79
  };
78
80
  }
79
81
  }, [customField]);
@@ -83,6 +83,7 @@ const SettingsPage = () => {
83
83
  const formikInitialValues = (0, react_1.useMemo)(() => ({
84
84
  allowedLevels: (0, lodash_1.get)(navigationConfigData, "allowedLevels", 2),
85
85
  audienceFieldChecked: (0, lodash_1.get)(navigationConfigData, "additionalFields", []).includes(utils_1.navigationItemAdditionalFields.AUDIENCE),
86
+ cascadeMenuAttachedChecked: (0, lodash_1.get)(navigationConfigData, "cascadeMenuAttached", true),
86
87
  i18nEnabled: (0, lodash_1.get)(navigationConfigData, "i18nEnabled", false),
87
88
  nameFields: (0, lodash_1.get)(navigationConfigData, "contentTypesNameFields", {}),
88
89
  pathDefaultFields: (0, lodash_1.get)(navigationConfigData, "pathDefaultFields", {}),
@@ -97,9 +98,10 @@ const SettingsPage = () => {
97
98
  ?.filter((field) => field !== utils_1.navigationItemAdditionalFields.AUDIENCE);
98
99
  setCustomFields(additionalFields || []);
99
100
  }, [navigationConfigData]);
100
- const preparePayload = (0, react_1.useCallback)(({ form: { allowedLevels, audienceFieldChecked, i18nEnabled, nameFields, pathDefaultFields, populate, selectedContentTypes, }, pruneObsoleteI18nNavigations }) => ({
101
+ const preparePayload = (0, react_1.useCallback)(({ form: { allowedLevels, audienceFieldChecked, cascadeMenuAttachedChecked, i18nEnabled, nameFields, pathDefaultFields, populate, selectedContentTypes, }, pruneObsoleteI18nNavigations }) => ({
101
102
  additionalFields: audienceFieldChecked ? ['audience', ...customFields] : [...customFields],
102
103
  allowedLevels,
104
+ cascadeMenuAttached: cascadeMenuAttachedChecked,
103
105
  contentTypes: selectedContentTypes,
104
106
  contentTypesNameFields: nameFields,
105
107
  contentTypesPopulate: populate,
@@ -158,7 +160,7 @@ const SettingsPage = () => {
158
160
  react_1.default.createElement(helper_plugin_1.SettingsPageTitle, { name: (0, utils_2.getMessage)('Settings.email.plugin.title', 'Configuration') }),
159
161
  react_1.default.createElement(helper_plugin_1.LoadingIndicatorPage, null, "Fetching plugin config...")));
160
162
  }
161
- const allContentTypes = !isLoading ? Object.values(allContentTypesData).filter(({ uid }) => (0, functions_1.isContentTypeEligible)(uid, {
163
+ const allContentTypes = !isLoading ? (0, lodash_1.sortBy)(Object.values(allContentTypesData).filter(({ uid }) => (0, functions_1.isContentTypeEligible)(uid, {
162
164
  allowedContentTypes: navigationConfigData?.allowedContentTypes,
163
165
  restrictedContentTypes: navigationConfigData?.restrictedContentTypes,
164
166
  })).map(ct => {
@@ -172,7 +174,7 @@ const SettingsPage = () => {
172
174
  };
173
175
  }
174
176
  return ct;
175
- }) : [];
177
+ }), ct => ct.info.displayName) : [];
176
178
  const isI18NPluginEnabled = navigationConfigData?.isI18NPluginEnabled;
177
179
  const defaultLocale = navigationConfigData?.defaultLocale;
178
180
  const handleSubmitCustomField = (field) => {
@@ -221,9 +223,10 @@ const SettingsPage = () => {
221
223
  const contentType = allContentTypes.find(item => item.uid == uid);
222
224
  if (!contentType)
223
225
  return;
224
- const { attributes, info: { displayName }, available, isSingle } = contentType;
225
- const stringAttributes = Object.keys(attributes).filter(_ => STRING_ATTRIBUTE_TYPES.includes(attributes[_].type));
226
- const relationAttributes = Object.keys(attributes).filter(_ => RELATION_ATTRIBUTE_TYPES.includes(attributes[_].type));
226
+ const { info: { displayName }, available, isSingle } = contentType;
227
+ const attributeKeys = Object.keys(contentType.attributes).sort();
228
+ const stringAttributes = attributeKeys.filter(key => STRING_ATTRIBUTE_TYPES.includes(contentType.attributes[key].type));
229
+ const relationAttributes = attributeKeys.filter(key => RELATION_ATTRIBUTE_TYPES.includes(contentType.attributes[key].type));
227
230
  const key = `collectionSettings-${uid}`;
228
231
  return (react_1.default.createElement(Accordion_1.Accordion, { expanded: contentTypeExpanded === key, toggle: () => handleSetContentTypeExpanded(key), key: key, id: key, size: "S" },
229
232
  react_1.default.createElement(Accordion_1.AccordionToggle, { title: displayName, togglePosition: "left", startIcon: (isSingle && !available) ? (react_1.default.createElement(icons_1.ExclamationMarkCircle, { "aria-hidden": true })) : null }),
@@ -239,8 +242,14 @@ const SettingsPage = () => {
239
242
  react_1.default.createElement(Stack_1.Stack, { size: 4 },
240
243
  react_1.default.createElement(Typography_1.Typography, { variant: "delta", as: "h2" }, (0, utils_2.getMessage)('pages.settings.additional.title')),
241
244
  react_1.default.createElement(Grid_1.Grid, { gap: 4 },
242
- react_1.default.createElement(Grid_1.GridItem, { col: 3, s: 6, xs: 12 },
243
- react_1.default.createElement(NumberInput_1.NumberInput, { name: "allowedLevels", label: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.label'), placeholder: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.placeholder'), hint: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.hint'), onValueChange: (value) => setFieldValue('allowedLevels', value, false), value: values.allowedLevels, disabled: restartStatus.required })),
245
+ react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 6, xs: 12 },
246
+ react_1.default.createElement(Box_1.Box, { style: { maxWidth: 257 } },
247
+ react_1.default.createElement(NumberInput_1.NumberInput, { name: "allowedLevels", label: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.label'), placeholder: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.placeholder'), hint: (0, utils_2.getMessage)('pages.settings.form.allowedLevels.hint'), onValueChange: (value) => setFieldValue('allowedLevels', value, false), value: values.allowedLevels, disabled: restartStatus.required }))),
248
+ react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 12, xs: 12 },
249
+ react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "cascadeMenuAttachedChecked", label: (0, utils_2.getMessage)('pages.settings.form.cascadeMenuAttached.label'), hint: (0, utils_2.getMessage)('pages.settings.form.cascadeMenuAttached.hint'), checked: values.cascadeMenuAttachedChecked, onChange: ({ target: { checked } }) => {
250
+ setFieldValue('cascadeMenuAttachedChecked', checked, true);
251
+ }, onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required }))),
252
+ react_1.default.createElement(Grid_1.Grid, { gap: 4 },
244
253
  react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 12, xs: 12 },
245
254
  react_1.default.createElement(ToggleInput_1.ToggleInput, { name: "audienceFieldChecked", label: (0, utils_2.getMessage)('pages.settings.form.audience.label'), hint: (0, utils_2.getMessage)('pages.settings.form.audience.hint'), checked: values.audienceFieldChecked, onChange: () => setFieldValue('audienceFieldChecked', !values.audienceFieldChecked, false), onLabel: "Enabled", offLabel: "Disabled", disabled: restartStatus.required })),
246
255
  isI18NPluginEnabled && (react_1.default.createElement(Grid_1.GridItem, { col: 4, s: 12, xs: 12 },
@@ -3,6 +3,7 @@ import { Effect, NavigationPluginConfig } from "../../../../types";
3
3
  export declare type RawPayload = {
4
4
  allowedLevels: number;
5
5
  audienceFieldChecked: boolean;
6
+ cascadeMenuAttachedChecked: boolean;
6
7
  i18nEnabled: boolean;
7
8
  nameFields: Record<string, string[]>;
8
9
  pathDefaultFields: Record<string, string[]>;
@@ -18,7 +19,7 @@ export declare type StrapiContentTypeSchema = StrapiContentTypeFullSchema & {
18
19
  export declare type PreparePayload = (payload: {
19
20
  form: RawPayload;
20
21
  pruneObsoleteI18nNavigations: boolean;
21
- }) => Omit<NavigationPluginConfig, "slugify">;
22
+ }) => NavigationPluginConfig;
22
23
  export declare type OnSave = Effect<RawPayload>;
23
24
  export declare type OnPopupClose = Effect<boolean>;
24
25
  export declare type HandleSetContentTypeExpanded = Effect<string | undefined>;
@@ -6,6 +6,7 @@ export declare const schemaFactory: (usedCustomFieldNames: string[]) => import("
6
6
  required: import("yup/lib/boolean").RequiredBooleanSchema<boolean | undefined, Record<string, any>>;
7
7
  multi: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
8
8
  options: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
9
+ enabled: import("yup").BooleanSchema<boolean | undefined, Record<string, any>, boolean | undefined>;
9
10
  }, Record<string, any>, import("yup/lib/object").TypeOfShape<{
10
11
  name: import("yup/lib/string").RequiredStringSchema<string | undefined, Record<string, any>>;
11
12
  label: import("yup/lib/string").RequiredStringSchema<string | undefined, Record<string, any>>;
@@ -13,6 +14,7 @@ export declare const schemaFactory: (usedCustomFieldNames: string[]) => import("
13
14
  required: import("yup/lib/boolean").RequiredBooleanSchema<boolean | undefined, Record<string, any>>;
14
15
  multi: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
15
16
  options: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
17
+ enabled: import("yup").BooleanSchema<boolean | undefined, Record<string, any>, boolean | undefined>;
16
18
  }>>;
17
19
  export declare const defaultValues: NavigationItemCustomField;
18
20
  //# sourceMappingURL=form.d.ts.map
@@ -19,7 +19,8 @@ const schemaFactory = (usedCustomFieldNames) => {
19
19
  is: (val) => val === 'select',
20
20
  then: (0, yup_1.array)().of((0, yup_1.string)()),
21
21
  otherwise: (0, yup_1.mixed)().notRequired(),
22
- })
22
+ }),
23
+ enabled: (0, yup_1.bool)().notRequired(),
23
24
  });
24
25
  };
25
26
  exports.schemaFactory = schemaFactory;
@@ -30,5 +31,6 @@ exports.defaultValues = {
30
31
  required: false,
31
32
  multi: false,
32
33
  options: [],
34
+ enabled: true,
33
35
  };
34
36
  //# sourceMappingURL=form.js.map
@@ -28,7 +28,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const react_1 = __importStar(require("react"));
30
30
  const lodash_1 = require("lodash");
31
- const slugify_1 = __importDefault(require("@sindresorhus/slugify"));
31
+ const fp_1 = require("lodash/fp");
32
32
  const formik_1 = require("formik");
33
33
  const ModalLayout_1 = require("@strapi/design-system/ModalLayout");
34
34
  const Select_1 = require("@strapi/design-system/Select");
@@ -44,8 +44,7 @@ const translations_1 = require("../../../../translations");
44
44
  const types_1 = require("../../../../../../types");
45
45
  const AdditionalFieldInput_1 = __importDefault(require("../../../../components/AdditionalFieldInput"));
46
46
  const utils_2 = require("../../../../utils");
47
- const appendLabelPublicationStatusFallback = () => '';
48
- const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading, inputsPrefix, data, contentTypes = [], contentTypeEntities = [], usedContentTypeEntities = [], availableAudience = [], additionalFields = [], contentTypesNameFields = {}, onSubmit, onCancel, getContentTypeEntities, usedContentTypesData, appendLabelPublicationStatus = appendLabelPublicationStatusFallback, locale, readNavigationItemFromLocale, }) => {
47
+ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading, inputsPrefix, data, contentTypes = [], contentTypeEntities = [], usedContentTypeEntities = [], availableAudience = [], additionalFields = [], contentTypesNameFields = {}, onSubmit, onCancel, getContentTypeEntities, usedContentTypesData, appendLabelPublicationStatus = appendLabelPublicationStatusFallback, locale, readNavigationItemFromLocale, slugify, }) => {
49
48
  const [isLoading, setIsLoading] = (0, react_1.useState)(isPreloading);
50
49
  const [hasBeenInitialized, setInitializedState] = (0, react_1.useState)(false);
51
50
  const [hasChanged, setChangedState] = (0, react_1.useState)(false);
@@ -53,8 +52,8 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
53
52
  const [contentTypeSearchInputValue, setContentTypeSearchInputValue] = (0, react_1.useState)(undefined);
54
53
  const formik = (0, formik_1.useFormik)({
55
54
  initialValues: formDefinition.defaultValues,
56
- onSubmit: (payload) => onSubmit(sanitizePayload(payload, data)),
57
- validate: (values) => (0, form_1.checkFormValidity)(sanitizePayload(values, {}), formDefinition.schemaFactory(isSingleSelected, additionalFields)),
55
+ onSubmit: loadingAware(async (payload) => onSubmit(await sanitizePayload(slugify, payload, data)), setIsLoading),
56
+ validate: loadingAware(async (values) => (0, form_1.checkFormValidity)(await sanitizePayload(slugify, values, {}), formDefinition.schemaFactory(isSingleSelected, additionalFields)), setIsLoading),
58
57
  validateOnChange: false,
59
58
  });
60
59
  const initialRelatedTypeSelected = (0, lodash_1.get)(data, 'relatedType.value');
@@ -97,7 +96,10 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
97
96
  })), [availableAudience]);
98
97
  const generatePreviewPath = () => {
99
98
  if (!isExternal) {
100
- const value = `${data.levelPath !== '/' ? `${data.levelPath}` : ''}/${formik.values.path !== '/' ? formik.values.path || '' : ''}`;
99
+ const itemPath = (0, lodash_1.isEmpty)(formik.values.path) || formik.values.path === '/'
100
+ ? getDefaultPath()
101
+ : formik.values.path || "";
102
+ const value = `${data.levelPath !== '/' ? `${data.levelPath}` : ''}/${itemPath}`;
101
103
  return {
102
104
  id: (0, translations_1.getTradId)('popup.item.form.type.external.description'),
103
105
  defaultMessage: '',
@@ -117,7 +119,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
117
119
  }, contentTypesNameFields, { contentTypes });
118
120
  }
119
121
  }, [contentTypeEntities, contentTypesNameFields, contentTypes]);
120
- const sanitizePayload = (payload, data) => {
122
+ const sanitizePayload = async (slugify, payload, data) => {
121
123
  const { related, relatedType, menuAttached, type, ...purePayload } = payload;
122
124
  const relatedId = related;
123
125
  const singleRelatedItem = isSingleSelected ? (0, lodash_1.first)(contentTypeEntities) : undefined;
@@ -125,6 +127,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
125
127
  const title = !!payload.title?.trim()
126
128
  ? payload.title
127
129
  : getDefaultTitle(related, relatedType, isSingleSelected);
130
+ const uiRouterKey = await generateUiRouterKey(slugify, title, relatedId, relatedCollectionType);
128
131
  return {
129
132
  ...data,
130
133
  ...purePayload,
@@ -137,7 +140,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
137
140
  relatedType: type === utils_1.navigationItemType.INTERNAL ? relatedCollectionType : undefined,
138
141
  isSingle: isSingleSelected,
139
142
  singleRelatedItem,
140
- uiRouterKey: generateUiRouterKey(title, relatedId, relatedCollectionType),
143
+ uiRouterKey,
141
144
  };
142
145
  };
143
146
  const onChange = ({ name, value }) => {
@@ -159,11 +162,13 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
159
162
  (0, types_1.assertString)(relatedTypeSelectValue);
160
163
  const pathDefaultFields = (0, lodash_1.get)(config, ["pathDefaultFields", relatedTypeSelectValue], []);
161
164
  if ((0, lodash_1.isEmpty)(formik.values.path) && !(0, lodash_1.isEmpty)(pathDefaultFields)) {
162
- const selectedEntity = contentTypeEntities.find(i => i.id === relatedSelectValue);
165
+ const selectedEntity = isSingleSelected
166
+ ? (0, lodash_1.first)(contentTypeEntities)
167
+ : contentTypeEntities.find(i => i.id === relatedSelectValue);
163
168
  const pathDefaultValues = pathDefaultFields
164
169
  .map((field) => (0, lodash_1.get)(selectedEntity, field, ""))
165
170
  .filter(value => !(0, lodash_1.isNil)(value) && String(value).match(/^\S+$/));
166
- return String((0, lodash_1.first)(pathDefaultValues));
171
+ return String((0, lodash_1.first)(pathDefaultValues) || "");
167
172
  }
168
173
  return "";
169
174
  }, [relatedTypeSelectValue, formik, config]);
@@ -178,17 +183,16 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
178
183
  value,
179
184
  });
180
185
  };
181
- const generateUiRouterKey = (title, related, relatedType) => {
182
- const { slugify: customSlugifyConfig } = config;
186
+ const generateUiRouterKey = async (slugify, title, related, relatedType) => {
183
187
  if (title) {
184
- return (0, lodash_1.isString)(title) && !(0, lodash_1.isEmpty)(title) ? (0, slugify_1.default)(title, customSlugifyConfig).toLowerCase() : undefined;
188
+ return (0, lodash_1.isString)(title) && !(0, lodash_1.isEmpty)(title) ? await slugify(title).then((0, fp_1.prop)("slug")) : undefined;
185
189
  }
186
190
  else if (related) {
187
191
  const relationTitle = (0, parsers_1.extractRelatedItemLabel)({
188
192
  ...contentTypeEntities.find(_ => _.id === related),
189
193
  __collectionUid: relatedType
190
194
  }, contentTypesNameFields, { contentTypes });
191
- return (0, lodash_1.isString)(relationTitle) && !(0, lodash_1.isEmpty)(relationTitle) ? (0, slugify_1.default)(relationTitle, customSlugifyConfig).toLowerCase() : undefined;
195
+ return (0, lodash_1.isString)(relationTitle) && !(0, lodash_1.isEmpty)(relationTitle) ? await slugify(relationTitle).then((0, fp_1.prop)("slug")) : undefined;
192
196
  }
193
197
  return undefined;
194
198
  };
@@ -206,7 +210,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
206
210
  }
207
211
  };
208
212
  });
209
- const relatedSelectOptions = contentTypeEntities
213
+ const relatedSelectOptions = (0, lodash_1.sortBy)(contentTypeEntities
210
214
  .filter((item) => {
211
215
  const usedContentTypeEntitiesOfSameType = usedContentTypeEntities
212
216
  .filter(uctItem => relatedTypeSelectValue === uctItem.__collectionUid);
@@ -228,10 +232,10 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
228
232
  value: item.id,
229
233
  label: label,
230
234
  });
231
- });
235
+ }), item => item.metadatas.intlLabel.id);
232
236
  const isExternal = formik.values.type === utils_1.navigationItemType.EXTERNAL;
233
237
  const pathSourceName = isExternal ? 'externalPath' : 'path';
234
- const submitDisabled = (formik.values.type === utils_1.navigationItemType.INTERNAL && !isSingleSelected && (0, lodash_1.isNil)(formik.values.related));
238
+ const submitDisabled = (formik.values.type === utils_1.navigationItemType.INTERNAL && !isSingleSelected && (0, lodash_1.isNil)(formik.values.related)) || isLoading;
235
239
  const debouncedSearch = (0, react_1.useCallback)((0, lodash_1.debounce)(nextValue => setContentTypeSearchQuery(nextValue), 500), []);
236
240
  const debounceContentTypeSearchQuery = (value) => {
237
241
  setContentTypeSearchInputValue(value);
@@ -251,7 +255,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
251
255
  setChangedState(true);
252
256
  }
253
257
  };
254
- const relatedTypeSelectOptions = (0, react_1.useMemo)(() => contentTypes
258
+ const relatedTypeSelectOptions = (0, react_1.useMemo)(() => (0, lodash_1.sortBy)(contentTypes
255
259
  .filter((contentType) => {
256
260
  if (contentType.isSingle) {
257
261
  if (relatedTypeSelectValue && [relatedTypeSelectValue, initialRelatedTypeSelected].includes(contentType.uid)) {
@@ -271,7 +275,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
271
275
  },
272
276
  value: (0, lodash_1.get)(item, 'uid'),
273
277
  label: (0, lodash_1.get)(item, 'label', (0, lodash_1.get)(item, 'name')),
274
- })), [contentTypes, usedContentTypesData, relatedTypeSelectValue]);
278
+ })), item => item.metadatas.intlLabel.id), [contentTypes, usedContentTypesData, relatedTypeSelectValue]);
275
279
  const thereAreNoMoreContentTypes = (0, lodash_1.isEmpty)(relatedSelectOptions) && !contentTypeSearchQuery;
276
280
  (0, react_1.useEffect)(() => {
277
281
  const value = (0, lodash_1.get)(relatedSelectOptions, '0');
@@ -380,7 +384,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
380
384
  react_1.default.createElement(Grid_1.GridItem, { key: "type", col: 4, lg: 12 },
381
385
  react_1.default.createElement(helper_plugin_1.GenericInput, { intlLabel: (0, translations_1.getTrad)('popup.item.form.type.label', 'Internal link'), name: "type", options: navigationItemTypeOptions, type: "select", error: formik.errors.type, onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values.type })),
382
386
  react_1.default.createElement(Grid_1.GridItem, { key: "menuAttached", col: 4, lg: 12 },
383
- react_1.default.createElement(helper_plugin_1.GenericInput, { intlLabel: (0, translations_1.getTrad)('popup.item.form.menuAttached.label', 'MenuAttached'), name: "menuAttached", type: "bool", error: formik.errors.menuAttached, onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values.menuAttached, disabled: !(data.isMenuAllowedLevel && data.parentAttachedToMenu) })),
387
+ react_1.default.createElement(helper_plugin_1.GenericInput, { intlLabel: (0, translations_1.getTrad)('popup.item.form.menuAttached.label', 'MenuAttached'), name: "menuAttached", type: "bool", error: formik.errors.menuAttached, onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values.menuAttached, disabled: config.cascadeMenuAttached ? !(data.isMenuAllowedLevel && data.parentAttachedToMenu) : false })),
384
388
  react_1.default.createElement(Grid_1.GridItem, { key: "path", col: 12 },
385
389
  react_1.default.createElement(helper_plugin_1.GenericInput, { intlLabel: (0, translations_1.getTrad)(`popup.item.form.${pathSourceName}.label`, 'Path'), name: pathSourceName, placeholder: (0, translations_1.getTrad)(`popup.item.form.${pathSourceName}.placeholder`, 'e.g. Blog'), type: "text", error: formik.errors[pathSourceName], onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values[pathSourceName], description: generatePreviewPath() })),
386
390
  formik.values.type === utils_1.navigationItemType.INTERNAL && (react_1.default.createElement(react_1.default.Fragment, null,
@@ -415,5 +419,17 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
415
419
  react_1.default.createElement(Button_1.Button, { variant: "tertiary", onClick: onCopyFromLocale, disabled: isLoading || !itemLocaleCopyValue }, (0, utils_2.getMessage)('popup.item.form.i18n.locale.button'))))) : null)),
416
420
  react_1.default.createElement(NavigationItemPopupFooter_1.NavigationItemPopupFooter, { handleSubmit: formik.handleSubmit, handleCancel: onCancel, submitDisabled: submitDisabled })));
417
421
  };
422
+ const appendLabelPublicationStatusFallback = () => "";
423
+ const loadingAware = (action, isLoading) => async (input) => {
424
+ try {
425
+ isLoading(true);
426
+ return await action(input);
427
+ }
428
+ catch (_) {
429
+ }
430
+ finally {
431
+ isLoading(false);
432
+ }
433
+ };
418
434
  exports.default = NavigationItemForm;
419
435
  //# sourceMappingURL=index.js.map
@@ -60,6 +60,9 @@ export declare type NavigationItemFormProps = {
60
60
  availableLocale: string[];
61
61
  readNavigationItemFromLocale: ToBeFixed;
62
62
  inputsPrefix: string;
63
+ slugify: (q: string) => Promise<{
64
+ slug: string;
65
+ }>;
63
66
  };
64
67
  export declare type ContentTypeSearchQuery = ToBeFixed;
65
68
  export declare type RawFormPayload = {
@@ -86,5 +89,8 @@ export declare type SanitizedFormPayload = {
86
89
  singleRelatedItem: ContentTypeEntity | undefined;
87
90
  uiRouterKey: string | undefined;
88
91
  };
92
+ export declare type Slugify = (q: string) => Promise<{
93
+ slug: string;
94
+ }>;
89
95
  export {};
90
96
  //# sourceMappingURL=types.d.ts.map
@@ -67,13 +67,13 @@ const schemaFactory = (isSingleSelected, additionalFields) => {
67
67
  relatedType: yup.mixed()
68
68
  .when('type', {
69
69
  is: (val) => val === utils_1.navigationItemType.INTERNAL || (0, lodash_1.isNil)(val),
70
- then: isSingleSelected ? yup.mixed().notRequired() : yup.mixed().required(helper_plugin_1.translatedErrors.required),
70
+ then: yup.string().required(helper_plugin_1.translatedErrors.required).min(1, helper_plugin_1.translatedErrors.required),
71
71
  otherwise: yup.mixed().notRequired(),
72
72
  }),
73
73
  related: yup.mixed()
74
74
  .when('type', {
75
75
  is: (val) => val === utils_1.navigationItemType.INTERNAL || (0, lodash_1.isNil)(val),
76
- then: isSingleSelected ? yup.mixed().notRequired() : yup.mixed().required(helper_plugin_1.translatedErrors.required),
76
+ then: isSingleSelected ? yup.mixed().notRequired() : yup.string().required(helper_plugin_1.translatedErrors.required).min(1, helper_plugin_1.translatedErrors.required),
77
77
  otherwise: yup.mixed().notRequired(),
78
78
  }),
79
79
  additionalFields: yup.object({
@@ -1,5 +1,5 @@
1
1
  export default NavigationItemPopUp;
2
- declare function NavigationItemPopUp({ availableLocale, isOpen, isLoading, data, config, onSubmit, onClose, usedContentTypeItems, getContentTypeItems, usedContentTypesData, locale, readNavigationItemFromLocale, }: {
2
+ declare function NavigationItemPopUp({ availableLocale, isOpen, isLoading, data, config, onSubmit, onClose, usedContentTypeItems, getContentTypeItems, usedContentTypesData, locale, readNavigationItemFromLocale, slugify, }: {
3
3
  availableLocale: any;
4
4
  isOpen: any;
5
5
  isLoading: any;
@@ -12,6 +12,7 @@ declare function NavigationItemPopUp({ availableLocale, isOpen, isLoading, data,
12
12
  usedContentTypesData: any;
13
13
  locale: any;
14
14
  readNavigationItemFromLocale: any;
15
+ slugify: any;
15
16
  }): JSX.Element;
16
17
  declare namespace NavigationItemPopUp {
17
18
  namespace propTypes {
@@ -24,6 +25,7 @@ declare namespace NavigationItemPopUp {
24
25
  const getContentTypeItems: PropTypes.Validator<(...args: any[]) => any>;
25
26
  const locale: PropTypes.Requireable<string>;
26
27
  const readNavigationItemFromLocale: PropTypes.Validator<(...args: any[]) => any>;
28
+ const slugify: PropTypes.Validator<(...args: any[]) => any>;
27
29
  }
28
30
  }
29
31
  import PropTypes from "prop-types";
@@ -34,7 +34,7 @@ const NavigationItemForm_1 = __importDefault(require("../NavigationItemForm"));
34
34
  const parsers_1 = require("../../utils/parsers");
35
35
  const NavigationItemPopupHeader_1 = require("./NavigationItemPopupHeader");
36
36
  const utils_1 = require("../../../../utils");
37
- const NavigationItemPopUp = ({ availableLocale, isOpen, isLoading, data, config = {}, onSubmit, onClose, usedContentTypeItems, getContentTypeItems, usedContentTypesData, locale, readNavigationItemFromLocale, }) => {
37
+ const NavigationItemPopUp = ({ availableLocale, isOpen, isLoading, data, config = {}, onSubmit, onClose, usedContentTypeItems, getContentTypeItems, usedContentTypesData, locale, readNavigationItemFromLocale, slugify, }) => {
38
38
  const handleOnSubmit = (payload) => {
39
39
  onSubmit(payload);
40
40
  };
@@ -71,7 +71,7 @@ const NavigationItemPopUp = ({ availableLocale, isOpen, isLoading, data, config
71
71
  const hasViewId = !!data.viewId;
72
72
  return (react_1.default.createElement(ModalLayout_1.ModalLayout, { labelledBy: "condition-modal-breadcrumbs", onClose: onClose, isOpen: isOpen },
73
73
  react_1.default.createElement(NavigationItemPopupHeader_1.NavigationItemPopupHeader, { isNewItem: !hasViewId }),
74
- react_1.default.createElement(NavigationItemForm_1.default, { availableLocale: availableLocale, config: config, data: preparedData, isLoading: isLoading, additionalFields: additionalFields, contentTypesNameFields: contentTypesNameFields, availableAudience: availableAudience, contentTypes: contentTypes, contentTypeEntities: contentTypeItems, usedContentTypeEntities: usedContentTypeItems, getContentTypeEntities: getContentTypeItems, usedContentTypesData: usedContentTypesData, onSubmit: handleOnSubmit, onCancel: onClose, appendLabelPublicationStatus: appendLabelPublicationStatus, locale: locale, readNavigationItemFromLocale: readNavigationItemFromLocale })));
74
+ react_1.default.createElement(NavigationItemForm_1.default, { availableLocale: availableLocale, config: config, data: preparedData, isLoading: isLoading, additionalFields: additionalFields, contentTypesNameFields: contentTypesNameFields, availableAudience: availableAudience, contentTypes: contentTypes, contentTypeEntities: contentTypeItems, usedContentTypeEntities: usedContentTypeItems, getContentTypeEntities: getContentTypeItems, usedContentTypesData: usedContentTypesData, onSubmit: handleOnSubmit, onCancel: onClose, appendLabelPublicationStatus: appendLabelPublicationStatus, locale: locale, readNavigationItemFromLocale: readNavigationItemFromLocale, slugify: slugify })));
75
75
  };
76
76
  NavigationItemPopUp.propTypes = {
77
77
  data: prop_types_1.default.object.isRequired,
@@ -83,6 +83,7 @@ NavigationItemPopUp.propTypes = {
83
83
  getContentTypeItems: prop_types_1.default.func.isRequired,
84
84
  locale: prop_types_1.default.string,
85
85
  readNavigationItemFromLocale: prop_types_1.default.func.isRequired,
86
+ slugify: prop_types_1.default.func.isRequired,
86
87
  };
87
88
  exports.default = NavigationItemPopUp;
88
89
  //# sourceMappingURL=index.js.map
@@ -50,7 +50,8 @@ const useDataManager_1 = __importDefault(require("../../hooks/useDataManager"));
50
50
  const translations_1 = require("../../translations");
51
51
  const parsers_1 = require("./utils/parsers");
52
52
  const View = () => {
53
- const { items: availableNavigations, activeItem: activeNavigation, changedActiveItem: changedActiveNavigation, config, navigationItemPopupOpened, isLoading, isLoadingForAdditionalDataToBeSet, isLoadingForSubmit, handleChangeNavigationItemPopupVisibility, handleChangeSelection, handleChangeNavigationData, handleResetNavigationData, handleSubmitNavigation, handleLocalizationSelection, handleI18nCopy, getContentTypeItems, error, availableLocale: allAvailableLocale, readNavigationItemFromLocale, } = (0, useDataManager_1.default)();
53
+ const toggleNotification = (0, helper_plugin_1.useNotification)();
54
+ const { items: availableNavigations, activeItem: activeNavigation, changedActiveItem: changedActiveNavigation, config, navigationItemPopupOpened, isLoading, isLoadingForAdditionalDataToBeSet, isLoadingForSubmit, handleChangeNavigationItemPopupVisibility, handleChangeSelection, handleChangeNavigationData, handleResetNavigationData, handleSubmitNavigation, handleLocalizationSelection, handleI18nCopy, getContentTypeItems, error, availableLocale: allAvailableLocale, readNavigationItemFromLocale, slugify, } = (0, useDataManager_1.default)();
54
55
  const availableLocale = (0, react_1.useMemo)(() => allAvailableLocale.filter(locale => locale !== changedActiveNavigation?.localeCode), [changedActiveNavigation, allAvailableLocale]);
55
56
  const { i18nCopyItemsModal, i18nCopySourceLocale, setI18nCopyModalOpened, setI18nCopySourceLocale } = (0, useI18nCopyNavigationItemsModal_1.useI18nCopyNavigationItemsModal)((0, react_1.useCallback)((sourceLocale) => {
56
57
  const source = activeNavigation?.localizations?.find(({ localeCode }) => localeCode === sourceLocale);
@@ -65,6 +66,10 @@ const View = () => {
65
66
  const [structureChanged, setStructureChanged] = (0, react_1.useState)(false);
66
67
  const isSearchEmpty = (0, lodash_1.isEmpty)(searchValue);
67
68
  const structureHasErrors = !(0, parsers_1.validateNavigationStructure)((changedActiveNavigation || {}).items);
69
+ (0, react_1.useEffect)(() => structureHasErrors && toggleNotification({
70
+ type: 'warning',
71
+ message: (0, translations_1.getTrad)('notification.error.item.relation'),
72
+ }), [structureHasErrors]);
68
73
  const navigationSelectValue = (0, lodash_1.get)(activeNavigation, "id", null);
69
74
  const handleSave = () => isLoadingForSubmit || structureHasErrors
70
75
  ? null
@@ -227,7 +232,7 @@ const View = () => {
227
232
  react_1.default.createElement(Button_1.Button, { variant: "tertiary", onClick: openI18nCopyModalOpened, disabled: !i18nCopySourceLocale, size: "S" }, formatMessage((0, translations_1.getTrad)('view.i18n.fill.cta.button'))))))) : null)),
228
233
  !(0, lodash_1.isEmpty)(changedActiveNavigation.items || [])
229
234
  && react_1.default.createElement(NavigationItemList_1.default, { items: isSearchEmpty ? changedActiveNavigation.items || [] : filteredList, onItemLevelAdd: addNewNavigationItem, onItemRemove: handleItemRemove, onItemEdit: handleItemEdit, onItemRestore: handleItemRestore, onItemReOrder: handleItemReOrder, onItemToggleCollapse: handleItemToggleCollapse, displayFlat: !isSearchEmpty, root: true, error: error, allowedLevels: config.allowedLevels, contentTypes: config.contentTypes, isParentAttachedToMenu: true, contentTypesNameFields: config.contentTypesNameFields })))),
230
- navigationItemPopupOpened && react_1.default.createElement(NavigationItemPopup_1.default, { availableLocale: availableLocale, isLoading: isLoadingForAdditionalDataToBeSet, data: activeNavigationItem, config: config, usedContentTypesData: usedContentTypesData, usedContentTypeItems: usedContentTypeItems, getContentTypeItems: getContentTypeItems, onSubmit: handleSubmitNavigationItem, onClose: onPopUpClose, locale: activeNavigation.localeCode, readNavigationItemFromLocale: readNavigationItemFromLocale }),
235
+ navigationItemPopupOpened && react_1.default.createElement(NavigationItemPopup_1.default, { availableLocale: availableLocale, isLoading: isLoadingForAdditionalDataToBeSet, data: activeNavigationItem, config: config, usedContentTypesData: usedContentTypesData, usedContentTypeItems: usedContentTypeItems, getContentTypeItems: getContentTypeItems, onSubmit: handleSubmitNavigationItem, onClose: onPopUpClose, locale: activeNavigation.localeCode, readNavigationItemFromLocale: readNavigationItemFromLocale, slugify: slugify }),
231
236
  i18nCopyItemsModal));
232
237
  };
233
238
  exports.default = (0, react_1.memo)(View);
@@ -14,7 +14,7 @@ const transformItemToRESTPayload = (item, parent = undefined, master = undefined
14
14
  const relatedContentType = relatedType ?
15
15
  (0, lodash_1.find)(contentTypes, ct => ct.uid === relatedType) :
16
16
  undefined;
17
- const itemAttachedToMenu = menuAttached && parentAttachedToMenu;
17
+ const itemAttachedToMenu = config.cascadeMenuAttached ? menuAttached && parentAttachedToMenu : menuAttached;
18
18
  return {
19
19
  id,
20
20
  parent,
@@ -82,6 +82,7 @@
82
82
  "notification.navigation.item.relation.status.published": "published",
83
83
  "notification.error": "Error while processing request.",
84
84
  "notification.error.customField.type": "Unsupported type of custom field",
85
+ "notification.error.item.relation": "Relations provided in some items are incorrect",
85
86
  "pages.main.search.placeholder": "Type to start searching...",
86
87
  "pages.main.header.localization.select.placeholder": "Select locale",
87
88
  "pages.settings.general.title": "General settings",
@@ -122,6 +123,8 @@
122
123
  "pages.settings.notification.submit.error": "Config update has failed",
123
124
  "pages.settings.notification.restore.error": "Config restore has failed",
124
125
  "pages.settings.notification.restart.error": "Failed to restart your application. Try to do it manually.",
126
+ "pages.settings.form.cascadeMenuAttached.label": "Cascade menu attached",
127
+ "pages.settings.form.cascadeMenuAttached.hint": "Disable if you don't want \"Menu attached\" to cascade on child items",
125
128
  "pages.settings.form.contentTypes.label": "Enable navigation for",
126
129
  "pages.settings.form.i18n.label": "i18n",
127
130
  "pages.settings.form.i18n.hint": "Enable internationalisation",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-navigation",
3
- "version": "2.2.1",
3
+ "version": "2.3.0-beta.0",
4
4
  "description": "Strapi - Navigation plugin",
5
5
  "strapi": {
6
6
  "name": "navigation",
@@ -15,7 +15,7 @@
15
15
  "scripts": {},
16
16
  "dependencies": {
17
17
  "@sindresorhus/slugify": "1.1.0",
18
- "@strapi/utils": "^4.3.2",
18
+ "@strapi/utils": "^4.3.8",
19
19
  "lodash": "^4.17.11",
20
20
  "pluralize": "^8.0.0",
21
21
  "react": "^16.9.0",
@@ -28,7 +28,7 @@ const config = {
28
28
  i18nEnabled: false,
29
29
  pathDefaultFields: {},
30
30
  pruneObsoleteI18nNavigations: false,
31
- slugify: {},
31
+ cascadeMenuAttached: true,
32
32
  },
33
33
  };
34
34
  exports.default = config;
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.configSetupStrategy = void 0;
4
- const lodash_1 = require("lodash");
5
4
  const types_1 = require("../../types");
6
5
  const utils_1 = require("../utils");
7
6
  const configSetupStrategy = async ({ strapi }) => {
@@ -23,9 +22,9 @@ const configSetupStrategy = async ({ strapi }) => {
23
22
  allowedLevels: getWithFallback("allowedLevels"),
24
23
  gql: getWithFallback("gql"),
25
24
  i18nEnabled: hasI18nPlugin && getWithFallback("i18nEnabled"),
26
- slugify: (0, lodash_1.pick)(getWithFallback("slugify"), validSlugifyFields),
27
25
  pruneObsoleteI18nNavigations: false,
28
26
  pathDefaultFields: getWithFallback("pathDefaultFields"),
27
+ cascadeMenuAttached: getWithFallback("cascadeMenuAttached"),
29
28
  };
30
29
  (0, utils_1.validateAdditionalFields)(config.additionalFields);
31
30
  await pluginStore.set({
@@ -40,11 +39,4 @@ const getWithFallbackFactory = (config, fallback) => (key) => {
40
39
  (0, types_1.assertNotEmpty)(value, new Error(`[Navigation] Config "${key}" is undefined`));
41
40
  return value;
42
41
  };
43
- const validSlugifyFields = [
44
- "separator",
45
- "lowercase",
46
- "decamelize",
47
- "customReplacements",
48
- "preserveLeadingUnderscore",
49
- ];
50
42
  //# sourceMappingURL=setupStrategy.js.map