strapi-plugin-navigation 2.2.4 → 2.2.5

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 (45) hide show
  1. package/README.md +5 -1
  2. package/admin/src/components/AdditionalFieldInput/index.js +2 -2
  3. package/admin/src/components/AdditionalFieldInput/types.d.ts +1 -0
  4. package/admin/src/components/Item/ItemCardHeader/icons.d.ts +1 -1
  5. package/admin/src/components/Item/ItemCardHeader/icons.js +2 -1
  6. package/admin/src/components/Item/ItemCardHeader/index.d.ts +1 -0
  7. package/admin/src/components/Item/ItemCardHeader/index.js +6 -6
  8. package/admin/src/components/Item/index.js +7 -6
  9. package/admin/src/components/NavigationItemList/index.d.ts +2 -1
  10. package/admin/src/components/NavigationItemList/index.js +2 -2
  11. package/admin/src/hooks/useNavigationManager.d.ts +0 -1
  12. package/admin/src/index.js +1 -1
  13. package/admin/src/pages/DataManagerProvider/reducer.d.ts +1 -1
  14. package/admin/src/pages/NoAccessPage/index.d.ts +3 -0
  15. package/admin/src/pages/NoAccessPage/index.js +31 -0
  16. package/admin/src/pages/SettingsPage/index.d.ts +0 -1
  17. package/admin/src/pages/SettingsPage/index.js +9 -0
  18. package/admin/src/pages/View/components/NavigationHeader/index.d.ts +2 -1
  19. package/admin/src/pages/View/components/NavigationHeader/index.js +9 -8
  20. package/admin/src/pages/View/components/NavigationItemForm/index.js +14 -13
  21. package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +2 -1
  22. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.d.ts +4 -2
  23. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +5 -1
  24. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.d.ts +2 -1
  25. package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +6 -2
  26. package/admin/src/pages/View/components/NavigationItemPopup/index.d.ts +2 -1
  27. package/admin/src/pages/View/components/NavigationItemPopup/index.js +4 -3
  28. package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.d.ts +0 -1
  29. package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.d.ts +0 -1
  30. package/admin/src/pages/View/components/NavigationManager/DeletionConfirm/index.d.ts +0 -1
  31. package/admin/src/pages/View/components/NavigationManager/ErrorDetails/index.d.ts +0 -1
  32. package/admin/src/pages/View/components/NavigationManager/Form/index.d.ts +0 -1
  33. package/admin/src/pages/View/components/NavigationManager/NavigationUpdate/index.d.ts +0 -1
  34. package/admin/src/pages/View/components/NavigationManager/NewNavigation/index.d.ts +0 -1
  35. package/admin/src/pages/View/components/NavigationManager/index.d.ts +0 -1
  36. package/admin/src/pages/View/index.js +39 -19
  37. package/admin/src/permissions.d.ts +4 -0
  38. package/admin/src/permissions.js +1 -0
  39. package/admin/src/translations/en.json +8 -0
  40. package/package.json +2 -2
  41. package/permissions.d.ts +1 -0
  42. package/permissions.js +1 -0
  43. package/server/bootstrap/index.js +6 -0
  44. package/tsconfig.tsbuildinfo +1 -1
  45. package/types/utils.d.ts +5 -0
package/README.md CHANGED
@@ -118,7 +118,7 @@ Complete installation requirements are exact same as for Strapi itself and can b
118
118
 
119
119
  **Supported Strapi versions**:
120
120
 
121
- - Strapi v4.6.0 (recently tested)
121
+ - Strapi v4.9.0 (recently tested)
122
122
  - Strapi v4.x
123
123
 
