strapi-plugin-navigation 2.3.0-beta.0 → 2.3.1

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 (81) hide show
  1. package/README.md +128 -31
  2. package/admin/src/components/AdditionalFieldInput/index.js +2 -2
  3. package/admin/src/components/AdditionalFieldInput/types.d.ts +4 -3
  4. package/admin/src/components/ConfirmationDialog/index.d.ts +10 -10
  5. package/admin/src/components/EmptyView/index.js +2 -0
  6. package/admin/src/components/Item/ItemCardHeader/icons.d.ts +1 -1
  7. package/admin/src/components/Item/ItemCardHeader/icons.js +2 -1
  8. package/admin/src/components/Item/ItemCardHeader/index.d.ts +1 -0
  9. package/admin/src/components/Item/ItemCardHeader/index.js +10 -8
  10. package/admin/src/components/Item/index.d.ts +15 -15
  11. package/admin/src/components/Item/index.js +10 -8
  12. package/admin/src/components/NavigationItemList/index.d.ts +13 -12
  13. package/admin/src/components/NavigationItemList/index.js +2 -2
  14. package/admin/src/hooks/useNavigationManager.d.ts +0 -1
  15. package/admin/src/index.d.ts +5 -7
  16. package/admin/src/index.js +12 -18
  17. package/admin/src/pages/DataManagerProvider/index.d.ts +1 -1
  18. package/admin/src/pages/DataManagerProvider/index.js +32 -5
  19. package/admin/src/pages/DataManagerProvider/reducer.d.ts +16 -16
  20. package/admin/src/pages/NoAccessPage/index.d.ts +3 -0
  21. package/admin/src/pages/NoAccessPage/index.js +31 -0
  22. package/admin/src/pages/SettingsPage/index.d.ts +0 -1
  23. package/admin/src/pages/SettingsPage/index.js +9 -0
  24. package/admin/src/pages/SettingsPage/types.d.ts +8 -8
  25. package/admin/src/pages/SettingsPage/utils/functions.d.ts +0 -2
  26. package/admin/src/pages/View/components/NavigationHeader/index.d.ts +2 -1
  27. package/admin/src/pages/View/components/NavigationHeader/index.js +19 -9
  28. package/admin/src/pages/View/components/NavigationItemForm/index.js +25 -19
  29. package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +10 -9
  30. package/admin/src/pages/View/components/NavigationItemForm/utils/form.d.ts +6 -6
  31. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.d.ts +12 -10
  32. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +5 -1
  33. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.d.ts +2 -1
  34. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +6 -2
  35. package/admin/src/pages/View/components/NavigationItemPopup/index.d.ts +13 -12
  36. package/admin/src/pages/View/components/NavigationItemPopup/index.js +4 -3
  37. package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.d.ts +0 -1
  38. package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.d.ts +0 -1
  39. package/admin/src/pages/View/components/NavigationManager/DeletionConfirm/index.d.ts +0 -1
  40. package/admin/src/pages/View/components/NavigationManager/ErrorDetails/index.d.ts +0 -1
  41. package/admin/src/pages/View/components/NavigationManager/Footer/index.d.ts +1 -1
  42. package/admin/src/pages/View/components/NavigationManager/Form/index.d.ts +0 -1
  43. package/admin/src/pages/View/components/NavigationManager/NavigationUpdate/index.d.ts +0 -1
  44. package/admin/src/pages/View/components/NavigationManager/NewNavigation/index.d.ts +0 -1
  45. package/admin/src/pages/View/components/NavigationManager/index.d.ts +0 -1
  46. package/admin/src/pages/View/components/NavigationManager/types.d.ts +3 -3
  47. package/admin/src/pages/View/index.d.ts +1 -1
  48. package/admin/src/pages/View/index.js +42 -25
  49. package/admin/src/permissions.d.ts +6 -2
  50. package/admin/src/permissions.js +1 -0
  51. package/admin/src/translations/ca.json +198 -0
  52. package/admin/src/translations/en.json +11 -1
  53. package/admin/src/translations/fr.json +3 -1
  54. package/admin/src/translations/index.d.ts +2 -0
  55. package/admin/src/translations/index.js +2 -0
  56. package/admin/src/utils/functions.d.ts +2 -2
  57. package/package.json +16 -14
  58. package/permissions.d.ts +1 -0
  59. package/permissions.js +1 -0
  60. package/server/bootstrap/index.js +6 -0
  61. package/server/config/setupStrategy.js +11 -0
  62. package/server/controllers/client.js +15 -0
  63. package/server/i18n/graphQLEnhancers.d.ts +1 -1
  64. package/server/i18n/navigationSetupStrategy.js +68 -40
  65. package/server/i18n/types.d.ts +11 -11
  66. package/server/i18n/utils.d.ts +2 -2
  67. package/server/routes/admin.js +99 -2
  68. package/server/routes/client.js +8 -0
  69. package/server/services/admin.js +114 -57
  70. package/server/services/client.js +17 -1
  71. package/server/services/common.js +31 -16
  72. package/server/utils/functions.d.ts +3 -1
  73. package/server/utils/functions.js +31 -2
  74. package/tsconfig.tsbuildinfo +1 -1
  75. package/types/config.d.ts +8 -8
  76. package/types/contentTypes.d.ts +20 -20
  77. package/types/controllers.d.ts +3 -2
  78. package/types/graphQL.d.ts +1 -1
  79. package/types/i18n.d.ts +2 -2
  80. package/types/services.d.ts +7 -3
  81. package/types/utils.d.ts +25 -20
@@ -40,6 +40,8 @@ const reducer_1 = __importStar(require("./reducer"));
40
40
  const actions_1 = require("./actions");
41
41
  const parsers_1 = require("../View/utils/parsers");
42
42
  const utils_1 = require("../../utils");
43
+ const NoAccessPage_1 = __importDefault(require("../NoAccessPage"));
44
+ const permissions_1 = __importDefault(require("../../permissions"));
43
45
  const i18nAwareItems = ({ items, config }) => config.i18nEnabled ? items.filter(({ localeCode }) => localeCode === config.defaultLocale) : items;
