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.
- package/README.md +5 -1
- package/admin/src/components/AdditionalFieldInput/index.js +2 -2
- package/admin/src/components/AdditionalFieldInput/types.d.ts +1 -0
- package/admin/src/components/Item/ItemCardHeader/icons.d.ts +1 -1
- package/admin/src/components/Item/ItemCardHeader/icons.js +2 -1
- package/admin/src/components/Item/ItemCardHeader/index.d.ts +1 -0
- package/admin/src/components/Item/ItemCardHeader/index.js +6 -6
- package/admin/src/components/Item/index.js +7 -6
- package/admin/src/components/NavigationItemList/index.d.ts +2 -1
- package/admin/src/components/NavigationItemList/index.js +2 -2
- package/admin/src/hooks/useNavigationManager.d.ts +0 -1
- package/admin/src/index.js +1 -1
- package/admin/src/pages/DataManagerProvider/reducer.d.ts +1 -1
- package/admin/src/pages/NoAccessPage/index.d.ts +3 -0
- package/admin/src/pages/NoAccessPage/index.js +31 -0
- package/admin/src/pages/SettingsPage/index.d.ts +0 -1
- package/admin/src/pages/SettingsPage/index.js +9 -0
- package/admin/src/pages/View/components/NavigationHeader/index.d.ts +2 -1
- package/admin/src/pages/View/components/NavigationHeader/index.js +9 -8
- package/admin/src/pages/View/components/NavigationItemForm/index.js +14 -13
- package/admin/src/pages/View/components/NavigationItemForm/types.d.ts +2 -1
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.d.ts +4 -2
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +5 -1
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.d.ts +2 -1
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +6 -2
- package/admin/src/pages/View/components/NavigationItemPopup/index.d.ts +2 -1
- package/admin/src/pages/View/components/NavigationItemPopup/index.js +4 -3
- package/admin/src/pages/View/components/NavigationManager/AllNavigations/icons.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/AllNavigations/index.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/DeletionConfirm/index.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/ErrorDetails/index.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/Form/index.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/NavigationUpdate/index.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/NewNavigation/index.d.ts +0 -1
- package/admin/src/pages/View/components/NavigationManager/index.d.ts +0 -1
- package/admin/src/pages/View/index.js +39 -19
- package/admin/src/permissions.d.ts +4 -0
- package/admin/src/permissions.js +1 -0
- package/admin/src/translations/en.json +8 -0
- package/package.json +2 -2
- package/permissions.d.ts +1 -0
- package/permissions.js +1 -0
- package/server/bootstrap/index.js +6 -0
- package/tsconfig.tsbuildinfo +1 -1
- 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.
|
|
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";
|
|
@@ -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
|
|
@@ -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:
|
|
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,
|
package/admin/src/index.js
CHANGED
|
@@ -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.
|
|
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,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
|
|
@@ -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, {
|
|
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
|
-
|
|
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
|
|
@@ -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.${
|
|
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,
|