strapi-plugin-navigation 1.1.2 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -15
- package/admin/src/components/EmptyView/index.js +7 -16
- package/admin/src/components/Item/ItemCardBadge/index.js +8 -0
- package/admin/src/components/Item/ItemCardHeader/Wrapper.js +21 -0
- package/admin/src/components/Item/ItemCardHeader/index.js +59 -0
- package/admin/src/components/Item/Wrapper.js +39 -0
- package/admin/src/components/Item/index.js +76 -124
- package/admin/src/components/NavigationItemList/Wrapper.js +22 -0
- package/admin/src/components/NavigationItemList/index.js +54 -0
- package/admin/src/components/PluginIcon/index.js +6 -0
- package/admin/src/index.js +49 -45
- package/admin/src/pages/App/index.js +31 -0
- package/admin/src/{containers → pages}/DataManagerProvider/actions.js +0 -0
- package/admin/src/{containers → pages}/DataManagerProvider/index.js +81 -85
- package/admin/src/{containers → pages}/DataManagerProvider/init.js +0 -0
- package/admin/src/{containers → pages}/DataManagerProvider/reducer.js +0 -0
- package/admin/src/pages/View/components/NavigationContentHeader/index.js +18 -0
- package/admin/src/pages/View/components/NavigationHeader/index.js +60 -0
- package/admin/src/pages/View/components/NavigationItemForm/index.js +403 -0
- package/admin/src/{containers → pages}/View/components/NavigationItemForm/utils/form.js +2 -2
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupFooter.js +40 -0
- package/admin/src/pages/View/components/NavigationItemPopup/NavigationItemPopupHeader.js +20 -0
- package/admin/src/{containers → pages}/View/components/NavigationItemPopup/index.js +16 -16
- package/admin/src/pages/View/index.js +209 -0
- package/admin/src/{containers → pages}/View/utils/enums.js +0 -0
- package/admin/src/{containers → pages}/View/utils/form.js +1 -1
- package/admin/src/{containers → pages}/View/utils/index.js +0 -0
- package/admin/src/{containers → pages}/View/utils/parsers.js +13 -12
- package/admin/src/pluginId.js +4 -3
- package/admin/src/translations/en.json +47 -38
- package/admin/src/translations/fr.json +7 -1
- package/admin/src/utils/getTrad.js +2 -2
- package/package.json +13 -5
- package/server/bootstrap.js +41 -0
- package/server/config.js +8 -0
- package/server/content-types/audience/index.js +9 -0
- package/{models/audience.js → server/content-types/audience/lifecycle.js} +0 -0
- package/{models/audience.settings.json → server/content-types/audience/schema.json} +4 -2
- package/server/content-types/index.js +13 -0
- package/server/content-types/navigation/index.js +9 -0
- package/{models/navigation.js → server/content-types/navigation/lifecycle.js} +0 -0
- package/server/content-types/navigation/schema.js +45 -0
- package/server/content-types/navigation-item/index.js +9 -0
- package/{models/navigationItem.js → server/content-types/navigation-item/lifecycle.js} +0 -0
- package/{models/navigationItem.settings.json → server/content-types/navigation-item/schema.json} +16 -12
- package/server/content-types/navigations-items-related/index.js +9 -0
- package/{models/navigations_items_related.js → server/content-types/navigations-items-related/lifecycle.js} +0 -0
- package/{models/navigations_items_related.settings.json → server/content-types/navigations-items-related/schema.json} +4 -2
- package/server/controllers/index.js +7 -0
- package/{controllers → server/controllers}/navigation.js +7 -39
- package/server/routes/admin.js +38 -0
- package/server/routes/index.js +3 -0
- package/{services → server/services}/__tests__/navigation.test.js +0 -0
- package/server/services/index.js +7 -0
- package/server/services/navigation.js +463 -0
- package/{services → server/services}/utils/constant.js +3 -1
- package/server/services/utils/functions.js +103 -0
- package/strapi-admin.js +1 -0
- package/strapi-server.js +18 -0
- package/__mocks__/helpers/another-plugin/blog-post.settings.json +0 -31
- package/__mocks__/helpers/another-plugin/pages.settings.json +0 -28
- package/__mocks__/helpers/blog-post.settings.json +0 -31
- package/__mocks__/helpers/home-page.settings.json +0 -4
- package/__mocks__/helpers/my-homepage.settings.json +0 -27
- package/__mocks__/helpers/pages.settings.json +0 -27
- package/__mocks__/helpers/strapi.js +0 -101
- package/admin/src/assets/images/icon-cross-blue.svg +0 -1
- package/admin/src/assets/images/icon_remove.svg +0 -19
- package/admin/src/components/Container/index.js +0 -7
- package/admin/src/components/Input/index.js +0 -41
- package/admin/src/components/Item/CardItem.js +0 -46
- package/admin/src/components/Item/CardItemLevelAdd.js +0 -41
- package/admin/src/components/Item/CardItemLevelWrapper.js +0 -27
- package/admin/src/components/Item/CardItemPath.js +0 -9
- package/admin/src/components/Item/CardItemRestore.js +0 -19
- package/admin/src/components/Item/CardItemTitle.js +0 -5
- package/admin/src/components/Item/CardWrapper.js +0 -78
- package/admin/src/components/ItemFooter/CardItemError.js +0 -11
- package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
- package/admin/src/components/ItemFooter/CardItemRelationStatus.js +0 -17
- package/admin/src/components/ItemFooter/CardItemType.js +0 -18
- package/admin/src/components/ItemFooter/Wrapper.js +0 -26
- package/admin/src/components/ItemFooter/index.js +0 -66
- package/admin/src/components/ItemOrdering/CardOrderingButton.js +0 -24
- package/admin/src/components/ItemOrdering/Wrapper.js +0 -24
- package/admin/src/components/ItemOrdering/index.js +0 -36
- package/admin/src/components/List/Container.js +0 -34
- package/admin/src/components/List/ListLevelRoot.js +0 -18
- package/admin/src/components/List/index.js +0 -81
- package/admin/src/components/Option/OptionButton.js +0 -18
- package/admin/src/components/Option/OptionSet.js +0 -14
- package/admin/src/components/Option/Wrapper.js +0 -15
- package/admin/src/components/Option/index.js +0 -47
- package/admin/src/components/Search/index.js +0 -86
- package/admin/src/components/Select/ClearIndicator.js +0 -15
- package/admin/src/components/Select/DropdownIndicator.js +0 -39
- package/admin/src/components/Select/ErrorMessage.js +0 -10
- package/admin/src/components/Select/IndicatorSeparator.js +0 -3
- package/admin/src/components/Select/MultiValueContainer.js +0 -43
- package/admin/src/components/Select/StyledOption.js +0 -11
- package/admin/src/components/Select/index.js +0 -68
- package/admin/src/components/Select/utils/styles.js +0 -92
- package/admin/src/containers/App/Wrapper.js +0 -14
- package/admin/src/containers/App/index.js +0 -34
- package/admin/src/containers/DetailsView/Wrapper.js +0 -21
- package/admin/src/containers/DetailsView/index.js +0 -111
- package/admin/src/containers/Initializer/index.js +0 -26
- package/admin/src/containers/ListView/Footer.js +0 -56
- package/admin/src/containers/ListView/components.js +0 -138
- package/admin/src/containers/ListView/index.js +0 -54
- package/admin/src/containers/View/FadedWrapper.js +0 -51
- package/admin/src/containers/View/HeaderForm.js +0 -9
- package/admin/src/containers/View/HeaderFormCell.js +0 -25
- package/admin/src/containers/View/Wrapper.js +0 -17
- package/admin/src/containers/View/components/NavigationItemForm/ModalFooter.js +0 -45
- package/admin/src/containers/View/components/NavigationItemForm/index.js +0 -427
- package/admin/src/containers/View/components/NavigationItemPopup/MediumPopup.js +0 -6
- package/admin/src/containers/View/index.js +0 -240
- package/admin/src/lifecycles.js +0 -3
- package/admin/src/permissions.js +0 -14
- package/config/functions/bootstrap.js +0 -138
- package/config/routes.json +0 -60
- package/config/schema.graphql.js +0 -204
- package/examples/audit-log-integrations.js.md +0 -38
- package/models/navigation.settings.json +0 -43
- package/public/assets/preview.png +0 -0
- package/services/navigation.js +0 -730
- package/services/utils/functions.js +0 -186
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
3
|
-
* Navigation View
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React, { memo, useMemo, useState } from 'react';
|
|
8
|
-
import { FormattedMessage, useIntl } from "react-intl";
|
|
9
|
-
import { LoadingIndicatorPage } from "strapi-helper-plugin";
|
|
10
|
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
11
|
-
import { faHamburger, faPlus } from "@fortawesome/free-solid-svg-icons";
|
|
12
|
-
import useDataManager from "../../hooks/useDataManager";
|
|
13
|
-
import { isEmpty, get } from "lodash";
|
|
14
|
-
import { Header } from "@buffetjs/custom";
|
|
15
|
-
import { Button, HeaderActions, Select } from "@buffetjs/core";
|
|
16
|
-
import Wrapper from "../View/Wrapper";
|
|
17
|
-
import EmptyView from "../../components/EmptyView";
|
|
18
|
-
import HeaderForm from "./HeaderForm";
|
|
19
|
-
import HeaderFormCell from "./HeaderFormCell";
|
|
20
|
-
import NavigationItemPopUp from "./components/NavigationItemPopup";
|
|
21
|
-
import List from "../../components/List";
|
|
22
|
-
import {
|
|
23
|
-
transformItemToViewPayload,
|
|
24
|
-
transformToRESTPayload,
|
|
25
|
-
usedContentTypes,
|
|
26
|
-
validateNavigationStructure,
|
|
27
|
-
} from './utils/parsers';
|
|
28
|
-
import FadedWrapper from "./FadedWrapper";
|
|
29
|
-
import { getTrad, getTradId } from '../../translations';
|
|
30
|
-
|
|
31
|
-
const View = () => {
|
|
32
|
-
const {
|
|
33
|
-
items: availableNavigations,
|
|
34
|
-
activeItem: activeNavigation,
|
|
35
|
-
changedActiveItem: changedActiveNavigation,
|
|
36
|
-
config,
|
|
37
|
-
navigationItemPopupOpened,
|
|
38
|
-
isLoading,
|
|
39
|
-
isLoadingForAdditionalDataToBeSet,
|
|
40
|
-
isLoadingForSubmit,
|
|
41
|
-
handleChangeNavigationItemPopupVisibility,
|
|
42
|
-
handleChangeSelection,
|
|
43
|
-
handleChangeNavigationData,
|
|
44
|
-
handleResetNavigationData,
|
|
45
|
-
handleSubmitNavigation,
|
|
46
|
-
getContentTypeItems,
|
|
47
|
-
error
|
|
48
|
-
} = useDataManager();
|
|
49
|
-
const [activeNavigationItem, setActiveNavigationItemState] = useState({});
|
|
50
|
-
const { formatMessage } = useIntl();
|
|
51
|
-
|
|
52
|
-
const options = availableNavigations.map((item) => ({
|
|
53
|
-
value: item.id,
|
|
54
|
-
label: item.name,
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
const structureHasErrors = !validateNavigationStructure((changedActiveNavigation || {}).items);
|
|
58
|
-
const navigationSelectValue = get(activeNavigation, "id", null);
|
|
59
|
-
const actions = [
|
|
60
|
-
{
|
|
61
|
-
label: formatMessage(getTrad('submit.cta.cancel')),
|
|
62
|
-
onClick: () => isLoadingForSubmit ? null : handleResetNavigationData(),
|
|
63
|
-
color: "cancel",
|
|
64
|
-
type: "button",
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
label: formatMessage(getTrad('submit.cta.save')),
|
|
68
|
-
onClick: () =>
|
|
69
|
-
isLoadingForSubmit || structureHasErrors ? null : handleSubmitNavigation(formatMessage, transformToRESTPayload(changedActiveNavigation, config)),
|
|
70
|
-
color: "success",
|
|
71
|
-
type: "submit",
|
|
72
|
-
isLoading: isLoadingForSubmit,
|
|
73
|
-
disabled: structureHasErrors,
|
|
74
|
-
},
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
const pullUsedContentTypeItem = (items = []) =>
|
|
78
|
-
items.reduce((prev, curr) =>
|
|
79
|
-
[...prev, curr.relatedRef ? {
|
|
80
|
-
__collectionName: curr.relatedRef.__collectionName,
|
|
81
|
-
id: curr.relatedRef.id
|
|
82
|
-
} : undefined, ...pullUsedContentTypeItem(curr.items)].filter(item => item)
|
|
83
|
-
, []);
|
|
84
|
-
const usedContentTypeItems = pullUsedContentTypeItem((changedActiveNavigation || {}).items);
|
|
85
|
-
|
|
86
|
-
const changeNavigationItemPopupState = (visible, editedItem = {}) => {
|
|
87
|
-
setActiveNavigationItemState(editedItem);
|
|
88
|
-
handleChangeNavigationItemPopupVisibility(visible);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const addNewNavigationItem = (
|
|
92
|
-
e,
|
|
93
|
-
viewId = null,
|
|
94
|
-
isMenuAllowedLevel = true,
|
|
95
|
-
levelPath = '',
|
|
96
|
-
parentAttachedToMenu = true,
|
|
97
|
-
) => {
|
|
98
|
-
e.preventDefault();
|
|
99
|
-
e.stopPropagation();
|
|
100
|
-
changeNavigationItemPopupState(true, {
|
|
101
|
-
viewParentId: viewId,
|
|
102
|
-
isMenuAllowedLevel,
|
|
103
|
-
levelPath,
|
|
104
|
-
parentAttachedToMenu,
|
|
105
|
-
});
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const editNavigationItem = (
|
|
109
|
-
e,
|
|
110
|
-
item,
|
|
111
|
-
levelPath = '',
|
|
112
|
-
parentAttachedToMenu = true,
|
|
113
|
-
) => {
|
|
114
|
-
e.preventDefault();
|
|
115
|
-
e.stopPropagation();
|
|
116
|
-
changeNavigationItemPopupState(true, {
|
|
117
|
-
...item,
|
|
118
|
-
levelPath,
|
|
119
|
-
parentAttachedToMenu,
|
|
120
|
-
});
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
const restoreNavigationItem = (e, item) => {
|
|
124
|
-
e.preventDefault();
|
|
125
|
-
e.stopPropagation();
|
|
126
|
-
|
|
127
|
-
handleSubmitNavigationItem({
|
|
128
|
-
...item,
|
|
129
|
-
removed: false,
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const reOrderNavigationItem = (e, item, moveBy = 0) => {
|
|
134
|
-
e.preventDefault();
|
|
135
|
-
e.stopPropagation();
|
|
136
|
-
|
|
137
|
-
handleSubmitNavigationItem({
|
|
138
|
-
...item,
|
|
139
|
-
order: item.order + (moveBy * 1.5),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const onPopUpClose = (e) => {
|
|
144
|
-
e.preventDefault();
|
|
145
|
-
e.stopPropagation();
|
|
146
|
-
changeNavigationItemPopupState(false);
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const handleSubmitNavigationItem = (payload) => {
|
|
150
|
-
const changedStructure = {
|
|
151
|
-
...changedActiveNavigation,
|
|
152
|
-
items: transformItemToViewPayload(payload, changedActiveNavigation.items, config),
|
|
153
|
-
};
|
|
154
|
-
handleChangeNavigationData(changedStructure, true);
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
const usedContentTypesData = useMemo(
|
|
158
|
-
() => changedActiveNavigation ? usedContentTypes(changedActiveNavigation.items) : [],
|
|
159
|
-
[changedActiveNavigation],
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return (
|
|
163
|
-
<div className="container-fluid">
|
|
164
|
-
<div className="row">
|
|
165
|
-
<Wrapper className="col-md-12">
|
|
166
|
-
<HeaderForm>
|
|
167
|
-
<HeaderFormCell>
|
|
168
|
-
<Header
|
|
169
|
-
title={{
|
|
170
|
-
label: formatMessage(getTrad('header.title')),
|
|
171
|
-
}}
|
|
172
|
-
content={formatMessage(getTrad('header.description'))}
|
|
173
|
-
/>
|
|
174
|
-
</HeaderFormCell>
|
|
175
|
-
{ options && (options.length > 1) && (<HeaderFormCell>
|
|
176
|
-
<Select
|
|
177
|
-
name="activeNavigation"
|
|
178
|
-
onChange={({ target: { value } }) =>
|
|
179
|
-
handleChangeSelection(value)
|
|
180
|
-
}
|
|
181
|
-
options={options}
|
|
182
|
-
value={navigationSelectValue}
|
|
183
|
-
/>
|
|
184
|
-
</HeaderFormCell>) }
|
|
185
|
-
<HeaderFormCell align="right" fill>
|
|
186
|
-
<HeaderActions actions={actions} />
|
|
187
|
-
</HeaderFormCell>
|
|
188
|
-
</HeaderForm>
|
|
189
|
-
<FadedWrapper>
|
|
190
|
-
{isLoading && <LoadingIndicatorPage />}
|
|
191
|
-
{changedActiveNavigation && (
|
|
192
|
-
<>
|
|
193
|
-
{isEmpty(changedActiveNavigation.items || []) && (
|
|
194
|
-
<EmptyView>
|
|
195
|
-
<FontAwesomeIcon icon={faHamburger} size="5x" />
|
|
196
|
-
<FormattedMessage id={getTradId('empty')} />
|
|
197
|
-
<Button
|
|
198
|
-
color="primary"
|
|
199
|
-
icon={<FontAwesomeIcon icon={faPlus} />}
|
|
200
|
-
label={formatMessage(getTrad('empty.cta'))}
|
|
201
|
-
onClick={addNewNavigationItem}
|
|
202
|
-
/>
|
|
203
|
-
</EmptyView>
|
|
204
|
-
)}
|
|
205
|
-
{!isEmpty(changedActiveNavigation.items || []) && (
|
|
206
|
-
<List
|
|
207
|
-
items={changedActiveNavigation.items || []}
|
|
208
|
-
onItemClick={editNavigationItem}
|
|
209
|
-
onItemReOrder={reOrderNavigationItem}
|
|
210
|
-
onItemRestoreClick={restoreNavigationItem}
|
|
211
|
-
onItemLevelAddClick={addNewNavigationItem}
|
|
212
|
-
root
|
|
213
|
-
error={error}
|
|
214
|
-
allowedLevels={config.allowedLevels}
|
|
215
|
-
contentTypes={config.contentTypes}
|
|
216
|
-
isParentAttachedToMenu={true}
|
|
217
|
-
contentTypesNameFields={config.contentTypesNameFields}
|
|
218
|
-
/>
|
|
219
|
-
)}
|
|
220
|
-
</>
|
|
221
|
-
)}
|
|
222
|
-
</FadedWrapper>
|
|
223
|
-
<NavigationItemPopUp
|
|
224
|
-
isOpen={navigationItemPopupOpened}
|
|
225
|
-
isLoading={isLoadingForAdditionalDataToBeSet}
|
|
226
|
-
data={activeNavigationItem}
|
|
227
|
-
config={config}
|
|
228
|
-
usedContentTypesData={usedContentTypesData}
|
|
229
|
-
usedContentTypeItems={usedContentTypeItems}
|
|
230
|
-
getContentTypeItems={getContentTypeItems}
|
|
231
|
-
onSubmit={handleSubmitNavigationItem}
|
|
232
|
-
onClose={onPopUpClose}
|
|
233
|
-
/>
|
|
234
|
-
</Wrapper>
|
|
235
|
-
</div>
|
|
236
|
-
</div>
|
|
237
|
-
);
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
export default memo(View);
|
package/admin/src/lifecycles.js
DELETED
package/admin/src/permissions.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const pluginPermissions = {
|
|
2
|
-
// This permission regards the main component (App) and is used to tell
|
|
3
|
-
// If the plugin link should be displayed in the menu
|
|
4
|
-
// And also if the plugin is accessible. This use case is found when a user types the url of the
|
|
5
|
-
// plugin directly in the browser
|
|
6
|
-
main: [
|
|
7
|
-
{ action: "plugins::navigation.read", subject: null },
|
|
8
|
-
{ action: "plugins::navigation.update", subject: null },
|
|
9
|
-
],
|
|
10
|
-
open: [{ action: "plugins::navigation.read", subject: null }],
|
|
11
|
-
update: [{ action: "plugins::navigation.update", subject: null }],
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export default pluginPermissions;
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
const { isEmpty, get, last } = require('lodash');
|
|
2
|
-
|
|
3
|
-
const saveJSONParse = (value) => {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(value).map((_) => ({ ..._, id: _._id }));
|
|
6
|
-
} catch (e) {
|
|
7
|
-
return null;
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const getDefaultConnectionName = (strapi) => strapi.config.get('database.defaultConnection');
|
|
12
|
-
|
|
13
|
-
const isMongo = (strapi) => {
|
|
14
|
-
const connectionName = getDefaultConnectionName(strapi);
|
|
15
|
-
return strapi.config.get(`database.connections.${connectionName}.connector`).includes('mongo');
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const getNavigationMorphData = (strapi) => {
|
|
19
|
-
const connectionName = getDefaultConnectionName(strapi);
|
|
20
|
-
const { [connectionName]: knex } = strapi.connections;
|
|
21
|
-
return knex.schema.hasTable('navigations_items_morph').then((exist)=> exist ? knex('navigations_items_morph').select('*') : []);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const getNavigationItemsModel = (strapi) => strapi.query('navigationitem', 'navigation');
|
|
25
|
-
|
|
26
|
-
const getRelatedModel = (strapi) => strapi.query('navigations_items_related', 'navigation');
|
|
27
|
-
|
|
28
|
-
const createRelatedData = (relatedModel, navigationItemsModel, items) => ({
|
|
29
|
-
field,
|
|
30
|
-
order,
|
|
31
|
-
related_id,
|
|
32
|
-
related_type,
|
|
33
|
-
navigations_items_id,
|
|
34
|
-
}) => {
|
|
35
|
-
const item = items.find(item => item.id === navigations_items_id);
|
|
36
|
-
const modelUID = get(strapi.query(related_type), 'model.uid');
|
|
37
|
-
if (item && modelUID) {
|
|
38
|
-
const relatedData = {
|
|
39
|
-
field,
|
|
40
|
-
order,
|
|
41
|
-
related_id,
|
|
42
|
-
related_type: modelUID,
|
|
43
|
-
master: get(item.master, 'id', item.master),
|
|
44
|
-
};
|
|
45
|
-
return relatedModel.create(relatedData)
|
|
46
|
-
.then(
|
|
47
|
-
({ id }) => navigationItemsModel.update({ id: navigations_items_id }, { related: id }),
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
return Promise.resolve();
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const migrateNavigationItemsSQL = async (strapi) => {
|
|
54
|
-
const morphData = await getNavigationMorphData(strapi);
|
|
55
|
-
if (morphData.length) {
|
|
56
|
-
const relatedModel = getRelatedModel(strapi);
|
|
57
|
-
const navigationItemsModel = getNavigationItemsModel(strapi);
|
|
58
|
-
const items = await navigationItemsModel.find({});
|
|
59
|
-
await Promise.all(morphData.map(createRelatedData(relatedModel, navigationItemsModel, items)));
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const migrateNavigationItemsMongo = async (strapi) => {
|
|
64
|
-
const navigationItemsModel = getNavigationItemsModel(strapi);
|
|
65
|
-
const connectionName = getDefaultConnectionName(strapi);
|
|
66
|
-
const models = strapi.connections[connectionName].models;
|
|
67
|
-
const items = (await models.NavigationNavigationitem.find({}))
|
|
68
|
-
// workaround to change type from object to int
|
|
69
|
-
.map(_ => ({ ..._.toObject(), related: last(saveJSONParse(get(_.errors, 'related.properties.value', null))) }))
|
|
70
|
-
.filter(_ => _.related);
|
|
71
|
-
|
|
72
|
-
if (items.length) {
|
|
73
|
-
await Promise.all(items.map(item => {
|
|
74
|
-
const data = {
|
|
75
|
-
related_id: item.related.ref,
|
|
76
|
-
related_type: models[item.related.kind].uid,
|
|
77
|
-
field: item.related.field,
|
|
78
|
-
order: 1,
|
|
79
|
-
master: item.master,
|
|
80
|
-
};
|
|
81
|
-
return getRelatedModel(strapi)
|
|
82
|
-
.create(data)
|
|
83
|
-
.then(result => navigationItemsModel.update({ id: item.id }, { related: [result.id] }));
|
|
84
|
-
}));
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
module.exports = async () => {
|
|
90
|
-
// Check if the plugin users-permissions is installed because the navigation needs it
|
|
91
|
-
if (Object.keys(strapi.plugins).indexOf('users-permissions') === -1) {
|
|
92
|
-
throw new Error(
|
|
93
|
-
'In order to make the navigation plugin work the users-permissions plugin is required',
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Add permissions
|
|
98
|
-
const actions = [
|
|
99
|
-
{
|
|
100
|
-
section: 'plugins',
|
|
101
|
-
displayName: 'Access the Navigation',
|
|
102
|
-
uid: 'read',
|
|
103
|
-
pluginName: 'navigation',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
section: 'plugins',
|
|
107
|
-
displayName: 'Ability to change the Navigation',
|
|
108
|
-
uid: 'update',
|
|
109
|
-
pluginName: 'navigation',
|
|
110
|
-
},
|
|
111
|
-
];
|
|
112
|
-
|
|
113
|
-
const navigations = await strapi
|
|
114
|
-
.query('navigation', 'navigation')
|
|
115
|
-
.find();
|
|
116
|
-
if (isEmpty(navigations)) {
|
|
117
|
-
await strapi
|
|
118
|
-
.query('navigation', 'navigation')
|
|
119
|
-
.create({
|
|
120
|
-
name: 'Main navigation',
|
|
121
|
-
slug: 'main-navigation',
|
|
122
|
-
visible: true,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
const relatedModel = getRelatedModel(global.strapi);
|
|
126
|
-
const isMigrated = !!(await relatedModel.count({}));
|
|
127
|
-
if (!isMigrated) {
|
|
128
|
-
const isMongoDB = isMongo(global.strapi);
|
|
129
|
-
if (isMongoDB) {
|
|
130
|
-
await migrateNavigationItemsMongo(global.strapi);
|
|
131
|
-
} else {
|
|
132
|
-
await migrateNavigationItemsSQL(global.strapi);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const { actionProvider } = strapi.admin.services.permission;
|
|
137
|
-
await actionProvider.registerMany(actions);
|
|
138
|
-
};
|
package/config/routes.json
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"routes": [
|
|
3
|
-
{
|
|
4
|
-
"method": "GET",
|
|
5
|
-
"path": "/",
|
|
6
|
-
"handler": "navigation.get",
|
|
7
|
-
"config": {
|
|
8
|
-
"policies": []
|
|
9
|
-
}
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"method": "POST",
|
|
13
|
-
"path": "/",
|
|
14
|
-
"handler": "navigation.post",
|
|
15
|
-
"config": {
|
|
16
|
-
"policies": []
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"method": "GET",
|
|
21
|
-
"path": "/config",
|
|
22
|
-
"handler": "navigation.config",
|
|
23
|
-
"config": {
|
|
24
|
-
"policies": []
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"method": "GET",
|
|
29
|
-
"path": "/:id",
|
|
30
|
-
"handler": "navigation.getById",
|
|
31
|
-
"config": {
|
|
32
|
-
"policies": []
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
"method": "PUT",
|
|
37
|
-
"path": "/:id",
|
|
38
|
-
"handler": "navigation.put",
|
|
39
|
-
"config": {
|
|
40
|
-
"policies": []
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"method": "GET",
|
|
45
|
-
"path": "/render/:idOrSlug",
|
|
46
|
-
"handler": "navigation.render",
|
|
47
|
-
"config": {
|
|
48
|
-
"policies": []
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"method": "GET",
|
|
53
|
-
"path": "/render/:idOrSlug/:childUIKey",
|
|
54
|
-
"handler": "navigation.renderChild",
|
|
55
|
-
"config": {
|
|
56
|
-
"policies": []
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
}
|
package/config/schema.graphql.js
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
const NAVIGATION_DATE = `
|
|
2
|
-
# SQL
|
|
3
|
-
created_at: String
|
|
4
|
-
updated_at: String
|
|
5
|
-
# MONGO
|
|
6
|
-
createdAt: String
|
|
7
|
-
updatedAt: String
|
|
8
|
-
`;
|
|
9
|
-
|
|
10
|
-
const NAVIGATION_USER = `
|
|
11
|
-
# SQL
|
|
12
|
-
created_by: String
|
|
13
|
-
updated_by: String
|
|
14
|
-
# MONGO
|
|
15
|
-
createdBy: String
|
|
16
|
-
updatedBy: String
|
|
17
|
-
`;
|
|
18
|
-
|
|
19
|
-
const NAVIGATION = `
|
|
20
|
-
id: String!
|
|
21
|
-
name: String!
|
|
22
|
-
slug: String!
|
|
23
|
-
visible: Boolean!
|
|
24
|
-
`;
|
|
25
|
-
|
|
26
|
-
const getContentTypesNamesFields = () => {
|
|
27
|
-
const contentTypesNameFields = strapi.config.get('plugins.navigation.contentTypesNameFields');
|
|
28
|
-
return Object.keys(contentTypesNameFields || {}).map(key => `${key}: [String]!`).join('\n');
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const getNavigationRelated = () => {
|
|
32
|
-
const related = strapi.config.get('plugins.navigation.gql.navigationItemRelated');
|
|
33
|
-
if (related) {
|
|
34
|
-
return related;
|
|
35
|
-
}
|
|
36
|
-
return `
|
|
37
|
-
type NavigationRelated {
|
|
38
|
-
id: Int
|
|
39
|
-
title: String
|
|
40
|
-
name: String
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
module.exports = {
|
|
46
|
-
// language=GraphQL
|
|
47
|
-
definition: `
|
|
48
|
-
enum NavigationRenderType {
|
|
49
|
-
FLAT,
|
|
50
|
-
TREE,
|
|
51
|
-
RFR
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
${getNavigationRelated()}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
type NavigationItem {
|
|
58
|
-
id: Int!
|
|
59
|
-
title: String!
|
|
60
|
-
type: String!
|
|
61
|
-
path: String
|
|
62
|
-
externalPath: String
|
|
63
|
-
uiRouterKey: String!
|
|
64
|
-
menuAttached: Boolean!
|
|
65
|
-
order: Int!
|
|
66
|
-
parent: Int
|
|
67
|
-
master: Int
|
|
68
|
-
items: [NavigationItem]
|
|
69
|
-
related: NavigationRelated
|
|
70
|
-
audience: [String]
|
|
71
|
-
${NAVIGATION_DATE}
|
|
72
|
-
${NAVIGATION_USER}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type Navigation {
|
|
76
|
-
${NAVIGATION}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
type NavigationDetails {
|
|
80
|
-
${NAVIGATION}
|
|
81
|
-
items: [NavigationItem]!
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
type ContentTypesNameFields {
|
|
86
|
-
default: [String!]!
|
|
87
|
-
${getContentTypesNamesFields()}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
type ContentTypes {
|
|
91
|
-
uid: String!
|
|
92
|
-
name: String!
|
|
93
|
-
isSingle: Boolean!
|
|
94
|
-
collectionName: String!
|
|
95
|
-
contentTypeName: String!
|
|
96
|
-
label: String!
|
|
97
|
-
relatedField: String!
|
|
98
|
-
labelSingular: String!
|
|
99
|
-
endpoint: String!
|
|
100
|
-
available: Boolean!
|
|
101
|
-
visible: Boolean!
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
type NavigationConfig {
|
|
105
|
-
allowedLevels: Int
|
|
106
|
-
availableAudience: [NavigationAudience]!
|
|
107
|
-
additionalFields: [String]!
|
|
108
|
-
contentTypesNameFields: ContentTypesNameFields
|
|
109
|
-
contentTypes: [ContentTypes]
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
input CreateNavigationRelated {
|
|
113
|
-
ref: String!
|
|
114
|
-
field: String!
|
|
115
|
-
refId: String!
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
input CreateNavigationItem {
|
|
119
|
-
title: String!
|
|
120
|
-
type: String!
|
|
121
|
-
path: String
|
|
122
|
-
externalPath: String
|
|
123
|
-
uiRouterKey: String!
|
|
124
|
-
menuAttached: Boolean!
|
|
125
|
-
order: Int!
|
|
126
|
-
parent: Int
|
|
127
|
-
master: Int
|
|
128
|
-
items: [CreateNavigationItem]
|
|
129
|
-
audience: [String]
|
|
130
|
-
related: CreateNavigationRelated
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
input CreateNavigation {
|
|
134
|
-
name: String!
|
|
135
|
-
items: [CreateNavigationItem]!
|
|
136
|
-
}
|
|
137
|
-
`,
|
|
138
|
-
query: `
|
|
139
|
-
renderNavigation(navigationIdOrSlug: String!, type: NavigationRenderType, menuOnly: Boolean): [NavigationItem]!
|
|
140
|
-
renderNavigationChild(id: String!, childUIKey: String!, type: NavigationRenderType, menuOnly: Boolean): [NavigationItem]!
|
|
141
|
-
getNavigation: [Navigation]!
|
|
142
|
-
configNavigation: NavigationConfig
|
|
143
|
-
getByIdNavigation(id: String!): NavigationItem
|
|
144
|
-
`,
|
|
145
|
-
type: {},
|
|
146
|
-
mutation: `
|
|
147
|
-
navigationCreate(newNavigation: CreateNavigation!): Navigation!
|
|
148
|
-
navigationUpdate(id: String!, navigation: CreateNavigation!): Navigation!
|
|
149
|
-
`,
|
|
150
|
-
resolver: {
|
|
151
|
-
Query: {
|
|
152
|
-
renderNavigation: {
|
|
153
|
-
resolverOf: 'plugins::navigation.navigation.render',
|
|
154
|
-
resolver(obj, options) {
|
|
155
|
-
const { navigationIdOrSlug, type, menuOnly } = options;
|
|
156
|
-
return strapi.plugins.navigation.services.navigation.render(navigationIdOrSlug, type, menuOnly);
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
renderNavigationChild: {
|
|
160
|
-
resolverOf: 'plugins::navigation.navigation.renderChild',
|
|
161
|
-
async resolver(obj, options) {
|
|
162
|
-
const { id, childUIKey, type, menuOnly } = options;
|
|
163
|
-
return strapi.plugins.navigation.services.navigation.renderChildren(id, childUIKey, type, menuOnly);
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
getNavigation: {
|
|
167
|
-
resolverOf: 'plugins::navigation.navigation.get',
|
|
168
|
-
resolver() {
|
|
169
|
-
return strapi.plugins.navigation.services.navigation.get();
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
configNavigation: {
|
|
173
|
-
resolverOf: 'plugins::navigation.navigation.config',
|
|
174
|
-
resolver() {
|
|
175
|
-
return strapi.plugins.navigation.services.navigation.config();
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
getByIdNavigation: {
|
|
179
|
-
resolverOf: 'plugins::navigation.navigation.getById',
|
|
180
|
-
async resolver(obj, options) {
|
|
181
|
-
const { id } = options;
|
|
182
|
-
return strapi.plugins.navigation.services.navigation.getById(id);
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
Mutation: {
|
|
187
|
-
navigationCreate: {
|
|
188
|
-
resolverOf: 'plugins::navigation.navigation.post',
|
|
189
|
-
resolver(obj, options) {
|
|
190
|
-
const { newNavigation } = options;
|
|
191
|
-
return strapi.plugins.navigation.services.navigation.post(newNavigation);
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
navigationUpdate: {
|
|
195
|
-
resolverOf: 'plugins::navigation.navigation.put',
|
|
196
|
-
resolver(obj, options) {
|
|
197
|
-
const { id, navigation } = options;
|
|
198
|
-
return strapi.plugins.navigation.services.navigation.put(id, navigation);
|
|
199
|
-
},
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
},
|
|
203
|
-
};
|
|
204
|
-
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
```javascript
|
|
2
|
-
const { Base, AvailableAction } = require('strapi-plugin-audit-log');
|
|
3
|
-
|
|
4
|
-
class Navigation extends Base {
|
|
5
|
-
constructor(strapi, user) {
|
|
6
|
-
super(strapi, user);
|
|
7
|
-
|
|
8
|
-
this.once('onChangeNavigation', ({ actionType, oldEntity, newEntity }) => {
|
|
9
|
-
this.actionType = actionType;
|
|
10
|
-
this.add('beforeUpdate', oldEntity);
|
|
11
|
-
this.add('afterUpdate', newEntity);
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async run(method, ctx, config) {
|
|
16
|
-
const data = this.sanitize(this.entities);
|
|
17
|
-
switch (method) {
|
|
18
|
-
case 'POST':
|
|
19
|
-
case 'PUT': {
|
|
20
|
-
const { beforeUpdate, afterUpdate } = data;
|
|
21
|
-
if (beforeUpdate && afterUpdate) {
|
|
22
|
-
const diffs = this.getDiff(beforeUpdate, afterUpdate);
|
|
23
|
-
return this.save(
|
|
24
|
-
ctx.params.id,
|
|
25
|
-
this.actionType || AvailableAction.UPDATE,
|
|
26
|
-
config.pluginName,
|
|
27
|
-
diffs,
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return Promise.resolve();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
module.exports = Navigation;
|
|
38
|
-
```
|