44
46
  const DataManagerProvider = ({ children }) => {
45
47
  const [reducerState, dispatch] = (0, react_1.useReducer)(reducer_1.default, reducer_1.initialState, init_1.default);
@@ -50,6 +52,11 @@ const DataManagerProvider = ({ children }) => {
50
52
  const { pathname } = (0, react_router_dom_1.useLocation)();
51
53
  const formatMessageRef = (0, react_1.useRef)();
52
54
  formatMessageRef.current = formatMessage;
55
+ const viewPermissions = (0, react_1.useMemo)(() => ({
56
+ access: permissions_1.default.access || permissions_1.default.update,
57
+ update: permissions_1.default.update,
58
+ }), []);
59
+ const { isLoading: isLoadingForPermissions, allowedActions: { canAccess, canUpdate, }, } = (0, helper_plugin_1.useRBAC)(viewPermissions);
53
60
  const getLayoutSettingRef = (0, react_1.useRef)();
54
61
  getLayoutSettingRef.current = (settingName) => (0, lodash_1.get)({}, ["settings", settingName], "");
55
62
  const isInDevelopmentMode = autoReload;
@@ -267,12 +274,18 @@ const DataManagerProvider = ({ children }) => {
267
274
  type: actions_1.SUBMIT_NAVIGATION_ERROR,
268
275
  error: err.response.payload.data
269
276
  });
270
- console.error({ err: err.response });
271
- if (err.response.payload.data && err.response.payload.data.errorTitles) {
277
+ if (err.response.payload.error &&
278
+ err.response.payload.error.details &&
279
+ err.response.payload.error.details.errorTitles) {
272
280
  return toggleNotification({
273
281
  type: 'warning',
274
282
  message: {
275
- id: formatMessage((0, translations_1.getTrad)('notification.navigation.error'), { ...err.response.payload.data, errorTitles: err.response.payload.data.errorTitles.join(' and ') })
283
+ id: formatMessage((0, translations_1.getTrad)('notification.navigation.error'), {
284
+ ...err.response.payload.error.details,
285
+ errorTitles: err.response.payload.error.details.errorTitles
286
+ .map(title => `"${title}"`)
287
+ .join(", ")
288
+ })
276
289
  },
277
290
  });
278
291
  }
@@ -287,8 +300,19 @@ const DataManagerProvider = ({ children }) => {
287
300
  method: "DELETE",
288
301
  signal,
289
302
  });
290
- const slugify = (query) => (0, helper_plugin_1.request)(`/${pluginId_1.default}/slug?q=${query}`, { method: "GET", signal });
303
+ const slugify = (query) => (0, helper_plugin_1.request)(`/${pluginId_1.default}/slug?q=${query}`, { method: "GET", signal }).then((res) => {
304
+ if (!res?.slug) {
305
+ toggleNotification({
306
+ type: 'warning',
307
+ message: formatMessage((0, translations_1.getTrad)('notification.error.item.slug'), { query, result: res?.slug || "" })
308
+ });
309
+ }
310
+ return res;
311
+ });
291
312
  const hardReset = () => getDataRef.current();
313
+ if (!canAccess && !isLoadingForPermissions) {
314
+ return (react_1.default.createElement(NoAccessPage_1.default, null));
315
+ }
292
316
  return (react_1.default.createElement(DataManagerContext_1.default.Provider, { value: {
293
317
  items: passedActiveItems,
294
318
  activeItem,
@@ -318,7 +342,10 @@ const DataManagerProvider = ({ children }) => {
318
342
  handleNavigationsDeletion,
319
343
  hardReset,
320
344
  slugify,
321
- } }, isLoading ? react_1.default.createElement(helper_plugin_1.LoadingIndicatorPage, null) : children));
345
+ permissions: {
346
+ canAccess, canUpdate
347
+ },
348
+ } }, isLoading || isLoadingForPermissions ? react_1.default.createElement(helper_plugin_1.LoadingIndicatorPage, null) : children));
322
349
  };