124
124
  > This plugin is designed for **Strapi v4** and is not working with v3.x. To get version for **Strapi v3** install version [v1.x](https://github.com/VirtusLab-Open-Source/strapi-plugin-navigation/tree/strapi-v3).
@@ -163,6 +163,9 @@ Config for this plugin is stored as a part of the `config/plugins.js` or `config
163
163
  contentTypesNameFields: {
164
164
  'api::page.page': ['title']
165
165
  },
166
+ pathDefaultFields: {
167
+ 'api::page.page': ['slug']
168
+ },
166
169
  allowedLevels: 2,
167
170
  gql: {...},
168
171
  }
@@ -175,6 +178,7 @@ Config for this plugin is stored as a part of the `config/plugins.js` or `config
175
178
  - `allowedLevels` - Maximum level for which you're able to mark item as "Menu attached"
176
179
  - `contentTypes` - UIDs of related content types
177
180
  - `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`
181
+ - `pathDefaultFields` - The attribute to copy the default path from per content type. Syntax: `'api::<collection name>.<content type name>': ['url_slug', 'path']`
178
182
  - `gql` - If you're using GraphQL that's the right place to put all necessary settings. More **[ here ](#gql-configuration)**
179
183
  - `i18nEnabled` - should you want to manage multi-locale content via navigation set this value `Enabled`. More **[ here ](#i18n-internationalization)**
180
184
  - `cascadeMenuAttached` - If you don't want "Menu attached" to cascade on child items set this value `Disabled`.
@@ -36,14 +36,14 @@ const DEFAULT_STRING_VALUE = "";
36
36
  const handlerFactory = ({ field, prop, onChange }) => ({ target }) => {
37
37
  onChange(field.name, target[prop]);
38
38
  };
39
- const AdditionalFieldInput = ({ field, isLoading, onChange, value, error }) => {
39
+ const AdditionalFieldInput = ({ field, isLoading, onChange, value, disabled, error }) => {
40
40
  const toggleNotification = (0, helper_plugin_1.useNotification)();
41
41
  const { formatMessage } = (0, react_intl_1.useIntl)();
42
42
  const defaultInputProps = (0, react_1.useMemo)(() => ({
43
43
  id: field.name,
44
44
  name: field.name,
45
45
  label: field.label,
46
- disabled: isLoading,
46
+ disabled: isLoading || disabled,
47
47
  error: error && formatMessage(error),
48
48
  }), [field, isLoading, error]);
49
49
  const handleBoolean = (0, react_1.useMemo)(() => handlerFactory({ field, onChange, prop: "checked" }), [onChange, field]);
@@ -5,6 +5,7 @@ export declare type AdditionalFieldInputProps = {
5
5
  isLoading: boolean;
6
6
  onChange: (name: string, value: string) => void;
7
7
  value: string | boolean | string[] | null;
8
+ disabled: boolean;
8
9
  error: MessageDescriptor | null;
9
10
  };
10
11
  export declare type TargetProp = "value" | "checked";
@@ -1,5 +1,5 @@
1
- /// <reference types="react" />
2
1
  export declare const pencilIcon: JSX.Element;
3
2
  export declare const refreshIcon: JSX.Element;
4
3
  export declare const trashIcon: JSX.Element;
4
+ export declare const eyeIcon: JSX.Element;
5
5
  //# sourceMappingURL=icons.d.ts.map
@@ -3,10 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.trashIcon = exports.refreshIcon = exports.pencilIcon = void 0;
6
+ exports.eyeIcon = exports.trashIcon = exports.refreshIcon = exports.pencilIcon = void 0;
7
7
  const react_1 = __importDefault(require("react"));
8
8
  const icons_1 = require("@strapi/icons");
9
9
  exports.pencilIcon = react_1.default.createElement(icons_1.Pencil, null);
10
10
  exports.refreshIcon = react_1.default.createElement(icons_1.Refresh, null);
11
11
  exports.trashIcon = react_1.default.createElement(icons_1.Trash, null);
12
+ exports.eyeIcon = react_1.default.createElement(icons_1.Eye, null);
12
13
  //# sourceMappingURL=icons.js.map
@@ -5,6 +5,7 @@ interface IProps {
5
5
  path: string;
6
6
  icon: ToBeFixed;
7
7
  removed: boolean;
8
+ canUpdate: boolean;
8
9
  onItemRemove: VoidEffect;
9
10
  onItemEdit: VoidEffect;
10
11
  onItemRestore: VoidEffect;
@@ -15,9 +15,9 @@ const utils_1 = require("../../../utils");
15
15
  const icons_1 = require("./icons");
16
16
  const wrapperStyle = { zIndex: 2 };
17
17
  const pathWrapperStyle = { maxWidth: "425px" };
18
- const ItemCardHeader = ({ title, path, icon, removed, onItemRemove, onItemEdit, onItemRestore, dragRef }) => (react_1.default.createElement(Wrapper_1.default, null,
18
+ const ItemCardHeader = ({ title, path, icon, removed, canUpdate, onItemRemove, onItemEdit, onItemRestore, dragRef }) => (react_1.default.createElement(Wrapper_1.default, null,
19
19
  react_1.default.createElement(Flex_1.Flex, { alignItems: "center" },
20
- react_1.default.createElement(DragButton_1.default, { ref: dragRef }),
20
+ canUpdate && (react_1.default.createElement(DragButton_1.default, { ref: dragRef })),
21
21
  react_1.default.createElement(Typography_1.Typography, { variant: "omega", fontWeight: "bold" }, title),
22
22
  react_1.default.createElement(Typography_1.Typography, { variant: "omega", fontWeight: "bold", textColor: 'neutral500', ellipsis: true, style: pathWrapperStyle }, path),
23
23
  react_1.default.createElement(Flex_1.Flex, null,
@@ -25,9 +25,9 @@ const ItemCardHeader = ({ title, path, icon, removed, onItemRemove, onItemEdit,
25
25
  react_1.default.createElement(Flex_1.Flex, { alignItems: "center", style: wrapperStyle },
26
26
  removed &&
27
27
  (react_1.default.createElement(ItemCardBadge_1.default, { borderColor: "danger200", backgroundColor: "danger100", textColor: "danger600" }, (0, utils_1.getMessage)("components.navigationItem.badge.removed"))),
28
- react_1.default.createElement(IconButton_1.IconButton, { disabled: removed, onClick: onItemEdit, label: "Edit", icon: icons_1.pencilIcon }),
29
- removed ?
30
- react_1.default.createElement(IconButton_1.IconButton, { onClick: onItemRestore, label: "Restore", icon: icons_1.refreshIcon }) :
31
- react_1.default.createElement(IconButton_1.IconButton, { onClick: onItemRemove, label: "Remove", icon: icons_1.trashIcon }))));
28
+ react_1.default.createElement(IconButton_1.IconButton, { disabled: removed, onClick: onItemEdit, label: (0, utils_1.getMessage)(`components.navigationItem.action.${canUpdate ? 'edit' : 'view'}`, canUpdate ? 'Edit' : 'View'), icon: canUpdate ? icons_1.pencilIcon : icons_1.eyeIcon }),
29
+ canUpdate && (react_1.default.createElement(react_1.default.Fragment, null, removed ?
30
+ react_1.default.createElement(IconButton_1.IconButton, { onClick: onItemRestore, label: (0, utils_1.getMessage)('components.navigationItem.action.restore', "Restore"), icon: icons_1.refreshIcon }) :
31
+ react_1.default.createElement(IconButton_1.IconButton, { onClick: onItemRemove, label: (0, utils_1.getMessage)('components.navigationItem.action.remove', "Remove"), icon: icons_1.trashIcon }))))));
32
32
  exports.default = ItemCardHeader;
33
33
  //# sourceMappingURL=index.js.map
@@ -46,7 +46,7 @@ const ItemCardRemovedOverlay_1 = require("./ItemCardRemovedOverlay");
46
46
  const utils_1 = require("../../utils");
47
47
  const CollapseButton_1 = __importDefault(require("../CollapseButton"));
48
48
  const Item = (props) => {
49
- const { item, isLast = false, level = 0, levelPath = '', allowedLevels, relatedRef, isParentAttachedToMenu, onItemLevelAdd, onItemRemove, onItemRestore, onItemEdit, onItemReOrder, onItemToggleCollapse, error, displayChildren, config = {}, } = props;
49
+ const { item, isLast = false, level = 0, levelPath = '', allowedLevels, relatedRef, isParentAttachedToMenu, onItemLevelAdd, onItemRemove, onItemRestore, onItemEdit, onItemReOrder, onItemToggleCollapse, error, displayChildren, config = {}, permissions = {}, } = props;
50
50
  const { viewId, title, type, path, removed, externalPath, menuAttached, collapsed, structureId, items = [], } = item;
51
51
  const { contentTypes = [], contentTypesNameFields } = config;
52
52
  const isExternal = type === utils_1.navigationItemType.EXTERNAL;
@@ -60,6 +60,7 @@ const Item = (props) => {
60
60
  const relatedItemLabel = !isExternal ? (0, parsers_1.extractRelatedItemLabel)(relatedRef, contentTypesNameFields, { contentTypes }) : '';
61
61
  const relatedTypeLabel = relatedRef?.labelSingular;
62
62
  const relatedBadgeColor = isPublished ? 'success' : 'secondary';
63
+ const { canUpdate } = permissions;
63
64
  const dragRef = (0, react_1.useRef)(null);
64
65
  const dropRef = (0, react_1.useRef)(null);
65
66
  const previewRef = (0, react_1.useRef)(null);
@@ -110,7 +111,7 @@ const Item = (props) => {
110
111
  const { isSingle } = contentType;
111
112
  return `/content-manager/${isSingle ? 'singleType' : 'collectionType'}/${entity?.__collectionUid}${!isSingle ? '/' + entity?.id : ''}`;
112
113
  };
113
- const onNewItemClick = (0, react_1.useCallback)((event) => onItemLevelAdd(event, viewId, isNextMenuAllowedLevel, absolutePath, menuAttached, `${structureId}.${items.length}`), [viewId, isNextMenuAllowedLevel, absolutePath, menuAttached, structureId, items]);
114
+ const onNewItemClick = (0, react_1.useCallback)((event) => canUpdate && onItemLevelAdd(event, viewId, isNextMenuAllowedLevel, absolutePath, menuAttached, `${structureId}.${items.length}`), [viewId, isNextMenuAllowedLevel, absolutePath, menuAttached, structureId, items, canUpdate]);
114
115
  return (react_1.default.createElement(Wrapper_1.default, { level: level, isLast: isLast, style: { opacity: isDragging ? 0.2 : 1 }, ref: refs ? refs.dropRef : null },
115
116
  react_1.default.createElement(Card_1.Card, { style: { width: "728px", zIndex: 1, position: "relative", overflow: 'hidden' } },
116
117
  removed && (react_1.default.createElement(ItemCardRemovedOverlay_1.ItemCardRemovedOverlay, null)),
@@ -120,14 +121,14 @@ const Item = (props) => {
120
121
  ...item,
121
122
  isMenuAllowedLevel,
122
123
  isParentAttachedToMenu,
123
- }, levelPath, isParentAttachedToMenu), onItemRestore: () => onItemRestore(item), dragRef: refs.dragRef, removed: removed })),
124
+ }, levelPath, isParentAttachedToMenu), onItemRestore: () => onItemRestore(item), dragRef: refs.dragRef, removed: removed, canUpdate: canUpdate })),
124
125
  react_1.default.createElement(Divider_1.Divider, null),
125
126
  !isExternal && (react_1.default.createElement(Card_1.CardBody, { style: { padding: '8px' } },
126
127
  react_1.default.createElement(Flex_1.Flex, { style: { width: '100%' }, direction: "row", alignItems: "center", justifyContent: "space-between" },
127
128
  react_1.default.createElement(Flex_1.Flex, null,
128
129
  !(0, lodash_1.isEmpty)(item.items) && react_1.default.createElement(CollapseButton_1.default, { toggle: () => onItemToggleCollapse(item), collapsed: collapsed, itemsCount: item.items.length }),
129
- react_1.default.createElement(TextButton_1.TextButton, { disabled: removed, startIcon: react_1.default.createElement(icons_1.Plus, null), onClick: onNewItemClick },
130
- react_1.default.createElement(Typography_1.Typography, { variant: "pi", fontWeight: "bold", textColor: removed ? "neutral600" : "primary600" }, (0, utils_1.getMessage)("components.navigationItem.action.newItem")))),
130
+ canUpdate && (react_1.default.createElement(TextButton_1.TextButton, { disabled: removed, startIcon: react_1.default.createElement(icons_1.Plus, null), onClick: onNewItemClick },
131
+ react_1.default.createElement(Typography_1.Typography, { variant: "pi", fontWeight: "bold", textColor: removed ? "neutral600" : "primary600" }, (0, utils_1.getMessage)("components.navigationItem.action.newItem"))))),
131
132
  relatedItemLabel && (react_1.default.createElement(Flex_1.Flex, { justifyContent: 'center', alignItems: 'center' },
132
133
  isHandledByPublishFlow && (react_1.default.createElement(ItemCardBadge_1.default, { borderColor: `${relatedBadgeColor}200`, backgroundColor: `${relatedBadgeColor}100`, textColor: `${relatedBadgeColor}600`, className: "action", small: true }, (0, utils_1.getMessage)({ id: `components.navigationItem.badge.${isPublished ? 'published' : 'draft'}` }))),
133
134
  react_1.default.createElement(Typography_1.Typography, { variant: "omega", textColor: 'neutral600' },
@@ -135,7 +136,7 @@ const Item = (props) => {
135
136
  "\u00A0/\u00A0"),
136
137
  react_1.default.createElement(Typography_1.Typography, { variant: "omega", textColor: 'neutral800' }, relatedItemLabel),
137
138
  react_1.default.createElement(Link_1.Link, { to: `/content-manager/collectionType/${relatedRef?.__collectionUid}/${relatedRef?.id}`, endIcon: react_1.default.createElement(icons_1.ArrowRight, null) }, "\u00A0")))))))),
138
- hasChildren && !removed && !collapsed && react_1.default.createElement(NavigationItemList_1.default, { onItemLevelAdd: onItemLevelAdd, onItemRemove: onItemRemove, onItemEdit: onItemEdit, onItemRestore: onItemRestore, onItemReOrder: onItemReOrder, onItemToggleCollapse: onItemToggleCollapse, error: error, allowedLevels: allowedLevels, isParentAttachedToMenu: menuAttached, items: item.items, level: level + 1, levelPath: absolutePath, contentTypes: contentTypes, contentTypesNameFields: contentTypesNameFields })));
139
+ hasChildren && !removed && !collapsed && react_1.default.createElement(NavigationItemList_1.default, { onItemLevelAdd: onItemLevelAdd, onItemRemove: onItemRemove, onItemEdit: onItemEdit, onItemRestore: onItemRestore, onItemReOrder: onItemReOrder, onItemToggleCollapse: onItemToggleCollapse, error: error, allowedLevels: allowedLevels, isParentAttachedToMenu: menuAttached, items: item.items, level: level + 1, levelPath: absolutePath, contentTypes: contentTypes, contentTypesNameFields: contentTypesNameFields, permissions: permissions })));
139
140
  };
