strapi-plugin-navigation 1.1.1 → 2.0.0-beta.3
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 +77 -84
- package/admin/src/{containers → pages}/DataManagerProvider/init.js +0 -0
- package/admin/src/pages/DataManagerProvider/reducer.js +125 -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 +3 -2
- 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 +14 -6
- 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/DataManagerProvider/reducer.js +0 -136
- 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
package/admin/src/index.js
CHANGED
|
@@ -1,49 +1,53 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import lifecycles from "./lifecycles";
|
|
6
|
-
import trads from "./translations";
|
|
7
|
-
import pluginPermissions from "./permissions";
|
|
1
|
+
import { prefixPluginTranslations } from '@strapi/helper-plugin';
|
|
2
|
+
import PluginIcon from './components/PluginIcon';
|
|
3
|
+
import pluginPkg from '../../package.json';
|
|
4
|
+
import pluginId from './pluginId';
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
const pluginDescription =
|
|
11
|
-
pluginPkg.strapi.description || pluginPkg.description;
|
|
12
|
-
const { icon, name } = pluginPkg.strapi;
|
|
6
|
+
const name = pluginPkg.strapi.name;
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
lifecycles,
|
|
26
|
-
leftMenuLinks: [],
|
|
27
|
-
leftMenuSections: [],
|
|
28
|
-
mainComponent: App,
|
|
29
|
-
name,
|
|
30
|
-
preventComponentRendering: false,
|
|
31
|
-
trads,
|
|
32
|
-
menu: {
|
|
33
|
-
pluginsSectionLinks: [
|
|
34
|
-
{
|
|
35
|
-
destination: `/plugins/${pluginId}`,
|
|
36
|
-
icon,
|
|
37
|
-
name,
|
|
38
|
-
label: {
|
|
39
|
-
id: `${pluginId}.plugin.name`,
|
|
40
|
-
defaultMessage: "NAVIGATION",
|
|
41
|
-
},
|
|
42
|
-
permissions: pluginPermissions.main,
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
};
|
|
8
|
+
export default {
|
|
9
|
+
register(app) {
|
|
10
|
+
app.addMenuLink({
|
|
11
|
+
to: `/plugins/${pluginId}`,
|
|
12
|
+
icon: PluginIcon,
|
|
13
|
+
intlLabel: {
|
|
14
|
+
id: `${pluginId}.plugin.name`,
|
|
15
|
+
defaultMessage: 'Navigation',
|
|
16
|
+
},
|
|
17
|
+
Component: async () => {
|
|
18
|
+
const component = await import(/* webpackChunkName: "my-plugin" */ './pages/App');
|
|
47
19
|
|
|
48
|
-
|
|
20
|
+
return component;
|
|
21
|
+
},
|
|
22
|
+
permissions: [],
|
|
23
|
+
});
|
|
24
|
+
app.registerPlugin({
|
|
25
|
+
id: pluginId,
|
|
26
|
+
name,
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
bootstrap() {},
|
|
30
|
+
async registerTrads({ locales }) {
|
|
31
|
+
const importedTrads = await Promise.all(
|
|
32
|
+
locales.map(locale => {
|
|
33
|
+
return import(
|
|
34
|
+
/* webpackChunkName: "[pluginId]-[request]" */ `./translations/${locale}.json`
|
|
35
|
+
)
|
|
36
|
+
.then(({ default: data }) => {
|
|
37
|
+
return {
|
|
38
|
+
data: prefixPluginTranslations(data, pluginId),
|
|
39
|
+
locale,
|
|
40
|
+
};
|
|
41
|
+
})
|
|
42
|
+
.catch(() => {
|
|
43
|
+
return {
|
|
44
|
+
data: {},
|
|
45
|
+
locale,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return Promise.resolve(importedTrads);
|
|
52
|
+
},
|
|
49
53
|
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* This component is the skeleton around the actual pages, and should only
|
|
4
|
+
* contain code that should be seen on all pages. (e.g. navigation bar)
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { Suspense, lazy } from "react";
|
|
9
|
+
import { Switch, Route } from "react-router-dom";
|
|
10
|
+
import { NotFound, LoadingIndicatorPage } from "@strapi/helper-plugin";
|
|
11
|
+
// Utils
|
|
12
|
+
import DataManagerProvider from "../DataManagerProvider";
|
|
13
|
+
import pluginId from "../../pluginId";
|
|
14
|
+
// Containers
|
|
15
|
+
const View = lazy(() => import("../View"));
|
|
16
|
+
|
|
17
|
+
const App = () => {
|
|
18
|
+
return (
|
|
19
|
+
<DataManagerProvider>
|
|
20
|
+
<Suspense fallback={<LoadingIndicatorPage />}>
|
|
21
|
+
<Switch>
|
|
22
|
+
<Route path={`/plugins/${pluginId}`} component={View} exact />
|
|
23
|
+
<Route component={NotFound} />
|
|
24
|
+
</Switch>
|
|
25
|
+
</Suspense>
|
|
26
|
+
</DataManagerProvider>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default App;
|
|
31
|
+
|
|
File without changes
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import React, { memo, useEffect, useReducer, useRef } from "react";
|
|
2
|
+
import { useLocation, useRouteMatch } from "react-router-dom";
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
2
4
|
import PropTypes from "prop-types";
|
|
3
5
|
import { get, find, first, isEmpty } from "lodash";
|
|
4
6
|
import {
|
|
5
7
|
request,
|
|
6
8
|
LoadingIndicatorPage,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
useNotification,
|
|
10
|
+
useAppInfos,
|
|
11
|
+
} from "@strapi/helper-plugin";
|
|
10
12
|
import DataManagerContext from "../../contexts/DataManagerContext";
|
|
11
13
|
import getTrad from "../../utils/getTrad";
|
|
12
14
|
import pluginId from "../../pluginId";
|
|
@@ -30,16 +32,13 @@ import {
|
|
|
30
32
|
SUBMIT_NAVIGATION_ERROR,
|
|
31
33
|
} from './actions';
|
|
32
34
|
import { prepareItemToViewPayload } from '../View/utils/parsers';
|
|
33
|
-
import { getTradId } from "../../translations";
|
|
34
35
|
|
|
35
36
|
const DataManagerProvider = ({ children }) => {
|
|
36
37
|
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
formatMessage,
|
|
42
|
-
} = useGlobalContext();
|
|
38
|
+
const toggleNotification = useNotification();
|
|
39
|
+
const { autoReload } = useAppInfos();
|
|
40
|
+
const { formatMessage } = useIntl();
|
|
41
|
+
|
|
43
42
|
const {
|
|
44
43
|
items,
|
|
45
44
|
config,
|
|
@@ -54,9 +53,8 @@ const DataManagerProvider = ({ children }) => {
|
|
|
54
53
|
isLoadingForAdditionalDataToBeSet,
|
|
55
54
|
isLoadingForSubmit,
|
|
56
55
|
error
|
|
57
|
-
} = reducerState
|
|
56
|
+
} = reducerState;
|
|
58
57
|
const { pathname } = useLocation();
|
|
59
|
-
|
|
60
58
|
const formatMessageRef = useRef();
|
|
61
59
|
formatMessageRef.current = formatMessage;
|
|
62
60
|
|
|
@@ -64,8 +62,7 @@ const DataManagerProvider = ({ children }) => {
|
|
|
64
62
|
getLayoutSettingRef.current = (settingName) =>
|
|
65
63
|
get({}, ["settings", settingName], "");
|
|
66
64
|
|
|
67
|
-
const isInDevelopmentMode =
|
|
68
|
-
currentEnvironment === "development" && autoReload;
|
|
65
|
+
const isInDevelopmentMode = autoReload;
|
|
69
66
|
|
|
70
67
|
const abortController = new AbortController();
|
|
71
68
|
const { signal } = abortController;
|
|
@@ -95,9 +92,11 @@ const DataManagerProvider = ({ children }) => {
|
|
|
95
92
|
});
|
|
96
93
|
}
|
|
97
94
|
} catch (err) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
console.error({ err });
|
|
96
|
+
toggleNotification({
|
|
97
|
+
type: 'error',
|
|
98
|
+
message: { id: 'notification.error' },
|
|
99
|
+
});
|
|
101
100
|
}
|
|
102
101
|
};
|
|
103
102
|
|
|
@@ -110,7 +109,6 @@ const DataManagerProvider = ({ children }) => {
|
|
|
110
109
|
method: "GET",
|
|
111
110
|
signal,
|
|
112
111
|
});
|
|
113
|
-
|
|
114
112
|
dispatch({
|
|
115
113
|
type: GET_CONFIG_SUCCEEDED,
|
|
116
114
|
config,
|
|
@@ -134,7 +132,10 @@ const DataManagerProvider = ({ children }) => {
|
|
|
134
132
|
}
|
|
135
133
|
} catch (err) {
|
|
136
134
|
console.error({ err });
|
|
137
|
-
|
|
135
|
+
toggleNotification({
|
|
136
|
+
type: 'error',
|
|
137
|
+
message: { id: 'notification.error' },
|
|
138
|
+
});
|
|
138
139
|
}
|
|
139
140
|
};
|
|
140
141
|
|
|
@@ -152,21 +153,19 @@ const DataManagerProvider = ({ children }) => {
|
|
|
152
153
|
}, [isLoading, pathname]);
|
|
153
154
|
|
|
154
155
|
useEffect(() => {
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
);
|
|
156
|
+
if (!autoReload) {
|
|
157
|
+
toggleNotification({
|
|
158
|
+
type: 'info',
|
|
159
|
+
message: { id: getTrad('notification.info.autoreaload-disable') },
|
|
160
|
+
});
|
|
161
161
|
}
|
|
162
|
-
}, [autoReload
|
|
162
|
+
}, [autoReload]);
|
|
163
163
|
|
|
164
|
-
const getContentTypeItems = async ({
|
|
164
|
+
const getContentTypeItems = async ({ modelUID, query }) => {
|
|
165
165
|
dispatch({
|
|
166
166
|
type: GET_CONTENT_TYPE_ITEMS,
|
|
167
167
|
});
|
|
168
|
-
const url
|
|
169
|
-
|
|
168
|
+
const url =`/navigation/content-type-items/${modelUID}`;
|
|
170
169
|
const queryParams = new URLSearchParams();
|
|
171
170
|
queryParams.append('_publicationState', 'preview');
|
|
172
171
|
if (query) {
|
|
@@ -178,14 +177,13 @@ const DataManagerProvider = ({ children }) => {
|
|
|
178
177
|
signal,
|
|
179
178
|
});
|
|
180
179
|
|
|
181
|
-
const fetchedContentType = find(config.contentTypes, ct => ct.
|
|
182
|
-
|
|
180
|
+
const fetchedContentType = find(config.contentTypes, ct => ct.uid === modelUID);
|
|
183
181
|
const isArray = Array.isArray(contentTypeItems);
|
|
184
182
|
dispatch({
|
|
185
183
|
type: GET_CONTENT_TYPE_ITEMS_SUCCEEDED,
|
|
186
184
|
contentTypeItems: (isArray ? contentTypeItems : [contentTypeItems]).map(item => ({
|
|
187
185
|
...item,
|
|
188
|
-
|
|
186
|
+
__collectionUid: get(fetchedContentType, 'collectionUid', modelUID),
|
|
189
187
|
})),
|
|
190
188
|
});
|
|
191
189
|
};
|
|
@@ -195,86 +193,81 @@ const DataManagerProvider = ({ children }) => {
|
|
|
195
193
|
};
|
|
196
194
|
|
|
197
195
|
const handleChangeNavigationPopupVisibility = (visible) => {
|
|
198
|
-
emitEvent("willChangeNavigationPopupVisibility");
|
|
199
196
|
dispatch({
|
|
200
197
|
type: CHANGE_NAVIGATION_POPUP_VISIBILITY,
|
|
201
198
|
navigationPopupOpened: visible,
|
|
202
199
|
});
|
|
203
|
-
emitEvent("didChangeNavigationPopupVisibility");
|
|
204
|
-
emitEvent(`navigationPopup${visible ? "Visible" : "Hidden"}`);
|
|
205
200
|
};
|
|
206
201
|
|
|
207
202
|
const handleChangeNavigationItemPopupVisibility = (visible) => {
|
|
208
|
-
emitEvent("willChangeNavigationItemPopupVisibility");
|
|
209
203
|
dispatch({
|
|
210
204
|
type: CHANGE_NAVIGATION_ITEM_POPUP_VISIBILITY,
|
|
211
205
|
navigationItemPopupOpened: visible,
|
|
212
206
|
});
|
|
213
|
-
emitEvent("didChangeNavigationItemPopupVisibility");
|
|
214
|
-
emitEvent(`navigationItemPopup${visible ? "Visible" : "Hidden"}`);
|
|
215
207
|
};
|
|
216
208
|
|
|
217
209
|
const handleChangeNavigationData = (payload, forceClosePopups) => {
|
|
218
|
-
emitEvent("willChangeNavigationData");
|
|
219
210
|
dispatch({
|
|
220
211
|
type: CHANGE_NAVIGATION_DATA,
|
|
221
212
|
changedActiveItem: payload,
|
|
222
213
|
forceClosePopups,
|
|
223
214
|
});
|
|
224
|
-
emitEvent("didChangeNavigationData");
|
|
225
215
|
};
|
|
226
216
|
|
|
227
217
|
const handleResetNavigationData = () => {
|
|
228
|
-
|
|
229
|
-
dispatch({
|
|
218
|
+
dispatch({
|
|
230
219
|
type: RESET_NAVIGATION_DATA,
|
|
231
220
|
activeItem,
|
|
232
221
|
});
|
|
233
|
-
emitEvent("didResetNavigationChanges");
|
|
234
222
|
};
|
|
235
223
|
|
|
236
224
|
const handleSubmitNavigation = async (formatMessage, payload = {}) => {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
225
|
+
try {
|
|
226
|
+
dispatch({
|
|
227
|
+
type: SUBMIT_NAVIGATION,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
const nagivationId = payload.id ? `/${payload.id}` : "";
|
|
231
|
+
const method = payload.id ? "PUT" : "POST";
|
|
232
|
+
const navigation = await request(`/${pluginId}${nagivationId}`, {
|
|
233
|
+
method,
|
|
234
|
+
signal,
|
|
235
|
+
body: payload,
|
|
236
|
+
});
|
|
237
|
+
dispatch({
|
|
238
|
+
type: SUBMIT_NAVIGATION_SUCCEEDED,
|
|
239
|
+
navigation: {
|
|
240
|
+
...navigation,
|
|
241
|
+
items: prepareItemToViewPayload(navigation.items, null, config),
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
toggleNotification({
|
|
245
|
+
type: 'success',
|
|
246
|
+
message: { id: getTrad('notification.navigation.submit') },
|
|
247
|
+
});
|
|
248
|
+
} catch (err) {
|
|
249
|
+
dispatch({
|
|
250
|
+
type: SUBMIT_NAVIGATION_ERROR,
|
|
251
|
+
error: err.response.payload.data
|
|
252
|
+
});
|
|
253
|
+
console.error({ err: err.response });
|
|
254
|
+
|
|
255
|
+
if (err.response.payload.data && err.response.payload.data.errorTitles) {
|
|
256
|
+
return toggleNotification({
|
|
257
|
+
type: 'error',
|
|
258
|
+
message: {
|
|
259
|
+
id: formatMessage(
|
|
260
|
+
getTrad('notification.navigation.error'),
|
|
261
|
+
{ ...err.response.payload.data, errorTitles: err.response.payload.data.errorTitles.join(' and ') },
|
|
262
|
+
)
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
toggleNotification({
|
|
267
|
+
type: 'error',
|
|
268
|
+
message: { id: getTrad('notification.error') },
|
|
269
|
+
});
|
|
270
|
+
}
|
|
278
271
|
};
|
|
279
272
|
|
|
280
273
|
return (
|
|
File without changes
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import produce from 'immer';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
GET_LIST_DATA,
|
|
5
|
+
GET_LIST_DATA_SUCCEEDED,
|
|
6
|
+
GET_NAVIGATION_DATA,
|
|
7
|
+
GET_NAVIGATION_DATA_SUCCEEDED,
|
|
8
|
+
RELOAD_PLUGIN,
|
|
9
|
+
RESET_NAVIGATION_DATA,
|
|
10
|
+
CHANGE_NAVIGATION_POPUP_VISIBILITY,
|
|
11
|
+
CHANGE_NAVIGATION_ITEM_POPUP_VISIBILITY,
|
|
12
|
+
CHANGE_NAVIGATION_DATA,
|
|
13
|
+
GET_CONFIG,
|
|
14
|
+
GET_CONFIG_SUCCEEDED,
|
|
15
|
+
GET_CONTENT_TYPE_ITEMS,
|
|
16
|
+
GET_CONTENT_TYPE_ITEMS_SUCCEEDED,
|
|
17
|
+
SUBMIT_NAVIGATION_SUCCEEDED,
|
|
18
|
+
SUBMIT_NAVIGATION,
|
|
19
|
+
SUBMIT_NAVIGATION_ERROR,
|
|
20
|
+
} from './actions';
|
|
21
|
+
|
|
22
|
+
const initialState = {
|
|
23
|
+
items: [],
|
|
24
|
+
activeItem: undefined,
|
|
25
|
+
changedActiveItem: undefined,
|
|
26
|
+
navigationPopupOpened: false,
|
|
27
|
+
navigationItemPopupOpened: false,
|
|
28
|
+
config: {},
|
|
29
|
+
isLoading: true,
|
|
30
|
+
isLoadingForDataToBeSet: false,
|
|
31
|
+
isLoadingForDetailsDataToBeSet: false,
|
|
32
|
+
isLoadingForAdditionalDataToBeSet: false,
|
|
33
|
+
isLoadingForSubmit: false,
|
|
34
|
+
error: undefined,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const reducer = (state, action) => produce(state, draftState => {
|
|
38
|
+
switch (action.type) {
|
|
39
|
+
case GET_CONFIG: {
|
|
40
|
+
draftState.isLoadingForDetailsDataToBeSet = true;
|
|
41
|
+
draftState.config = {};
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
case GET_CONFIG_SUCCEEDED: {
|
|
45
|
+
draftState.isLoadingForDetailsDataToBeSet = false;
|
|
46
|
+
draftState.config = action.config;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case GET_LIST_DATA: {
|
|
50
|
+
draftState.items = [];
|
|
51
|
+
draftState.isLoadingForDataToBeSet = true;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case GET_LIST_DATA_SUCCEEDED: {
|
|
55
|
+
draftState.items = action.items;
|
|
56
|
+
draftState.isLoading = false;
|
|
57
|
+
draftState.isLoadingForDataToBeSet = false;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case GET_NAVIGATION_DATA: {
|
|
61
|
+
draftState.activeItem = undefined;
|
|
62
|
+
draftState.changedActiveItem = undefined;
|
|
63
|
+
draftState.isLoadingForDetailsDataToBeSet = true;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case GET_NAVIGATION_DATA_SUCCEEDED: {
|
|
67
|
+
const activeItem = action.activeItem || {};
|
|
68
|
+
draftState.activeItem = activeItem;
|
|
69
|
+
draftState.changedActiveItem = activeItem;
|
|
70
|
+
draftState.isLoadingForDetailsDataToBeSet = false;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case CHANGE_NAVIGATION_DATA: {
|
|
74
|
+
draftState.changedActiveItem = action.changedActiveItem;
|
|
75
|
+
draftState.navigationPopupOpened = action.forceClosePopups ? false : state.navigationPopupOpened;
|
|
76
|
+
draftState.navigationItemPopupOpened = action.forceClosePopups ? false : state.navigationItemPopupOpened;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case RESET_NAVIGATION_DATA : {
|
|
80
|
+
draftState.changedActiveItem = action.activeItem || {};
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case GET_CONTENT_TYPE_ITEMS: {
|
|
84
|
+
draftState.isLoadingForAdditionalDataToBeSet = true;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case GET_CONTENT_TYPE_ITEMS_SUCCEEDED: {
|
|
88
|
+
draftState.isLoadingForAdditionalDataToBeSet = false;
|
|
89
|
+
draftState.config.contentTypeItems = action.contentTypeItems;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
case CHANGE_NAVIGATION_POPUP_VISIBILITY: {
|
|
93
|
+
draftState.navigationPopupOpened = action.navigationPopupOpened;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case CHANGE_NAVIGATION_ITEM_POPUP_VISIBILITY: {
|
|
97
|
+
draftState.navigationItemPopupOpened = action.navigationItemPopupOpened;
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
case SUBMIT_NAVIGATION: {
|
|
101
|
+
draftState.isLoadingForSubmit = true;
|
|
102
|
+
draftState.error = undefined;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case SUBMIT_NAVIGATION_SUCCEEDED: {
|
|
106
|
+
draftState.activeItem = action.navigation || {};
|
|
107
|
+
draftState.changedActiveItem = action.navigation || {};
|
|
108
|
+
draftState.isLoadingForSubmit = false;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
case SUBMIT_NAVIGATION_ERROR: {
|
|
112
|
+
draftState.isLoadingForSubmit = false;
|
|
113
|
+
draftState.error = action.error;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case RELOAD_PLUGIN: {
|
|
117
|
+
return initialState;
|
|
118
|
+
}
|
|
119
|
+
default:
|
|
120
|
+
return draftState;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
export default reducer;
|
|
125
|
+
export { initialState };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { Flex } from '@strapi/design-system/Flex';
|
|
4
|
+
|
|
5
|
+
const NavigationContentHeader = ({ startActions, endActions }) => {
|
|
6
|
+
return (
|
|
7
|
+
<Flex justifyContent="space-between" width="100%">
|
|
8
|
+
<Flex alignItems="space-between">
|
|
9
|
+
{startActions}
|
|
10
|
+
</Flex>
|
|
11
|
+
<Flex alignItems="space-between">
|
|
12
|
+
{endActions}
|
|
13
|
+
</Flex>
|
|
14
|
+
</Flex>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default NavigationContentHeader;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import { HeaderLayout } from '@strapi/design-system/Layout';
|
|
4
|
+
import { Stack } from '@strapi/design-system/Stack';
|
|
5
|
+
import { Button } from '@strapi/design-system/Button';
|
|
6
|
+
import { IconButton } from '@strapi/design-system/IconButton';
|
|
7
|
+
import Check from '@strapi/icons/Check';
|
|
8
|
+
import More from '@strapi/icons/More';
|
|
9
|
+
import Plus from '@strapi/icons/Plus';
|
|
10
|
+
import styled from 'styled-components';
|
|
11
|
+
import { getTrad } from '../../../../translations';
|
|
12
|
+
import { transformToRESTPayload } from '../../utils/parsers';
|
|
13
|
+
const MoreButton = styled(IconButton)`
|
|
14
|
+
margin: ${({ theme }) => `0 ${theme.spaces[2]}`};
|
|
15
|
+
padding: ${({ theme }) => theme.spaces[2]};
|
|
16
|
+
|
|
17
|
+
svg {
|
|
18
|
+
width: ${18 / 16}rem;
|
|
19
|
+
height: ${18 / 16}rem;
|
|
20
|
+
}
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const NavigationHeader = ({
|
|
24
|
+
structureHasErrors,
|
|
25
|
+
handleSave,
|
|
26
|
+
}) => {
|
|
27
|
+
const { formatMessage } = useIntl();
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<HeaderLayout
|
|
31
|
+
primaryAction={
|
|
32
|
+
<Stack horizontal size={2}>
|
|
33
|
+
<Button
|
|
34
|
+
onClick={handleSave}
|
|
35
|
+
startIcon={<Check />}
|
|
36
|
+
disabled={structureHasErrors}
|
|
37
|
+
type="submit"
|
|
38
|
+
>
|
|
39
|
+
{formatMessage(getTrad('submit.cta.save'))}
|
|
40
|
+
</Button>
|
|
41
|
+
<MoreButton
|
|
42
|
+
id="more"
|
|
43
|
+
label="More"
|
|
44
|
+
icon={<More />}
|
|
45
|
+
/>
|
|
46
|
+
</Stack>
|
|
47
|
+
}
|
|
48
|
+
title={formatMessage({
|
|
49
|
+
id: getTrad('header.title'),
|
|
50
|
+
defaultMessage: 'UI Navigation',
|
|
51
|
+
})}
|
|
52
|
+
subtitle={formatMessage({
|
|
53
|
+
id: getTrad('header.description'),
|
|
54
|
+
defaultMessage: 'Define your portal navigation',
|
|
55
|
+
})}
|
|
56
|
+
/>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default NavigationHeader;
|