323
350
  DataManagerProvider.propTypes = {
324
351
  children: prop_types_1.default.node.isRequired,
@@ -1,20 +1,20 @@
1
1
  export default reducer;
2
- declare function reducer(state: any, action: any): any;
2
+ declare function reducer(state: any, action: any): (base?: ((draftState: any) => any) | undefined, ...args: unknown[]) => ((draftState: any) => any) | Promise<(draftState: any) => any>;
3
3
  export namespace initialState {
4
- const items: never[];
5
- const activeItem: undefined;
6
- const changedActiveItem: undefined;
7
- const navigationPopupOpened: boolean;
8
- const navigationItemPopupOpened: boolean;
9
- const config: {};
10
- const isLoading: boolean;
11
- const isLoadingForDataToBeSet: boolean;
12
- const isLoadingForDetailsDataToBeSet: boolean;
13
- const isLoadingForAdditionalDataToBeSet: boolean;
14
- const isLoadingForSubmit: boolean;
15
- const error: undefined;
16
- const i18nEnabled: boolean;
17
- const cascadeMenuAttached: boolean;
18
- const availableLocale: never[];
4
+ let items: never[];
5
+ let activeItem: undefined;
6
+ let changedActiveItem: undefined;
7
+ let navigationPopupOpened: boolean;
8
+ let navigationItemPopupOpened: boolean;
9
+ let config: {};
10
+ let isLoading: boolean;
11
+ let isLoadingForDataToBeSet: boolean;
12
+ let isLoadingForDetailsDataToBeSet: boolean;
13
+ let isLoadingForAdditionalDataToBeSet: boolean;
14
+ let isLoadingForSubmit: boolean;
15
+ let error: undefined;
16
+ let i18nEnabled: boolean;
17
+ let cascadeMenuAttached: boolean;
18
+ let availableLocale: never[];
19
19
  }
20
20
  //# sourceMappingURL=reducer.d.ts.map
@@ -0,0 +1,3 @@
1
+ declare const NoAcccessPage: () => JSX.Element;
2
+ export default NoAcccessPage;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_1 = __importDefault(require("react"));
7
+ const helper_plugin_1 = require("@strapi/helper-plugin");
8
+ const Main_1 = require("@strapi/design-system/Main");
9
+ const Layout_1 = require("@strapi/design-system/Layout");
10
+ const EmptyStateLayout_1 = require("@strapi/design-system/EmptyStateLayout");
11
+ const icons_1 = require("@strapi/icons");
12
+ const react_intl_1 = require("react-intl");
13
+ const NoAcccessPage = () => {
14
+ const { formatMessage } = (0, react_intl_1.useIntl)();
15
+ (0, helper_plugin_1.useFocusWhenNavigate)();
16
+ return (react_1.default.createElement(Main_1.Main, { labelledBy: "title" },
17
+ react_1.default.createElement(Layout_1.HeaderLayout, { id: "title", title: formatMessage({
18
+ id: 'page.auth.noAccess',
19
+ defaultMessage: 'No access',
20
+ }) }),
21
+ react_1.default.createElement(Layout_1.ContentLayout, null,
22
+ react_1.default.createElement(EmptyStateLayout_1.EmptyStateLayout, { action: react_1.default.createElement(helper_plugin_1.LinkButton, { variant: "secondary", endIcon: react_1.default.createElement(icons_1.ArrowRight, null), to: "/" }, formatMessage({
23
+ id: 'components.notAccessPage.back',
24
+ defaultMessage: 'Back to homepage',
25
+ })), content: formatMessage({
26
+ id: 'page.auth.not.allowed',
27
+ defaultMessage: "Oops! It seems like You do not have access to this page...",
28
+ }), hasRadius: true, icon: react_1.default.createElement(icons_1.EmptyPictures, { width: "10rem" }), shadow: "tableShadow" }))));
29
+ };
30
+ exports.default = NoAcccessPage;
31
+ //# sourceMappingURL=index.js.map
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  declare const SettingsPage: () => JSX.Element;
3
2
  export default SettingsPage;
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -55,6 +55,8 @@ const styles_1 = require("../../components/Alert/styles");
55
55
  const DisableI18nModal_1 = require("./components/DisableI18nModal");
56
56
  const CustomFieldModal_1 = __importDefault(require("./components/CustomFieldModal"));
57
57
  const CustomFieldTable_1 = __importDefault(require("./components/CustomFieldTable"));
58
+ const permissions_2 = __importDefault(require("../../permissions"));
59
+ const NoAccessPage_1 = __importDefault(require("../NoAccessPage"));
58
60
  const RESTART_NOT_REQUIRED = { required: false };
59
61
  const RESTART_REQUIRED = { required: true, reasons: [] };
60
62
  const RELATION_ATTRIBUTE_TYPES = ['relation', 'media', 'component'];
@@ -77,6 +79,10 @@ const SettingsPage = () => {
77
79
  const [contentTypeExpanded, setContentTypeExpanded] = (0, react_1.useState)(undefined);
78
80
  const { data: navigationConfigData, isLoading: isConfigLoading, error: configErr, submitMutation, restoreMutation, restartMutation } = (0, useNavigationConfig_1.default)();
79
81
  const { data: allContentTypesData, isLoading: isContentTypesLoading, error: contentTypesErr } = (0, useAllContentTypes_1.default)();
82
+ const viewPermissions = (0, react_1.useMemo)(() => ({
83
+ settings: permissions_2.default.settings
84
+ }), []);
85
+ const { isLoading: isLoadingForPermissions, allowedActions: { canSettings: canManageSettings, }, } = (0, helper_plugin_1.useRBAC)(viewPermissions);
80
86
  const isLoading = isConfigLoading || isContentTypesLoading;
81
87
  const isError = configErr || contentTypesErr;
82
88
  const configContentTypes = navigationConfigData?.contentTypes || [];
@@ -155,6 +161,9 @@ const SettingsPage = () => {
155
161
  };
156
162
  const handleRestartDiscard = () => setRestartStatus(RESTART_NOT_REQUIRED);
157
163
  const handleSetContentTypeExpanded = key => setContentTypeExpanded(key === contentTypeExpanded ? undefined : key);
164
+ if (!(isLoadingForPermissions || canManageSettings)) {
165
+ return (react_1.default.createElement(NoAccessPage_1.default, null));
166
+ }
158
167
  if (isLoading || isError) {
159
168
  return (react_1.default.createElement(react_1.default.Fragment, null,
160
169
  react_1.default.createElement(helper_plugin_1.SettingsPageTitle, { name: (0, utils_2.getMessage)('Settings.email.plugin.title', 'Configuration') }),
@@ -1,6 +1,6 @@
1
1
  import { StrapiContentTypeFullSchema } from "strapi-typed";
2
2
  import { Effect, NavigationPluginConfig } from "../../../../types";
3
- export declare type RawPayload = {
3
+ export type RawPayload = {
4
4
  allowedLevels: number;
5
5
  audienceFieldChecked: boolean;
6
6
  cascadeMenuAttachedChecked: boolean;
@@ -10,21 +10,21 @@ export declare type RawPayload = {
10
10
  populate: Record<string, string[]>;
11
11
  selectedContentTypes: string[];
12
12
  };
13
- export declare type StrapiContentTypeSchema = StrapiContentTypeFullSchema & {
13
+ export type StrapiContentTypeSchema = StrapiContentTypeFullSchema & {
14
14
  available: boolean;
15
15
  isSingle: boolean;
16
16
  plugin: string;
17
17
  label: string;
18
18
  };
19
- export declare type PreparePayload = (payload: {
19
+ export type PreparePayload = (payload: {
20
20
  form: RawPayload;
21
21
  pruneObsoleteI18nNavigations: boolean;
22
22
  }) => NavigationPluginConfig;
23
- export declare type OnSave = Effect<RawPayload>;
24
- export declare type OnPopupClose = Effect<boolean>;
25
- export declare type HandleSetContentTypeExpanded = Effect<string | undefined>;
26
- export declare type RestartReasons = 'I18N' | 'GRAPH_QL' | 'I18N_NAVIGATIONS_PRUNE';
27
- export declare type RestartStatus = {
23
+ export type OnSave = Effect<RawPayload>;
24
+ export type OnPopupClose = Effect<boolean>;
25
+ export type HandleSetContentTypeExpanded = Effect<string | undefined>;
26
+ export type RestartReasons = 'I18N' | 'GRAPH_QL' | 'I18N_NAVIGATIONS_PRUNE';
27
+ export type RestartStatus = {
28
28
  required: true;
29
29
  reasons?: RestartReasons[];
30
30
  } | {
@@ -1,5 +1,3 @@
1
1
  export function resolveGlobalLikeId(uid?: string): any;
2
- export function resolveGlobalLikeId(uid?: string): any;
3
- export function isContentTypeEligible(uid?: string, config?: {}): boolean;
4
2
  export function isContentTypeEligible(uid?: string, config?: {}): boolean;
5
3
  //# sourceMappingURL=functions.d.ts.map
@@ -1,5 +1,5 @@
1
1
  export default NavigationHeader;
2
- declare function NavigationHeader({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, }: {
2
+ declare function NavigationHeader({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, permissions, }: {
3
3
  activeNavigation: any;
4
4
  availableNavigations: any;
5
5
  structureHasErrors: any;
@@ -8,5 +8,6 @@ declare function NavigationHeader({ activeNavigation, availableNavigations, stru
8
8
  handleLocalizationSelection: any;
9
9
  handleSave: any;
10
10
  config: any;
11
+ permissions?: {} | undefined;
11
12
  }): JSX.Element;
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -32,7 +32,11 @@ const Layout_1 = require("@strapi/design-system/Layout");
32
32
  const Stack_1 = require("@strapi/design-system/Stack");
33
33
  const Button_1 = require("@strapi/design-system/Button");
34
34
  const Check_1 = __importDefault(require("@strapi/icons/Check"));
35
+ const More_1 = __importDefault(require("@strapi/icons/More"));
36
+ const Information_1 = __importDefault(require("@strapi/icons/Information"));
37
+ const Tag_1 = require("@strapi/design-system/Tag");
35
38
  const translations_1 = require("../../../../translations");
39
+ const styles_1 = require("./styles");
36
40
  const Select_1 = require("@strapi/design-system/Select");
37
41
  const Box_1 = require("@strapi/design-system/Box");
38
42
  const Grid_1 = require("@strapi/design-system/Grid");
@@ -46,7 +50,7 @@ const pickDefaultLocaleNavigation = ({ activeNavigation, config }) => config.i18
46
50
  : activeNavigation?.localizations.find(({ localeCode }) => localeCode === config.defaultLocale)
47
51
  : null
48
52
  : activeNavigation;
49
- const NavigationHeader = ({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, }) => {
53
+ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, permissions = {}, }) => {
50
54
  const { formatMessage } = (0, react_intl_1.useIntl)();
51
55
  const allLocaleVersions = (0, react_1.useMemo)(() => activeNavigation?.localizations.length && config.i18nEnabled
52
56
  ? (0, lodash_1.uniqBy)([activeNavigation, ...(activeNavigation.localizations ?? [])].sort((a, b) => a.localeCode.localeCompare(b.localeCode)), 'id')
@@ -54,21 +58,27 @@ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHas
54
58
  const hasLocalizations = config.i18nEnabled && allLocaleVersions.length;
55
59
  const passedActiveNavigation = pickDefaultLocaleNavigation({ activeNavigation, config });
56
60
  const { closeNavigationManagerModal, openNavigationManagerModal, navigationManagerModal } = (0, useNavigationManager_1.useNavigationManager)();
57
- return (react_1.default.createElement(Layout_1.HeaderLayout, { primaryAction: react_1.default.createElement(Stack_1.Stack, { horizontal: true, size: 2 },
58
- react_1.default.createElement(Box_1.Box, { width: "27vw", marginRight: "8px" },
61
+ const { canUpdate } = permissions;
62
+ return (react_1.default.createElement(Layout_1.HeaderLayout, { secondaryAction: react_1.default.createElement(Tag_1.Tag, { icon: react_1.default.createElement(Information_1.default, { "aria-hidden": true }) }, activeNavigation
63
+ ? formatMessage((0, translations_1.getTrad)('header.meta'), {
64
+ id: activeNavigation?.id,
65
+ key: activeNavigation?.slug
66
+ })
67
+ : null), primaryAction: react_1.default.createElement(Stack_1.Stack, { horizontal: true, size: 2 },
68
+ react_1.default.createElement(Box_1.Box, { marginRight: "8px" },
59
69
  react_1.default.createElement(Grid_1.Grid, { gap: 4 },
60
70
  !hasLocalizations ? (react_1.default.createElement(Grid_1.GridItem, { col: 2 })) : null,
61
- react_1.default.createElement(Grid_1.GridItem, { col: 3 },
62
- react_1.default.createElement(Button_1.Button, { onClick: openNavigationManagerModal, startIcon: null, type: "button", variant: "secondary", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('header.action.manage')))),
63
- react_1.default.createElement(Grid_1.GridItem, { col: 4 },
71
+ canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
72
+ react_1.default.createElement(Button_1.Button, { onClick: openNavigationManagerModal, startIcon: null, type: "button", variant: "secondary", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('header.action.manage'))))),
73
+ react_1.default.createElement(Grid_1.GridItem, { col: canUpdate ? 4 : 10 },
64
74
  react_1.default.createElement(Select_1.Select, { type: "select", placeholder: "Change navigation", name: "navigationSelect", onChange: handleChangeSelection, value: passedActiveNavigation?.id, size: "S", style: null }, availableNavigations.map(({ id, name }) => react_1.default.createElement(Select_1.Option, { key: id, value: id }, name)))),
65
75
  hasLocalizations
66
76
  ? react_1.default.createElement(Grid_1.GridItem, { col: 2 },
67
77
  react_1.default.createElement(Select_1.Select, { type: "select", placeholder: formatMessage((0, translations_1.getTrad)('pages.main.header.localization.select.placeholder')), name: "navigationLocalizationSelect", onChange: handleLocalizationSelection, value: activeNavigation?.id, size: "S" }, allLocaleVersions.map(({ id, localeCode }) => react_1.default.createElement(Select_1.Option, { key: id, value: id }, localeCode))))
68
78
  : null,
69
- react_1.default.createElement(Grid_1.GridItem, { col: 3 },
70
- react_1.default.createElement(Button_1.Button, { onClick: handleSave, startIcon: submitIcon, disabled: structureHasErrors || !structureHasChanged, type: "submit", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('submit.cta.save')))))),
71
- navigationManagerModal), title: formatMessage({
79
+ canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
80
+ react_1.default.createElement(Button_1.Button, { onClick: handleSave, startIcon: submitIcon, disabled: structureHasErrors || !structureHasChanged, type: "submit", fullWidth: true, size: "S" }, formatMessage((0, translations_1.getTrad)('submit.cta.save'))))))),
81
+ canUpdate && navigationManagerModal), title: formatMessage({
72
82
  id: (0, translations_1.getTrad)('header.title'),
73
83
  defaultMessage: 'UI Navigation',
74
84
  }), subtitle: formatMessage({
@@ -44,12 +44,13 @@ 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 NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading, inputsPrefix, data, contentTypes = [], contentTypeEntities = [], usedContentTypeEntities = [], availableAudience = [], additionalFields = [], contentTypesNameFields = {}, onSubmit, onCancel, getContentTypeEntities, usedContentTypesData, appendLabelPublicationStatus = appendLabelPublicationStatusFallback, locale, readNavigationItemFromLocale, slugify, }) => {
47
+ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading, inputsPrefix, data, contentTypes = [], contentTypeEntities = [], usedContentTypeEntities = [], availableAudience = [], additionalFields = [], contentTypesNameFields = {}, onSubmit, onCancel, getContentTypeEntities, usedContentTypesData, appendLabelPublicationStatus = appendLabelPublicationStatusFallback, locale, readNavigationItemFromLocale, slugify, permissions = {}, }) => {
48
48
  const [isLoading, setIsLoading] = (0, react_1.useState)(isPreloading);
49
49
  const [hasBeenInitialized, setInitializedState] = (0, react_1.useState)(false);
50
50
  const [hasChanged, setChangedState] = (0, react_1.useState)(false);
51
51
  const [contentTypeSearchQuery, setContentTypeSearchQuery] = (0, react_1.useState)(undefined);
52
52
  const [contentTypeSearchInputValue, setContentTypeSearchInputValue] = (0, react_1.useState)(undefined);
53
+ const { canUpdate } = permissions;
53
54
  const formik = (0, formik_1.useFormik)({
54
55
  initialValues: formDefinition.defaultValues,
55
56
  onSubmit: loadingAware(async (payload) => onSubmit(await sanitizePayload(slugify, payload, data)), setIsLoading),
@@ -77,7 +78,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
77
78
  type: (0, lodash_1.get)(data, "type", formDefinition.defaultValues.type),
78
79
  related: (0, lodash_1.get)(data, "related.value", formDefinition.defaultValues.related),
79
80
  relatedType: (0, lodash_1.get)(data, "relatedType.value", formDefinition.defaultValues.relatedType),
80
- audience: (0, lodash_1.get)(data, "audience", formDefinition.defaultValues.audience).map((item) => (0, lodash_1.isObject)(item) ? item.id : item),
81
+ audience: (0, lodash_1.get)(data, "audience", formDefinition.defaultValues.audience).map((item) => (0, lodash_1.isObject)(item) ? item.id.toString() : item.toString()),
81
82
  additionalFields: (0, utils_1.getDefaultCustomFields)({
82
83
  additionalFields,
83
84
  customFieldsValues: (0, lodash_1.get)(data, "additionalFields", []),
@@ -109,15 +110,20 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
109
110
  return null;
110
111
  };
111
112
  const getDefaultTitle = (0, react_1.useCallback)((related, relatedType, isSingleSelected) => {
113
+ let selectedEntity;
112
114
  if (isSingleSelected) {
113
- return contentTypes.find(_ => _.uid === relatedType)?.label;
115
+ selectedEntity = contentTypeEntities.find(_ => (_.uid === relatedType) || (_.__collectionUid === relatedType));
116
+ if (!selectedEntity) {
117
+ return contentTypes.find(_ => _.uid === relatedType)?.label;
118
+ }
114
119
  }
115
120
  else {
116
- return (0, parsers_1.extractRelatedItemLabel)({
121
+ selectedEntity = {
117
122
  ...contentTypeEntities.find(_ => _.id === related),
118
123
  __collectionUid: relatedType
119
- }, contentTypesNameFields, { contentTypes });
124
+ };
120
125
  }
126
+ return (0, parsers_1.extractRelatedItemLabel)(selectedEntity, contentTypesNameFields, { contentTypes });
121
127
  }, [contentTypeEntities, contentTypesNameFields, contentTypes]);
122
128
  const sanitizePayload = async (slugify, payload, data) => {
123
129
  const { related, relatedType, menuAttached, type, ...purePayload } = payload;
@@ -164,7 +170,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
164
170
  if ((0, lodash_1.isEmpty)(formik.values.path) && !(0, lodash_1.isEmpty)(pathDefaultFields)) {
165
171
  const selectedEntity = isSingleSelected
166
172
  ? (0, lodash_1.first)(contentTypeEntities)
167
- : contentTypeEntities.find(i => i.id === relatedSelectValue);
173
+ : contentTypeEntities.find(i => String(i.id) === relatedSelectValue);
168
174
  const pathDefaultValues = pathDefaultFields
169
175
  .map((field) => (0, lodash_1.get)(selectedEntity, field, ""))
170
176
  .filter(value => !(0, lodash_1.isNil)(value) && String(value).match(/^\S+$/));
@@ -189,7 +195,7 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
189
195
  }
190
196
  else if (related) {
191
197
  const relationTitle = (0, parsers_1.extractRelatedItemLabel)({
192
- ...contentTypeEntities.find(_ => _.id === related),
198
+ ...contentTypeEntities.find(_ => String(_.id) === String(related)),
193
199
  __collectionUid: relatedType
194
200
  }, contentTypesNameFields, { contentTypes });
195
201
  return (0, lodash_1.isString)(relationTitle) && !(0, lodash_1.isEmpty)(relationTitle) ? await slugify(relationTitle).then((0, fp_1.prop)("slug")) : undefined;
@@ -380,20 +386,20 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
380
386
  react_1.default.createElement(ModalLayout_1.ModalBody, null,
381
387
  react_1.default.createElement(Grid_1.Grid, { gap: 5 },
382
388
  react_1.default.createElement(Grid_1.GridItem, { key: "title", col: 12 },
383
- react_1.default.createElement(helper_plugin_1.GenericInput, { autoFocused: true, intlLabel: (0, translations_1.getTrad)('popup.item.form.title.label', 'Title'), name: "title", placeholder: (0, translations_1.getTrad)("e.g. Blog", 'e.g. Blog'), description: (0, translations_1.getTrad)('popup.item.form.title.placeholder', 'e.g. Blog'), type: "text", error: formik.errors.title, onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values.title })),
389
+ react_1.default.createElement(helper_plugin_1.GenericInput, { autoFocused: true, intlLabel: (0, translations_1.getTrad)('popup.item.form.title.label', 'Title'), name: "title", placeholder: (0, translations_1.getTrad)("e.g. Blog", 'e.g. Blog'), description: (0, translations_1.getTrad)('popup.item.form.title.placeholder', 'e.g. Blog'), type: "text", disabled: !canUpdate, error: formik.errors.title, onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values.title })),
384
390
  react_1.default.createElement(Grid_1.GridItem, { key: "type", col: 4, lg: 12 },
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 })),
391
+ 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", disabled: !canUpdate, error: formik.errors.type, onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values.type })),
386
392
  react_1.default.createElement(Grid_1.GridItem, { key: "menuAttached", col: 4, lg: 12 },
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 })),
393
+ 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: !canUpdate || (config.cascadeMenuAttached ? !(data.isMenuAllowedLevel && data.parentAttachedToMenu) : false) })),
388
394
  react_1.default.createElement(Grid_1.GridItem, { key: "path", col: 12 },
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() })),
395
+ 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", disabled: !canUpdate, error: formik.errors[pathSourceName], onChange: ({ target: { name, value } }) => onChange({ name, value }), value: formik.values[pathSourceName], description: generatePreviewPath() })),
390
396
  formik.values.type === utils_1.navigationItemType.INTERNAL && (react_1.default.createElement(react_1.default.Fragment, null,
391
397
  react_1.default.createElement(Grid_1.GridItem, { col: 6, lg: 12 },
392
- react_1.default.createElement(helper_plugin_1.GenericInput, { type: "select", intlLabel: (0, translations_1.getTrad)('popup.item.form.relatedType.label', 'Related Type'), placeholder: (0, translations_1.getTrad)('popup.item.form.relatedType.placeholder', 'Related Type'), name: "relatedType", error: formik.errors.relatedType, onChange: onChangeRelatedType, options: relatedTypeSelectOptions, value: formik.values.relatedType, disabled: isLoading || (0, lodash_1.isEmpty)(relatedTypeSelectOptions), description: !isLoading && (0, lodash_1.isEmpty)(relatedTypeSelectOptions)
398
+ react_1.default.createElement(helper_plugin_1.GenericInput, { type: "select", intlLabel: (0, translations_1.getTrad)('popup.item.form.relatedType.label', 'Related Type'), placeholder: (0, translations_1.getTrad)('popup.item.form.relatedType.placeholder', 'Related Type'), name: "relatedType", error: formik.errors.relatedType, onChange: onChangeRelatedType, options: relatedTypeSelectOptions, value: formik.values.relatedType, disabled: isLoading || (0, lodash_1.isEmpty)(relatedTypeSelectOptions) || !canUpdate, description: !isLoading && (0, lodash_1.isEmpty)(relatedTypeSelectOptions)
393
399
  ? (0, translations_1.getTrad)('popup.item.form.relatedType.empty', 'There are no more content types')
394
400
  : undefined })),
395
401
  formik.values.relatedType && !isSingleSelected && (react_1.default.createElement(Grid_1.GridItem, { col: 6, lg: 12 },
396
- react_1.default.createElement(helper_plugin_1.GenericInput, { type: "select", intlLabel: (0, translations_1.getTrad)('popup.item.form.related.label', 'Related'), placeholder: (0, translations_1.getTrad)('popup.item.form.related.label', 'Related'), name: "related", error: formik.errors.related, onChange: ({ target: { name, value } }) => onChange({ name, value }), onInputChange: debounceContentTypeSearchQuery, inputValue: contentTypeSearchInputValue, options: relatedSelectOptions, value: formik.values.related, disabled: isLoading || thereAreNoMoreContentTypes, description: !isLoading && thereAreNoMoreContentTypes
402
+ react_1.default.createElement(helper_plugin_1.GenericInput, { type: "select", intlLabel: (0, translations_1.getTrad)('popup.item.form.related.label', 'Related'), placeholder: (0, translations_1.getTrad)('popup.item.form.related.label', 'Related'), name: "related", error: formik.errors.related, onChange: ({ target: { name, value } }) => onChange({ name, value }), onInputChange: debounceContentTypeSearchQuery, inputValue: contentTypeSearchInputValue, options: relatedSelectOptions, value: formik.values.related, disabled: isLoading || thereAreNoMoreContentTypes || !canUpdate, description: !isLoading && thereAreNoMoreContentTypes
397
403
  ? {
398
404
  id: (0, translations_1.getTradId)('popup.item.form.related.empty'),
399
405
  defaultMessage: 'There are no more entities',
@@ -405,19 +411,19 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
405
411
  return (react_1.default.createElement(Grid_1.GridItem, { key: "audience", col: 6, lg: 12 },
406
412
  react_1.default.createElement(Select_1.Select, { id: "audience", placeholder: (0, utils_2.getMessage)('popup.item.form.audience.placeholder'), label: (0, utils_2.getMessage)('popup.item.form.audience.label'), onChange: onAudienceChange, value: formik.values.audience, hint: !isLoading && (0, lodash_1.isEmpty)(audienceOptions)
407
413
  ? (0, utils_2.getMessage)('popup.item.form.audience.empty', 'There are no more audiences')
408
- : undefined, multi: true, withTags: true, disabled: (0, lodash_1.isEmpty)(audienceOptions) }, audienceOptions.map(({ value, label }) => react_1.default.createElement(Select_1.Option, { key: value, value: value }, label)))));
414
+ : undefined, multi: true, withTags: true, disabled: (0, lodash_1.isEmpty)(audienceOptions) || !canUpdate }, audienceOptions.map(({ value, label }) => react_1.default.createElement(Select_1.Option, { key: value, value: value }, label)))));
409
415
  }
410
416
  else {
411
417
  return (react_1.default.createElement(Grid_1.GridItem, { key: additionalField.name, col: 6, lg: 12 },
412
- react_1.default.createElement(AdditionalFieldInput_1.default, { field: additionalField, isLoading: isLoading, onChange: onAdditionalFieldChange, value: (0, lodash_1.get)(formik.values, `additionalFields.${additionalField.name}`, null), error: (0, lodash_1.get)(formik.errors, `additionalFields.${additionalField.name}`, null) })));
418
+ react_1.default.createElement(AdditionalFieldInput_1.default, { field: additionalField, isLoading: isLoading, onChange: onAdditionalFieldChange, value: (0, lodash_1.get)(formik.values, `additionalFields.${additionalField.name}`, null), disabled: !canUpdate, error: (0, lodash_1.get)(formik.errors, `additionalFields.${additionalField.name}`, null) })));
413
419
  }
414
420
  })),
415
421
  isI18nBootstrapAvailable ? (react_1.default.createElement(Grid_1.Grid, { gap: 5, paddingTop: 5 },
416
422
  react_1.default.createElement(Grid_1.GridItem, { col: 6, lg: 12 },
417
- react_1.default.createElement(helper_plugin_1.GenericInput, { ...itemCopyProps, type: "select", name: itemLocaleCopyField, error: (0, lodash_1.get)(formik.errors, itemLocaleCopyField), onChange: onChangeLocaleCopy, options: availableLocaleOptions, value: itemLocaleCopyValue, disabled: isLoading })),
418
- react_1.default.createElement(Grid_1.GridItem, { col: 6, lg: 12, paddingTop: 6 },
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)),
420
- react_1.default.createElement(NavigationItemPopupFooter_1.NavigationItemPopupFooter, { handleSubmit: formik.handleSubmit, handleCancel: onCancel, submitDisabled: submitDisabled })));
423
+ react_1.default.createElement(helper_plugin_1.GenericInput, { ...itemCopyProps, type: "select", name: itemLocaleCopyField, error: (0, lodash_1.get)(formik.errors, itemLocaleCopyField), onChange: onChangeLocaleCopy, options: availableLocaleOptions, value: itemLocaleCopyValue, disabled: isLoading || !canUpdate })),
424
+ canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 6, lg: 12, paddingTop: 6 },
425
+ 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)),
426
+ react_1.default.createElement(NavigationItemPopupFooter_1.NavigationItemPopupFooter, { handleSubmit: formik.handleSubmit, handleCancel: onCancel, submitDisabled: submitDisabled, canUpdate: canUpdate })));
421
427
  };
422
428
  const appendLabelPublicationStatusFallback = () => "";
423
429
  const loadingAware = (action, isLoading) => async (input) => {
@@ -1,16 +1,16 @@
1
- import { Audience, Effect, ContentTypeEntity, NavigationItemAdditionalField, NavigationItemAdditionalFieldValues, NavigationItemType, NavigationPluginConfig, PluginConfigNameFields, ToBeFixed, VoidEffect } from '../../../../../../types';
1
+ import { Audience, Effect, ContentTypeEntity, NavigationItemAdditionalField, NavigationItemAdditionalFieldValues, NavigationItemType, NavigationPluginConfig, PluginConfigNameFields, PluginPermissions, ToBeFixed, VoidEffect } from '../../../../../../types';
2
2
  import { Id } from 'strapi-typed';
3
3
  import { StrapiContentTypeSchema } from '../../../SettingsPage/types';
4
- export declare type FormEventTarget<TValue = unknown> = {
4
+ export type FormEventTarget<TValue = unknown> = {
5
5
  name: string;
6
6
  value: TValue;
7
7
  };
8
- declare type GetContentTypeEntitiesPayload = {
8
+ type GetContentTypeEntitiesPayload = {
9
9
  modelUID: string;
10
10
  query: ContentTypeSearchQuery;
11
11
  locale: ToBeFixed;
12
12
  };
13
- export declare type NavigationItemFormData = {
13
+ export type NavigationItemFormData = {
14
14
  isMenuAllowedLevel: boolean;
15
15
  levelPath: string;
16
16
  parentAttachedToMenu: boolean;
@@ -41,7 +41,7 @@ export declare type NavigationItemFormData = {
41
41
  relatedRef?: ToBeFixed;
42
42
  structureId: ToBeFixed;
43
43
  };
44
- export declare type NavigationItemFormProps = {
44
+ export type NavigationItemFormProps = {
45
45
  additionalFields: NavigationItemAdditionalField[];
46
46
  appendLabelPublicationStatus: (label: string, entity: ContentTypeEntity) => string;
47
47
  availableAudience: string[];
@@ -63,9 +63,10 @@ export declare type NavigationItemFormProps = {
63
63
  slugify: (q: string) => Promise<{
64
64
  slug: string;
65
65
  }>;
66
+ permissions: PluginPermissions;
66
67
  };
67
- export declare type ContentTypeSearchQuery = ToBeFixed;
68
- export declare type RawFormPayload = {
68
+ export type ContentTypeSearchQuery = ToBeFixed;
69
+ export type RawFormPayload = {
69
70
  type: NavigationItemType;
70
71
  related?: string;
71
72
  relatedType?: string;
@@ -77,7 +78,7 @@ export declare type RawFormPayload = {
77
78
  additionalFields: NavigationItemAdditionalFieldValues;
78
79
  updated: boolean;
79
80
  };
80
- export declare type SanitizedFormPayload = {
81
+ export type SanitizedFormPayload = {
81
82
  title: string;
82
83
  type: NavigationItemType;
83
84
  menuAttached: boolean;
@@ -89,7 +90,7 @@ export declare type SanitizedFormPayload = {
89
90
  singleRelatedItem: ContentTypeEntity | undefined;
90
91
  uiRouterKey: string | undefined;
91
92
  };
92
- export declare type Slugify = (q: string) => Promise<{
93
+ export type Slugify = (q: string) => Promise<{
93
94
  slug: string;
94
95
  }>;
95
96
  export {};
@@ -2,21 +2,21 @@ import * as yup from "yup";
2
2
  import { NavigationItemAdditionalField } from "../../../../../../../types";
3
3
  import { RawFormPayload } from "../types";
4
4
  export declare const schemaFactory: (isSingleSelected: boolean, additionalFields: NavigationItemAdditionalField[]) => import("yup/lib/object").OptionalObjectSchema<{
5
- title: yup.StringSchema<string | undefined, Record<string, any>, string | undefined>;
5
+ title: yup.default<string | undefined, Record<string, any>, string | undefined>;
6
6
  uiRouterKey: import("yup/lib/string").RequiredStringSchema<string | undefined, Record<string, any>>;
7
7
  type: import("yup/lib/string").RequiredStringSchema<string | undefined, Record<string, any>>;
8
- path: yup.StringSchema<string | undefined, Record<string, any>, string | undefined>;
9
- externalPath: yup.StringSchema<string | undefined, Record<string, any>, string | undefined>;
8
+ path: yup.default<string | undefined, Record<string, any>, string | undefined>;
9
+ externalPath: yup.default<string | undefined, Record<string, any>, string | undefined>;
10
10
  menuAttached: yup.BooleanSchema<boolean | undefined, Record<string, any>, boolean | undefined>;
11
11
  relatedType: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
12
12
  related: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
13
13
  additionalFields: import("yup/lib/object").OptionalObjectSchema<{}, Record<string, any>, import("yup/lib/object").TypeOfShape<{}>>;
14
14
  }, Record<string, any>, import("yup/lib/object").TypeOfShape<{
15
- title: yup.StringSchema<string | undefined, Record<string, any>, string | undefined>;
15
+ title: yup.default<string | undefined, Record<string, any>, string | undefined>;
16
16
  uiRouterKey: import("yup/lib/string").RequiredStringSchema<string | undefined, Record<string, any>>;
17
17
  type: import("yup/lib/string").RequiredStringSchema<string | undefined, Record<string, any>>;
18
- path: yup.StringSchema<string | undefined, Record<string, any>, string | undefined>;
19
- externalPath: yup.StringSchema<string | undefined, Record<string, any>, string | undefined>;
18
+ path: yup.default<string | undefined, Record<string, any>, string | undefined>;
19
+ externalPath: yup.default<string | undefined, Record<string, any>, string | undefined>;
20
20
  menuAttached: yup.BooleanSchema<boolean | undefined, Record<string, any>, boolean | undefined>;
21
21
  relatedType: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
22
22
  related: import("yup/lib/mixed").MixedSchema<any, Record<string, any>, any>;
@@ -1,23 +1,25 @@
1
- export function NavigationItemPopupFooter({ handleCancel, handleSubmit, submitDisabled, formViewId }: {
1
+ export function NavigationItemPopupFooter({ handleCancel, handleSubmit, submitDisabled, formViewId, canUpdate }: {
2
2
  handleCancel: any;
3
3
  handleSubmit: any;
4
4
  submitDisabled: any;
5
5
  formViewId: any;
6
- }): JSX.Element;
6
+ canUpdate: any;
7
+ }): JSX.Element | null;
7
8
  export namespace NavigationItemPopupFooter {
8
9
  namespace defaultProps {
9
- const onValidate: undefined;
10
- const submitDisabled: boolean;
11
- const formViewId: undefined;
10
+ let onValidate: undefined;
11
+ let submitDisabled: boolean;
12
+ let formViewId: undefined;
12
13
  }
13
14
  namespace propTypes {
14
- export const handleCancel: PropTypes.Validator<(...args: any[]) => any>;
15
- export const handleSubmit: PropTypes.Requireable<(...args: any[]) => any>;
16
- const submitDisabled_1: PropTypes.Requireable<boolean>;
15
+ export let handleCancel: PropTypes.Validator<(...args: any[]) => any>;
16
+ export let handleSubmit: PropTypes.Requireable<(...args: any[]) => any>;
17
+ let submitDisabled_1: PropTypes.Requireable<boolean>;
17
18
  export { submitDisabled_1 as submitDisabled };
18
- const formViewId_1: PropTypes.Requireable<object>;
19
+ let formViewId_1: PropTypes.Requireable<object>;
19
20
  export { formViewId_1 as formViewId };
21
+ export let canUpdate: PropTypes.Requireable<boolean>;
20
22
  }
21
23
  }
22
- import PropTypes from "prop-types";
24
+ import PropTypes from 'prop-types';
23
25
  //# sourceMappingURL=NavigationItemPopupFooter.d.ts.map
@@ -9,7 +9,10 @@ const prop_types_1 = __importDefault(require("prop-types"));
9
9
  const Button_1 = require("@strapi/design-system/Button");
10
10
  const ModalLayout_1 = require("@strapi/design-system/ModalLayout");
11
11
  const utils_1 = require("../../../../utils");
12
- const NavigationItemPopupFooter = ({ handleCancel, handleSubmit, submitDisabled, formViewId }) => {
12
+ const NavigationItemPopupFooter = ({ handleCancel, handleSubmit, submitDisabled, formViewId, canUpdate }) => {
13
+ if (!canUpdate) {
14
+ return null;
15
+ }
13
16
  return (react_1.default.createElement(ModalLayout_1.ModalFooter, { startActions: react_1.default.createElement(Button_1.Button, { onClick: handleCancel, variant: "tertiary" }, (0, utils_1.getMessage)('popup.item.form.button.cancel')), endActions: react_1.default.createElement(Button_1.Button, { onClick: handleSubmit, disabled: submitDisabled }, (0, utils_1.getMessage)(`popup.item.form.button.save`)) }));
14
17
  };
15
18
  exports.NavigationItemPopupFooter = NavigationItemPopupFooter;
@@ -23,5 +26,6 @@ exports.NavigationItemPopupFooter.propTypes = {
23
26
  handleSubmit: prop_types_1.default.func,
24
27
  submitDisabled: prop_types_1.default.bool,
25
28
  formViewId: prop_types_1.default.object,
29
+ canUpdate: prop_types_1.default.bool,
26
30
  };
27
31
  //# sourceMappingURL=NavigationItemPopupFooter.js.map
@@ -1,4 +1,5 @@
1
- export function NavigationItemPopupHeader({ isNewItem }: {
1
+ export function NavigationItemPopupHeader({ isNewItem, canUpdate }: {
2
2
  isNewItem: any;
3
+ canUpdate: any;
3
4
  }): JSX.Element;
4
5
  //# sourceMappingURL=NavigationItemPopupHeader.d.ts.map
@@ -8,9 +8,13 @@ const react_1 = __importDefault(require("react"));
8
8
  const Typography_1 = require("@strapi/design-system/Typography");
9
9
  const ModalLayout_1 = require("@strapi/design-system/ModalLayout");
10
10
  const utils_1 = require("../../../../utils");
11
- const NavigationItemPopupHeader = ({ isNewItem }) => {
11
+ const NavigationItemPopupHeader = ({ isNewItem, canUpdate }) => {
12
+ let modalType = 'view';
13
+ if (canUpdate) {
14
+ modalType = isNewItem ? 'new' : 'edit';
15
+ }
12
16
  return (react_1.default.createElement(ModalLayout_1.ModalHeader, null,
13
- react_1.default.createElement(Typography_1.Typography, { variant: "omega", fontWeight: "bold", textColor: "neutral800", as: "h2", id: "asset-dialog-title" }, (0, utils_1.getMessage)(`popup.item.header.${isNewItem ? 'new' : 'edit'}`))));
17
+ react_1.default.createElement(Typography_1.Typography, { variant: "omega", fontWeight: "bold", textColor: "neutral800", as: "h2", id: "asset-dialog-title" }, (0, utils_1.getMessage)(`popup.item.header.${modalType}`))));
14
18
  };
15
19
  exports.NavigationItemPopupHeader = NavigationItemPopupHeader;
16
20
  //# sourceMappingURL=NavigationItemPopupHeader.js.map