140
141
  Item.propTypes = {
141
142
  item: prop_types_1.default.shape({
@@ -1,5 +1,5 @@
1
1
  export default List;
2
- declare function List({ allowedLevels, error, isParentAttachedToMenu, items, level, levelPath, onItemEdit, onItemLevelAdd, onItemRemove, onItemRestore, onItemReOrder, onItemToggleCollapse, displayFlat, contentTypes, contentTypesNameFields, }: {
2
+ declare function List({ allowedLevels, error, isParentAttachedToMenu, items, level, levelPath, onItemEdit, onItemLevelAdd, onItemRemove, onItemRestore, onItemReOrder, onItemToggleCollapse, displayFlat, contentTypes, contentTypesNameFields, permissions, }: {
3
3
  allowedLevels: any;
4
4
  error: any;
5
5
  isParentAttachedToMenu?: boolean | undefined;
@@ -15,6 +15,7 @@ declare function List({ allowedLevels, error, isParentAttachedToMenu, items, lev
15
15
  displayFlat: any;
16
16
  contentTypes: any;
17
17
  contentTypesNameFields: any;
18
+ permissions: any;
18
19
  }): JSX.Element;
19
20
  declare namespace List {
20
21
  namespace propTypes {
@@ -7,12 +7,12 @@ const react_1 = __importDefault(require("react"));
7
7
  const prop_types_1 = __importDefault(require("prop-types"));
8
8
  const Item_1 = __importDefault(require("../Item"));
9
9
  const Wrapper_1 = __importDefault(require("./Wrapper"));
10
- const List = ({ allowedLevels, error, isParentAttachedToMenu = false, items, level = 0, levelPath = '', onItemEdit, onItemLevelAdd, onItemRemove, onItemRestore, onItemReOrder, onItemToggleCollapse, displayFlat, contentTypes, contentTypesNameFields, }) => (react_1.default.createElement(Wrapper_1.default, { level: level }, items.map((item, n) => {
10
+ const List = ({ allowedLevels, error, isParentAttachedToMenu = false, items, level = 0, levelPath = '', onItemEdit, onItemLevelAdd, onItemRemove, onItemRestore, onItemReOrder, onItemToggleCollapse, displayFlat, contentTypes, contentTypesNameFields, permissions, }) => (react_1.default.createElement(Wrapper_1.default, { level: level }, items.map((item, n) => {
11
11
  const { relatedRef, ...itemProps } = item;
12
12
  return (react_1.default.createElement(Item_1.default, { key: `list-item-${item.viewId || n}`, item: itemProps, isLast: n === items.length - 1, relatedRef: relatedRef, level: level, levelPath: levelPath, isParentAttachedToMenu: isParentAttachedToMenu, allowedLevels: allowedLevels, onItemRestore: onItemRestore, onItemLevelAdd: onItemLevelAdd, onItemRemove: onItemRemove, onItemEdit: onItemEdit, onItemReOrder: onItemReOrder, onItemToggleCollapse: onItemToggleCollapse, error: error, displayChildren: displayFlat, config: {
13
13
  contentTypes,
14
14
  contentTypesNameFields
15
- } }));
15
+ }, permissions: permissions }));
16
16
  })));
17
17
  List.propTypes = {
18
18
  allowedLevels: prop_types_1.default.number,
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  export declare const useNavigationManager: () => {
3
2
  navigationManagerModal: JSX.Element | null;
4
3
  openNavigationManagerModal: () => void;
@@ -50,7 +50,7 @@ exports.default = {
50
50
  const component = await Promise.resolve().then(() => __importStar(require('./pages/SettingsPage')));
51
51
  return component;
52
52
  },
53
- permissions: permissions_1.default.access,
53
+ permissions: permissions_1.default.settings,
54
54
  }
55
55
  ]);
56
56
  app.addMenuLink({
@@ -1,5 +1,5 @@
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
4
  const items: never[];
5
5
  const activeItem: undefined;
@@ -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: { 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 || [];
@@ -198,6 +204,9 @@ const SettingsPage = () => {
198
204
  const filteredFields = customFields.filter(f => f.name !== field.name);
199
205
  setCustomFields([...filteredFields, updatedField]);
200
206
  };
207
+ if (!(isLoadingForPermissions || canManageSettings)) {
208
+ return (react_1.default.createElement(NoAccessPage_1.default, null));
209
+ }
201
210
  return (react_1.default.createElement(react_1.default.Fragment, null,
202
211
  react_1.default.createElement(helper_plugin_1.SettingsPageTitle, { name: (0, utils_2.getMessage)('Settings.email.plugin.title', 'Configuration') }),
203
212
  react_1.default.createElement(Main_1.Main, { labelledBy: "title" },
@@ -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
@@ -46,7 +46,7 @@ const pickDefaultLocaleNavigation = ({ activeNavigation, config }) => config.i18
46
46
  : activeNavigation?.localizations.find(({ localeCode }) => localeCode === config.defaultLocale)
47
47
  : null
48
48
  : activeNavigation;
49
- const NavigationHeader = ({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, }) => {
49
+ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHasErrors, structureHasChanged, handleChangeSelection, handleLocalizationSelection, handleSave, config, permissions = {}, }) => {
50
50
  const { formatMessage } = (0, react_intl_1.useIntl)();
51
51
  const allLocaleVersions = (0, react_1.useMemo)(() => activeNavigation?.localizations.length && config.i18nEnabled
52
52
  ? (0, lodash_1.uniqBy)([activeNavigation, ...(activeNavigation.localizations ?? [])].sort((a, b) => a.localeCode.localeCompare(b.localeCode)), 'id')
@@ -54,21 +54,22 @@ const NavigationHeader = ({ activeNavigation, availableNavigations, structureHas
54
54
  const hasLocalizations = config.i18nEnabled && allLocaleVersions.length;
55
55
  const passedActiveNavigation = pickDefaultLocaleNavigation({ activeNavigation, config });
56
56
  const { closeNavigationManagerModal, openNavigationManagerModal, navigationManagerModal } = (0, useNavigationManager_1.useNavigationManager)();
57
+ const { canUpdate } = permissions;
57
58
  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" },
59
+ react_1.default.createElement(Box_1.Box, { marginRight: "8px" },
59
60
  react_1.default.createElement(Grid_1.Grid, { gap: 4 },
60
61
  !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 },
62
+ canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
63
+ 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'))))),
64
+ react_1.default.createElement(Grid_1.GridItem, { col: canUpdate ? 4 : 10 },
64
65
  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
66
  hasLocalizations
66
67
  ? react_1.default.createElement(Grid_1.GridItem, { col: 2 },
67
68
  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
69
  : 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({
70
+ canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 3 },
71
+ 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'))))))),
72
+ canUpdate && navigationManagerModal), title: formatMessage({
72
73
  id: (0, translations_1.getTrad)('header.title'),
73
74
  defaultMessage: 'UI Navigation',
74
75
  }), 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),
@@ -380,20 +381,20 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
380
381
  react_1.default.createElement(ModalLayout_1.ModalBody, null,
381
382
  react_1.default.createElement(Grid_1.Grid, { gap: 5 },
382
383
  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 })),
384
+ 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
385
  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 })),
386
+ 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
387
  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 })),
388
+ 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
389
  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() })),
390
+ 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
391
  formik.values.type === utils_1.navigationItemType.INTERNAL && (react_1.default.createElement(react_1.default.Fragment, null,
391
392
  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)
393
+ 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
394
  ? (0, translations_1.getTrad)('popup.item.form.relatedType.empty', 'There are no more content types')
394
395
  : undefined })),
395
396
  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
397
+ 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
398
  ? {
398
399
  id: (0, translations_1.getTradId)('popup.item.form.related.empty'),
399
400
  defaultMessage: 'There are no more entities',
@@ -405,19 +406,19 @@ const NavigationItemForm = ({ config, availableLocale, isLoading: isPreloading,
405
406
  return (react_1.default.createElement(Grid_1.GridItem, { key: "audience", col: 6, lg: 12 },
406
407
  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
408
  ? (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)))));
409
+ : 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
410
  }
410
411
  else {
411
412
  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) })));
413
+ 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
414
  }
414
415
  })),
415
416
  isI18nBootstrapAvailable ? (react_1.default.createElement(Grid_1.Grid, { gap: 5, paddingTop: 5 },
416
417
  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 })));
418
+ 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 })),
419
+ canUpdate && (react_1.default.createElement(Grid_1.GridItem, { col: 6, lg: 12, paddingTop: 6 },
420
+ 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)),
421
+ react_1.default.createElement(NavigationItemPopupFooter_1.NavigationItemPopupFooter, { handleSubmit: formik.handleSubmit, handleCancel: onCancel, submitDisabled: submitDisabled, canUpdate: canUpdate })));
421
422
  };
422
423
  const appendLabelPublicationStatusFallback = () => "";
423
424
  const loadingAware = (action, isLoading) => async (input) => {
@@ -1,4 +1,4 @@
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
4
  export declare type FormEventTarget<TValue = unknown> = {
@@ -63,6 +63,7 @@ export declare type NavigationItemFormProps = {
63
63
  slugify: (q: string) => Promise<{
64
64
  slug: string;
65
65
  }>;
66
+ permissions: PluginPermissions;
66
67
  };
67
68
  export declare type ContentTypeSearchQuery = ToBeFixed;
68
69
  export declare type RawFormPayload = {
@@ -1,9 +1,10 @@
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
10
  const onValidate: undefined;
@@ -17,6 +18,7 @@ export namespace NavigationItemPopupFooter {
17
18
  export { submitDisabled_1 as submitDisabled };
18
19
  const formViewId_1: PropTypes.Requireable<object>;
19
20
  export { formViewId_1 as formViewId };
21
+ export const canUpdate: PropTypes.Requireable<boolean>;
20
22
  }
21
23
  }
22
24
  import PropTypes from "prop-types";
@@ -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
@@ -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, slugify, }: {
2
+ declare function NavigationItemPopUp({ availableLocale, isOpen, isLoading, data, config, onSubmit, onClose, usedContentTypeItems, getContentTypeItems, usedContentTypesData, locale, readNavigationItemFromLocale, slugify, permissions, }: {
3
3
  availableLocale: any;
4
4
  isOpen: any;
5
5
  isLoading: any;
@@ -13,6 +13,7 @@ declare function NavigationItemPopUp({ availableLocale, isOpen, isLoading, data,
13
13
  locale: any;
14
14
  readNavigationItemFromLocale: any;
15
15
  slugify: any;
16
+ permissions?: {} | undefined;
16
17
  }): JSX.Element;
17
18
  declare namespace NavigationItemPopUp {
18
19
  namespace propTypes {
@@ -34,12 +34,13 @@ 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, slugify, }) => {
37
+ const NavigationItemPopUp = ({ availableLocale, isOpen, isLoading, data, config = {}, onSubmit, onClose, usedContentTypeItems, getContentTypeItems, usedContentTypesData, locale, readNavigationItemFromLocale, slugify, permissions = {}, }) => {
38
38
  const handleOnSubmit = (payload) => {
39
39
  onSubmit(payload);
40
40
  };
41
41
  const { related, relatedType } = data;
42
42
  const { availableAudience = [], additionalFields, contentTypes, contentTypeItems, contentTypesNameFields = {}, } = config;
43
+ const { canUpdate } = permissions;
43
44
  const appendLabelPublicationStatus = (label = '', item = {}, isCollection = false) => {
44
45
  const appendix = (0, parsers_1.isRelationPublished)({
45
46
  relatedRef: item,
@@ -70,8 +71,8 @@ const NavigationItemPopUp = ({ availableLocale, isOpen, isLoading, data, config
70
71
  const preparedData = (0, react_1.useMemo)(prepareFormData.bind(null, data), [data]);
71
72
  const hasViewId = !!data.viewId;
72
73
  return (react_1.default.createElement(ModalLayout_1.ModalLayout, { labelledBy: "condition-modal-breadcrumbs", onClose: onClose, isOpen: isOpen },
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, slugify: slugify })));
74
+ react_1.default.createElement(NavigationItemPopupHeader_1.NavigationItemPopupHeader, { isNewItem: !hasViewId, canUpdate: canUpdate }),
75
+ 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, permissions: permissions })));
75
76
  };
76
77
  NavigationItemPopUp.propTypes = {
77
78
  data: prop_types_1.default.object.isRequired,
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  export declare const edit: JSX.Element;
3
2
  export declare const deleteIcon: JSX.Element;
4
3
  //# sourceMappingURL=icons.d.ts.map
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { Footer } from "../Footer";
3
2
  import { CommonProps, ListState } from "../types";
4
3
  interface Props extends ListState, CommonProps {
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { Footer } from "../Footer";
3
2
  import { CommonProps, DeleteState } from "../types";
4
3
  interface Props extends DeleteState, CommonProps {
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import { Footer } from "../Footer";
3
2
  import { CommonProps, ErrorState } from "../types";
4
3
  interface Props extends ErrorState, CommonProps {