@strapi/admin 4.2.0-beta.4 → 4.2.0
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/admin/src/app.js +4 -7
- package/admin/src/hooks/useFetchMarketplaceProviders/index.js +23 -0
- package/admin/src/hooks/useFetchMarketplaceProviders/utils/api.js +11 -0
- package/admin/src/pages/Admin/index.js +5 -15
- package/admin/src/pages/App/index.js +3 -17
- package/admin/src/pages/MarketplacePage/components/{EmptyPluginSearch/EmptyPluginGrid.js → EmptyNpmPackageSearch/EmptyNpmPackageGrid.js} +1 -1
- package/admin/src/pages/MarketplacePage/components/{EmptyPluginSearch → EmptyNpmPackageSearch}/index.js +6 -4
- package/admin/src/pages/MarketplacePage/components/{PluginCard → NpmPackageCard}/InstallPluginButton.js +0 -0
- package/admin/src/pages/MarketplacePage/components/{PluginCard → NpmPackageCard}/index.js +22 -10
- package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +42 -0
- package/admin/src/pages/MarketplacePage/components/PageHeader/index.js +12 -5
- package/admin/src/pages/MarketplacePage/index.js +99 -37
- package/admin/src/reducers.js +2 -4
- package/admin/src/translations/en.json +7 -3
- package/admin/src/translations/pl.json +264 -12
- package/admin/src/translations/vi.json +17 -17
- package/build/1856.6a94980b.chunk.js +172 -0
- package/build/2077.5456ccd1.chunk.js +194 -0
- package/build/2758.9475712b.chunk.js +162 -0
- package/build/2912.dd031292.chunk.js +253 -0
- package/build/4715.4588fdf5.chunk.js +385 -0
- package/build/4982.c57c5675.chunk.js +308 -0
- package/build/7197.ed8d6752.chunk.js +113 -0
- package/build/{6229.a5cca9f2.chunk.js → 7589.577cf729.chunk.js} +2 -2
- package/build/{472.0350a5bd.chunk.js → 7757.f6eb5e92.chunk.js} +58 -58
- package/build/7841.9e9cf739.chunk.js +253 -0
- package/build/8681.aec05472.chunk.js +163 -0
- package/build/9066.2847fdff.chunk.js +101 -0
- package/build/{4073.e144a91a.chunk.js → 9115.abdf4e3b.chunk.js} +1 -1
- package/build/9158.e48d88af.chunk.js +503 -0
- package/build/{9298.aff28744.chunk.js → 9298.cb3b6bc1.chunk.js} +93 -93
- package/build/9420.ba035f29.chunk.js +508 -0
- package/build/Admin-authenticatedApp.e7ed0550.chunk.js +80 -0
- package/build/{Admin_homePage.0ac648e8.chunk.js → Admin_homePage.8c00145e.chunk.js} +1 -1
- package/build/Admin_marketplace.a88d5bda.chunk.js +11 -0
- package/build/Admin_pluginsPage.e895d79f.chunk.js +1 -0
- package/build/{Admin_profilePage.27191ed2.chunk.js → Admin_profilePage.33cfed9b.chunk.js} +2 -2
- package/build/Admin_settingsPage.fe33e0a2.chunk.js +180 -0
- package/build/{admin-edit-roles-page.fb374555.chunk.js → admin-edit-roles-page.e77a2acc.chunk.js} +1 -1
- package/build/admin-edit-users.4c49fe98.chunk.js +11 -0
- package/build/admin-users.b89adf82.chunk.js +12 -0
- package/build/{api-tokens-create-page.698f132d.chunk.js → api-tokens-create-page.618b3e40.chunk.js} +1 -1
- package/build/{api-tokens-edit-page.afece2fe.chunk.js → api-tokens-edit-page.8d19dfe1.chunk.js} +1 -1
- package/build/{api-tokens-list-page.46d96dee.chunk.js → api-tokens-list-page.274e1c80.chunk.js} +1 -1
- package/build/{codemirror-css.b467b1de.chunk.js → codemirror-css.98490df3.chunk.js} +2 -2
- package/build/{codemirror-javacript.41bdefda.chunk.js → codemirror-javacript.cafbda9c.chunk.js} +1 -1
- package/build/codemirror-theme.b3c64617.chunk.js +34 -0
- package/build/{content-manager.7cd28f84.chunk.js → content-manager.04b93497.chunk.js} +9 -9
- package/build/content-type-builder.b3139cb1.chunk.js +141 -0
- package/build/{cropper-css.ecc0d670.chunk.js → cropper-css.0055cd53.chunk.js} +2 -2
- package/build/email-settings-page.4ae595f6.chunk.js +103 -0
- package/build/en-json.0a5ba154.chunk.js +1 -0
- package/build/{fontawesome-css-all.04f33619.chunk.js → fontawesome-css-all.b88d464e.chunk.js} +3 -3
- package/build/{fontawesome-css.477ba714.chunk.js → fontawesome-css.59dc4459.chunk.js} +2 -2
- package/build/highlight.js.9d8ef460.chunk.js +86 -0
- package/build/i18n-settings-page.bdac3c7b.chunk.js +101 -0
- package/build/index.html +1 -1
- package/build/main.3257934a.js +8404 -0
- package/build/pl-json.f65302c2.chunk.js +1 -0
- package/build/runtime~main.de49adfd.js +2 -0
- package/build/sso-settings-page.0b4d2106.chunk.js +1 -0
- package/build/upload-settings.cadfd452.chunk.js +101 -0
- package/build/upload.fbc65439.chunk.js +105 -0
- package/build/users-advanced-settings-page.646b6f29.chunk.js +101 -0
- package/build/users-email-settings-page.8b561ea3.chunk.js +1 -0
- package/build/users-providers-settings-page.82141ace.chunk.js +1 -0
- package/build/{users-roles-settings-page.988ebc3b.chunk.js → users-roles-settings-page.28bf6bdc.chunk.js} +2 -2
- package/build/vi-json.bf3424be.chunk.js +1 -0
- package/build/{webhook-edit-page.a7ae6e3b.chunk.js → webhook-edit-page.ca670f8d.chunk.js} +2 -2
- package/build/webhook-list-page.7057f1e8.chunk.js +133 -0
- package/index.js +239 -53
- package/package.json +7 -11
- package/scripts/build.js +3 -17
- package/server/controllers/admin.js +0 -15
- package/server/policies/index.js +0 -1
- package/server/routes/admin.js +0 -9
- package/server/routes/serve-admin-panel.js +1 -1
- package/webpack.config.js +5 -28
- package/admin/src/pages/App/constants.js +0 -1
- package/admin/src/pages/App/reducer.js +0 -22
- package/admin/src/tsconfig.json +0 -10
- package/build/1541.6c1c96f9.chunk.js +0 -307
- package/build/1856.521a99fd.chunk.js +0 -172
- package/build/2077.51485bfb.chunk.js +0 -194
- package/build/2912.79c2b3c8.chunk.js +0 -253
- package/build/3214.9196aeff.chunk.js +0 -235
- package/build/3865.21cec9de.chunk.js +0 -310
- package/build/4715.77e04177.chunk.js +0 -385
- package/build/4982.f53b78a4.chunk.js +0 -308
- package/build/7351.b95e65ae.chunk.js +0 -428
- package/build/7418.6db737ce.chunk.js +0 -112
- package/build/7841.f0e7d629.chunk.js +0 -253
- package/build/8826.58e236d4.chunk.js +0 -1057
- package/build/9066.118ecccd.chunk.js +0 -101
- package/build/9420.cb0b75e8.chunk.js +0 -508
- package/build/9988.f84412d9.chunk.js +0 -162
- package/build/Admin-authenticatedApp.162a5805.chunk.js +0 -80
- package/build/Admin_marketplace.0bb91ec8.chunk.js +0 -11
- package/build/Admin_pluginsPage.788fb2f6.chunk.js +0 -1
- package/build/Admin_settingsPage.23e873f0.chunk.js +0 -178
- package/build/admin-edit-users.a360deaf.chunk.js +0 -10
- package/build/admin-users.47d06d24.chunk.js +0 -11
- package/build/codemirror-theme.cf9f9eb6.chunk.js +0 -34
- package/build/content-type-builder.7456cabe.chunk.js +0 -141
- package/build/email-settings-page.f67d13b2.chunk.js +0 -103
- package/build/en-json.40ee00aa.chunk.js +0 -1
- package/build/highlight.js.3381ffc3.chunk.js +0 -86
- package/build/i18n-settings-page.6b67cb75.chunk.js +0 -101
- package/build/main.b632a0d6.js +0 -11625
- package/build/pl-json.94f05d2c.chunk.js +0 -1
- package/build/runtime~main.38d418e9.js +0 -2
- package/build/sso-settings-page.dfb0b917.chunk.js +0 -1
- package/build/upload-settings.3db55de0.chunk.js +0 -101
- package/build/upload.070c189b.chunk.js +0 -105
- package/build/users-advanced-settings-page.a23cda17.chunk.js +0 -101
- package/build/users-email-settings-page.0a096388.chunk.js +0 -1
- package/build/users-providers-settings-page.bfe7755a.chunk.js +0 -1
- package/build/vi-json.3d14e91e.chunk.js +0 -1
- package/build/webhook-list-page.83297d98.chunk.js +0 -133
- package/server/policies/isTelemetryEnabled.js +0 -16
- package/utils/create-cache-dir.js +0 -161
- package/utils/get-custom-app-config-file.js +0 -23
- package/utils/get-custom-webpack-config.js +0 -38
- package/utils/get-plugins-path.js +0 -26
- package/utils/index.js +0 -13
- package/utils/should-build-admin.js +0 -52
- package/utils/watch-admin-files.js +0 -59
package/admin/src/app.js
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useQuery } from 'react-query';
|
|
2
|
+
import { useNotification } from '@strapi/helper-plugin';
|
|
3
|
+
import { fetchMarketplacePlugins } from './utils/api';
|
|
4
|
+
|
|
5
|
+
const useFetchMarketplaceProviders = (notifyLoad) => {
|
|
6
|
+
const toggleNotification = useNotification();
|
|
7
|
+
|
|
8
|
+
return useQuery('list-marketplace-providers', () => fetchMarketplacePlugins(), {
|
|
9
|
+
onSuccess: () => {
|
|
10
|
+
if (notifyLoad) {
|
|
11
|
+
notifyLoad();
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
onError: () => {
|
|
15
|
+
toggleNotification({
|
|
16
|
+
type: 'warning',
|
|
17
|
+
message: { id: 'notification.error', defaultMessage: 'An error occured' },
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default useFetchMarketplaceProviders;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
|
|
3
|
+
const MARKETPLACE_API_URL = 'https://market-api.strapi.io';
|
|
4
|
+
|
|
5
|
+
const fetchMarketplacePlugins = async () => {
|
|
6
|
+
const { data } = await axios.get(`${MARKETPLACE_API_URL}/providers`);
|
|
7
|
+
|
|
8
|
+
return data;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { fetchMarketplacePlugins };
|
|
@@ -6,17 +6,16 @@
|
|
|
6
6
|
|
|
7
7
|
import React, { Suspense, useEffect, useMemo, lazy } from 'react';
|
|
8
8
|
import { Switch, Route } from 'react-router-dom';
|
|
9
|
+
// Components from @strapi/helper-plugin
|
|
9
10
|
import { useTracking, LoadingIndicatorPage, useStrapiApp } from '@strapi/helper-plugin';
|
|
10
|
-
import { useDispatch, useSelector } from 'react-redux';
|
|
11
11
|
import { DndProvider } from 'react-dnd';
|
|
12
12
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
13
|
-
import GuidedTourModal from '../../components/GuidedTour/Modal';
|
|
14
13
|
import LeftMenu from '../../components/LeftMenu';
|
|
15
14
|
import AppLayout from '../../layouts/AppLayout';
|
|
16
15
|
import { useMenu } from '../../hooks';
|
|
17
|
-
import { createRoute } from '../../utils';
|
|
18
|
-
import { SET_APP_RUNTIME_STATUS } from '../App/constants';
|
|
19
16
|
import Onboarding from './Onboarding';
|
|
17
|
+
import { createRoute } from '../../utils';
|
|
18
|
+
import GuidedTourModal from '../../components/GuidedTour/Modal';
|
|
20
19
|
|
|
21
20
|
const CM = lazy(() =>
|
|
22
21
|
import(/* webpackChunkName: "content-manager" */ '../../content-manager/pages/App')
|
|
@@ -41,20 +40,11 @@ const SettingsPage = lazy(() =>
|
|
|
41
40
|
// Simple hook easier for testing
|
|
42
41
|
const useTrackUsage = () => {
|
|
43
42
|
const { trackUsage } = useTracking();
|
|
44
|
-
const dispatch = useDispatch();
|
|
45
|
-
const appStatus = useSelector(state => state.admin_app.status);
|
|
46
43
|
|
|
47
44
|
useEffect(() => {
|
|
48
|
-
|
|
49
|
-
// and not at runtime for example when regenerating the permissions with the ctb
|
|
50
|
-
// or with i18n
|
|
51
|
-
if (appStatus === 'init') {
|
|
52
|
-
trackUsage('didAccessAuthenticatedAdministration');
|
|
53
|
-
|
|
54
|
-
dispatch({ type: SET_APP_RUNTIME_STATUS });
|
|
55
|
-
}
|
|
45
|
+
trackUsage('didAccessAuthenticatedAdministration');
|
|
56
46
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
-
}, [
|
|
47
|
+
}, []);
|
|
58
48
|
};
|
|
59
49
|
|
|
60
50
|
const Admin = () => {
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
TrackingContext,
|
|
15
15
|
prefixFileUrlWithBackendUrl,
|
|
16
16
|
} from '@strapi/helper-plugin';
|
|
17
|
-
import axios from 'axios';
|
|
18
17
|
import { SkipToContent } from '@strapi/design-system/Main';
|
|
19
18
|
import { useIntl } from 'react-intl';
|
|
20
19
|
import PrivateRoute from '../../components/PrivateRoute';
|
|
@@ -42,8 +41,6 @@ function App() {
|
|
|
42
41
|
);
|
|
43
42
|
}, []);
|
|
44
43
|
|
|
45
|
-
const [telemetryProperties, setTelemetryProperties] = useState(null);
|
|
46
|
-
|
|
47
44
|
useEffect(() => {
|
|
48
45
|
const currentToken = auth.getToken();
|
|
49
46
|
|
|
@@ -72,20 +69,12 @@ function App() {
|
|
|
72
69
|
const getData = async () => {
|
|
73
70
|
try {
|
|
74
71
|
const {
|
|
75
|
-
data: {
|
|
76
|
-
|
|
77
|
-
},
|
|
78
|
-
} = await axios.get(`${strapi.backendURL}/admin/init`);
|
|
72
|
+
data: { hasAdmin, uuid, menuLogo },
|
|
73
|
+
} = await request('/admin/init', { method: 'GET' });
|
|
79
74
|
|
|
80
75
|
updateProjectSettings({ menuLogo: prefixFileUrlWithBackendUrl(menuLogo) });
|
|
81
76
|
|
|
82
77
|
if (uuid) {
|
|
83
|
-
const {
|
|
84
|
-
data: { data: properties },
|
|
85
|
-
} = await axios.get(`${strapi.backendURL}/admin/telemetry-properties`);
|
|
86
|
-
|
|
87
|
-
setTelemetryProperties(properties);
|
|
88
|
-
|
|
89
78
|
try {
|
|
90
79
|
const deviceId = await getUID();
|
|
91
80
|
|
|
@@ -95,9 +84,6 @@ function App() {
|
|
|
95
84
|
event: 'didInitializeAdministration',
|
|
96
85
|
uuid,
|
|
97
86
|
deviceId,
|
|
98
|
-
properties: {
|
|
99
|
-
...properties,
|
|
100
|
-
},
|
|
101
87
|
}),
|
|
102
88
|
headers: {
|
|
103
89
|
'Content-Type': 'application/json',
|
|
@@ -129,7 +115,7 @@ function App() {
|
|
|
129
115
|
return (
|
|
130
116
|
<Suspense fallback={<LoadingIndicatorPage />}>
|
|
131
117
|
<SkipToContent>{formatMessage({ id: 'skipToContent' })}</SkipToContent>
|
|
132
|
-
<TrackingContext.Provider value={
|
|
118
|
+
<TrackingContext.Provider value={uuid}>
|
|
133
119
|
<Switch>
|
|
134
120
|
{authRoutes}
|
|
135
121
|
<Route
|
|
@@ -5,12 +5,12 @@ import { Box } from '@strapi/design-system/Box';
|
|
|
5
5
|
import { Flex } from '@strapi/design-system/Flex';
|
|
6
6
|
import { Icon } from '@strapi/design-system/Icon';
|
|
7
7
|
import EmptyStateDocument from '@strapi/icons/EmptyDocuments';
|
|
8
|
-
import {
|
|
8
|
+
import { EmptyNpmPackageGrid } from './EmptyNpmPackageGrid';
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const EmptyNpmPackageSearch = ({ content }) => {
|
|
11
11
|
return (
|
|
12
12
|
<Box position="relative">
|
|
13
|
-
<
|
|
13
|
+
<EmptyNpmPackageGrid />
|
|
14
14
|
<Box position="absolute" top={11} width="100%">
|
|
15
15
|
<Flex alignItems="center" justifyContent="center" direction="column">
|
|
16
16
|
<Icon as={EmptyStateDocument} color="" width="160px" height="88px" />
|
|
@@ -25,6 +25,8 @@ export const EmptyPluginSearch = ({ content }) => {
|
|
|
25
25
|
);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
EmptyNpmPackageSearch.propTypes = {
|
|
29
29
|
content: PropTypes.string.isRequired,
|
|
30
30
|
};
|
|
31
|
+
|
|
32
|
+
export default EmptyNpmPackageSearch;
|
|
File without changes
|
|
@@ -25,12 +25,18 @@ const EllipsisText = styled(Typography)`
|
|
|
25
25
|
overflow: hidden;
|
|
26
26
|
`;
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
|
|
28
|
+
const NpmPackageCard = ({
|
|
29
|
+
npmPackage,
|
|
30
|
+
installedPackageNames,
|
|
31
|
+
useYarn,
|
|
32
|
+
isInDevelopmentMode,
|
|
33
|
+
npmPackageType,
|
|
34
|
+
}) => {
|
|
35
|
+
const { attributes } = npmPackage;
|
|
30
36
|
const { formatMessage } = useIntl();
|
|
31
37
|
const { trackUsage } = useTracking();
|
|
32
38
|
|
|
33
|
-
const isInstalled =
|
|
39
|
+
const isInstalled = installedPackageNames.includes(attributes.npmPackageName);
|
|
34
40
|
|
|
35
41
|
const commandToCopy = useYarn
|
|
36
42
|
? `yarn add ${attributes.npmPackageName}`
|
|
@@ -41,6 +47,11 @@ const PluginCard = ({ plugin, installedPluginNames, useYarn, isInDevelopmentMode
|
|
|
41
47
|
defaultMessage: 'Made by Strapi',
|
|
42
48
|
});
|
|
43
49
|
|
|
50
|
+
const npmPackageHref =
|
|
51
|
+
npmPackageType === 'provider'
|
|
52
|
+
? attributes.npmPackageUrl
|
|
53
|
+
: `https://market.strapi.io/plugins/${attributes.slug}`;
|
|
54
|
+
|
|
44
55
|
return (
|
|
45
56
|
<Flex
|
|
46
57
|
direction="column"
|
|
@@ -107,7 +118,7 @@ const PluginCard = ({ plugin, installedPluginNames, useYarn, isInDevelopmentMode
|
|
|
107
118
|
<Stack horizontal spacing={2} style={{ alignSelf: 'flex-end' }} paddingTop={6}>
|
|
108
119
|
<LinkButton
|
|
109
120
|
size="S"
|
|
110
|
-
href={
|
|
121
|
+
href={npmPackageHref}
|
|
111
122
|
isExternal
|
|
112
123
|
endIcon={<ExternalLink />}
|
|
113
124
|
aria-label={formatMessage(
|
|
@@ -135,12 +146,12 @@ const PluginCard = ({ plugin, installedPluginNames, useYarn, isInDevelopmentMode
|
|
|
135
146
|
);
|
|
136
147
|
};
|
|
137
148
|
|
|
138
|
-
|
|
149
|
+
NpmPackageCard.defaultProps = {
|
|
139
150
|
isInDevelopmentMode: false,
|
|
140
151
|
};
|
|
141
152
|
|
|
142
|
-
|
|
143
|
-
|
|
153
|
+
NpmPackageCard.propTypes = {
|
|
154
|
+
npmPackage: PropTypes.shape({
|
|
144
155
|
id: PropTypes.string.isRequired,
|
|
145
156
|
attributes: PropTypes.shape({
|
|
146
157
|
name: PropTypes.string.isRequired,
|
|
@@ -153,12 +164,13 @@ PluginCard.propTypes = {
|
|
|
153
164
|
developerName: PropTypes.string.isRequired,
|
|
154
165
|
validated: PropTypes.bool.isRequired,
|
|
155
166
|
madeByStrapi: PropTypes.bool.isRequired,
|
|
156
|
-
strapiCompatibility: PropTypes.oneOf(['v3', 'v4'])
|
|
167
|
+
strapiCompatibility: PropTypes.oneOf(['v3', 'v4']),
|
|
157
168
|
}).isRequired,
|
|
158
169
|
}).isRequired,
|
|
159
|
-
|
|
170
|
+
installedPackageNames: PropTypes.arrayOf(PropTypes.string).isRequired,
|
|
160
171
|
useYarn: PropTypes.bool.isRequired,
|
|
161
172
|
isInDevelopmentMode: PropTypes.bool,
|
|
173
|
+
npmPackageType: PropTypes.string.isRequired,
|
|
162
174
|
};
|
|
163
175
|
|
|
164
|
-
export default
|
|
176
|
+
export default NpmPackageCard;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
|
4
|
+
import NpmPackageCard from '../NpmPackageCard';
|
|
5
|
+
|
|
6
|
+
const NpmPackagesGrid = ({
|
|
7
|
+
npmPackages,
|
|
8
|
+
installedPackageNames,
|
|
9
|
+
useYarn,
|
|
10
|
+
isInDevelopmentMode,
|
|
11
|
+
npmPackageType,
|
|
12
|
+
}) => {
|
|
13
|
+
return (
|
|
14
|
+
<Grid gap={4}>
|
|
15
|
+
{npmPackages.map((npmPackage) => (
|
|
16
|
+
<GridItem col={4} s={6} xs={12} style={{ height: '100%' }} key={npmPackage.id}>
|
|
17
|
+
<NpmPackageCard
|
|
18
|
+
npmPackage={npmPackage}
|
|
19
|
+
installedPackageNames={installedPackageNames}
|
|
20
|
+
useYarn={useYarn}
|
|
21
|
+
isInDevelopmentMode={isInDevelopmentMode}
|
|
22
|
+
npmPackageType={npmPackageType}
|
|
23
|
+
/>
|
|
24
|
+
</GridItem>
|
|
25
|
+
))}
|
|
26
|
+
</Grid>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
NpmPackagesGrid.defaultProps = {
|
|
31
|
+
installedPackageNames: [],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
NpmPackagesGrid.propTypes = {
|
|
35
|
+
npmPackages: PropTypes.array.isRequired,
|
|
36
|
+
installedPackageNames: PropTypes.arrayOf(PropTypes.string),
|
|
37
|
+
useYarn: PropTypes.bool.isRequired,
|
|
38
|
+
isInDevelopmentMode: PropTypes.bool.isRequired,
|
|
39
|
+
npmPackageType: PropTypes.string.isRequired,
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default NpmPackagesGrid;
|
|
@@ -6,10 +6,12 @@ import { LinkButton } from '@strapi/design-system/v2/LinkButton';
|
|
|
6
6
|
import Upload from '@strapi/icons/Upload';
|
|
7
7
|
import { useTracking } from '@strapi/helper-plugin';
|
|
8
8
|
|
|
9
|
-
const PageHeader = ({ isOnline }) => {
|
|
9
|
+
const PageHeader = ({ isOnline, npmPackageType }) => {
|
|
10
10
|
const { formatMessage } = useIntl();
|
|
11
11
|
const { trackUsage } = useTracking();
|
|
12
12
|
|
|
13
|
+
const tracking = npmPackageType === 'provider' ? 'didSubmitProvider' : 'didSubmitPlugin';
|
|
14
|
+
|
|
13
15
|
return (
|
|
14
16
|
<HeaderLayout
|
|
15
17
|
title={formatMessage({
|
|
@@ -25,13 +27,13 @@ const PageHeader = ({ isOnline }) => {
|
|
|
25
27
|
<LinkButton
|
|
26
28
|
startIcon={<Upload />}
|
|
27
29
|
variant="tertiary"
|
|
28
|
-
href=
|
|
29
|
-
onClick={() => trackUsage(
|
|
30
|
+
href={`https://market.strapi.io/submit-${npmPackageType}`}
|
|
31
|
+
onClick={() => trackUsage(tracking)}
|
|
30
32
|
isExternal
|
|
31
33
|
>
|
|
32
34
|
{formatMessage({
|
|
33
|
-
id:
|
|
34
|
-
defaultMessage:
|
|
35
|
+
id: `admin.pages.MarketPlacePage.submit.${npmPackageType}.link`,
|
|
36
|
+
defaultMessage: `Submit ${npmPackageType}`,
|
|
35
37
|
})}
|
|
36
38
|
</LinkButton>
|
|
37
39
|
)
|
|
@@ -42,6 +44,11 @@ const PageHeader = ({ isOnline }) => {
|
|
|
42
44
|
|
|
43
45
|
export default PageHeader;
|
|
44
46
|
|
|
47
|
+
PageHeader.defaultProps = {
|
|
48
|
+
npmPackageType: 'plugin',
|
|
49
|
+
};
|
|
50
|
+
|
|
45
51
|
PageHeader.propTypes = {
|
|
46
52
|
isOnline: PropTypes.bool.isRequired,
|
|
53
|
+
npmPackageType: PropTypes.string,
|
|
47
54
|
};
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
useNotification,
|
|
13
13
|
useAppInfos,
|
|
14
14
|
} from '@strapi/helper-plugin';
|
|
15
|
-
import { Grid, GridItem } from '@strapi/design-system/Grid';
|
|
16
15
|
import { Layout, ContentLayout } from '@strapi/design-system/Layout';
|
|
17
16
|
import { Main } from '@strapi/design-system/Main';
|
|
18
17
|
import { Searchbar } from '@strapi/design-system/Searchbar';
|
|
@@ -20,20 +19,22 @@ import { Box } from '@strapi/design-system/Box';
|
|
|
20
19
|
import { useNotifyAT } from '@strapi/design-system/LiveRegions';
|
|
21
20
|
import { Typography } from '@strapi/design-system/Typography';
|
|
22
21
|
import { Flex } from '@strapi/design-system/Flex';
|
|
22
|
+
import { Tabs, Tab, TabGroup, TabPanels, TabPanel } from '@strapi/design-system/Tabs';
|
|
23
23
|
|
|
24
|
-
import
|
|
25
|
-
import { EmptyPluginSearch } from './components/EmptyPluginSearch';
|
|
24
|
+
import EmptyNpmPackageSearch from './components/EmptyNpmPackageSearch';
|
|
26
25
|
import PageHeader from './components/PageHeader';
|
|
27
26
|
import { fetchAppInformation } from './utils/api';
|
|
28
27
|
import useFetchInstalledPlugins from '../../hooks/useFetchInstalledPlugins';
|
|
28
|
+
import useFetchMarketplaceProviders from '../../hooks/useFetchMarketplaceProviders';
|
|
29
29
|
import useFetchMarketplacePlugins from '../../hooks/useFetchMarketplacePlugins';
|
|
30
30
|
import adminPermissions from '../../permissions';
|
|
31
31
|
import offlineCloud from '../../assets/images/icon_offline-cloud.svg';
|
|
32
32
|
import useNavigatorOnLine from '../../hooks/useNavigatorOnLine';
|
|
33
33
|
import MissingPluginBanner from './components/MissingPluginBanner';
|
|
34
|
+
import NpmPackagesGrid from './components/NpmPackagesGrid';
|
|
34
35
|
|
|
35
|
-
const matchSearch = (
|
|
36
|
-
return matchSorter(
|
|
36
|
+
const matchSearch = (npmPackages, search) => {
|
|
37
|
+
return matchSorter(npmPackages, search, {
|
|
37
38
|
keys: [
|
|
38
39
|
{
|
|
39
40
|
threshold: matchSorter.rankings.WORD_STARTS_WITH,
|
|
@@ -51,6 +52,7 @@ const MarketPlacePage = () => {
|
|
|
51
52
|
const trackUsageRef = useRef(trackUsage);
|
|
52
53
|
const toggleNotification = useNotification();
|
|
53
54
|
const [searchQuery, setSearchQuery] = useState('');
|
|
55
|
+
const [npmPackageType, setNpmPackageType] = useState('plugin');
|
|
54
56
|
const { autoReload: isInDevelopmentMode } = useAppInfos();
|
|
55
57
|
const isOnline = useNavigatorOnLine();
|
|
56
58
|
|
|
@@ -78,6 +80,11 @@ const MarketPlacePage = () => {
|
|
|
78
80
|
data: marketplacePluginsResponse,
|
|
79
81
|
} = useFetchMarketplacePlugins(notifyMarketplaceLoad);
|
|
80
82
|
|
|
83
|
+
const {
|
|
84
|
+
status: marketplaceProvidersStatus,
|
|
85
|
+
data: marketplaceProvidersResponse,
|
|
86
|
+
} = useFetchMarketplaceProviders(notifyMarketplaceLoad);
|
|
87
|
+
|
|
81
88
|
const {
|
|
82
89
|
status: installedPluginsStatus,
|
|
83
90
|
data: installedPluginsResponse,
|
|
@@ -96,13 +103,19 @@ const MarketPlacePage = () => {
|
|
|
96
103
|
}
|
|
97
104
|
);
|
|
98
105
|
|
|
99
|
-
const isLoading = [
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
const isLoading = [
|
|
107
|
+
marketplacePluginsStatus,
|
|
108
|
+
marketplaceProvidersStatus,
|
|
109
|
+
installedPluginsStatus,
|
|
110
|
+
appInfoStatus,
|
|
111
|
+
].includes('loading');
|
|
102
112
|
|
|
103
|
-
const hasFailed = [
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
const hasFailed = [
|
|
114
|
+
marketplacePluginsStatus,
|
|
115
|
+
marketplaceProvidersStatus,
|
|
116
|
+
installedPluginsStatus,
|
|
117
|
+
appInfoStatus,
|
|
118
|
+
].includes('error');
|
|
106
119
|
|
|
107
120
|
useEffect(() => {
|
|
108
121
|
trackUsageRef.current('didGoToMarketplace');
|
|
@@ -179,7 +192,23 @@ const MarketPlacePage = () => {
|
|
|
179
192
|
);
|
|
180
193
|
}
|
|
181
194
|
|
|
182
|
-
|
|
195
|
+
// Search for plugins and providers that match the search query
|
|
196
|
+
const pluginSearchResults = matchSearch(marketplacePluginsResponse.data, searchQuery);
|
|
197
|
+
const providerSearchResults = matchSearch(marketplaceProvidersResponse.data, searchQuery);
|
|
198
|
+
const emptySearchMessage = formatMessage(
|
|
199
|
+
{
|
|
200
|
+
id: 'admin.pages.MarketPlacePage.search.empty',
|
|
201
|
+
defaultMessage: 'No result for "{target}"',
|
|
202
|
+
},
|
|
203
|
+
{ target: searchQuery }
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const handleTabChange = selected => {
|
|
207
|
+
const packageType = selected === 0 ? 'plugin' : 'provider';
|
|
208
|
+
setNpmPackageType(packageType);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// Check if plugins are installed already
|
|
183
212
|
const installedPluginNames = installedPluginsResponse.plugins.map(plugin => plugin.packageName);
|
|
184
213
|
|
|
185
214
|
return (
|
|
@@ -191,7 +220,7 @@ const MarketPlacePage = () => {
|
|
|
191
220
|
defaultMessage: 'Marketplace - Plugins',
|
|
192
221
|
})}
|
|
193
222
|
/>
|
|
194
|
-
<PageHeader isOnline={isOnline} />
|
|
223
|
+
<PageHeader isOnline={isOnline} npmPackageType={npmPackageType} />
|
|
195
224
|
<ContentLayout>
|
|
196
225
|
<Box width="25%" paddingBottom={4}>
|
|
197
226
|
<Searchbar
|
|
@@ -201,43 +230,76 @@ const MarketPlacePage = () => {
|
|
|
201
230
|
onChange={e => setSearchQuery(e.target.value)}
|
|
202
231
|
clearLabel={formatMessage({
|
|
203
232
|
id: 'admin.pages.MarketPlacePage.search.clear',
|
|
204
|
-
defaultMessage: 'Clear the
|
|
233
|
+
defaultMessage: 'Clear the search',
|
|
205
234
|
})}
|
|
206
235
|
placeholder={formatMessage({
|
|
207
236
|
id: 'admin.pages.MarketPlacePage.search.placeholder',
|
|
208
|
-
defaultMessage: 'Search
|
|
237
|
+
defaultMessage: 'Search',
|
|
209
238
|
})}
|
|
210
239
|
>
|
|
211
240
|
{formatMessage({
|
|
212
241
|
id: 'admin.pages.MarketPlacePage.search.placeholder',
|
|
213
|
-
defaultMessage: 'Search
|
|
242
|
+
defaultMessage: 'Search',
|
|
214
243
|
})}
|
|
215
244
|
</Searchbar>
|
|
216
245
|
</Box>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
246
|
+
<TabGroup
|
|
247
|
+
label={formatMessage({
|
|
248
|
+
id: 'admin.pages.MarketPlacePage.tab-group.label',
|
|
249
|
+
defaultMessage: 'Plugins and Providers for Strapi',
|
|
250
|
+
})}
|
|
251
|
+
id="tabs"
|
|
252
|
+
variant="simple"
|
|
253
|
+
onTabChange={handleTabChange}
|
|
254
|
+
>
|
|
255
|
+
<Box paddingBottom={4}>
|
|
256
|
+
<Tabs>
|
|
257
|
+
<Tab>
|
|
258
|
+
{formatMessage({
|
|
259
|
+
id: 'admin.pages.MarketPlacePage.plugins',
|
|
260
|
+
defaultMessage: 'Plugins',
|
|
261
|
+
})}{' '}
|
|
262
|
+
({pluginSearchResults.length})
|
|
263
|
+
</Tab>
|
|
264
|
+
<Tab>
|
|
265
|
+
{formatMessage({
|
|
266
|
+
id: 'admin.pages.MarketPlacePage.providers',
|
|
267
|
+
defaultMessage: 'Providers',
|
|
268
|
+
})}{' '}
|
|
269
|
+
({providerSearchResults.length})
|
|
270
|
+
</Tab>
|
|
271
|
+
</Tabs>
|
|
272
|
+
</Box>
|
|
273
|
+
<TabPanels>
|
|
274
|
+
{/* Plugins panel */}
|
|
275
|
+
<TabPanel>
|
|
276
|
+
{searchQuery.length > 0 && !pluginSearchResults.length ? (
|
|
277
|
+
<EmptyNpmPackageSearch content={emptySearchMessage} />
|
|
278
|
+
) : (
|
|
279
|
+
<NpmPackagesGrid
|
|
280
|
+
npmPackages={pluginSearchResults}
|
|
281
|
+
installedPackageNames={installedPluginNames}
|
|
282
|
+
useYarn={appInfoResponse.data.useYarn}
|
|
283
|
+
isInDevelopmentMode={isInDevelopmentMode}
|
|
284
|
+
npmPackageType="plugin"
|
|
285
|
+
/>
|
|
286
|
+
)}
|
|
287
|
+
</TabPanel>
|
|
288
|
+
{/* Providers panel */}
|
|
289
|
+
<TabPanel>
|
|
290
|
+
{searchQuery.length > 0 && !providerSearchResults.length ? (
|
|
291
|
+
<EmptyNpmPackageSearch content={emptySearchMessage} />
|
|
292
|
+
) : (
|
|
293
|
+
<NpmPackagesGrid
|
|
294
|
+
npmPackages={providerSearchResults}
|
|
234
295
|
useYarn={appInfoResponse.data.useYarn}
|
|
235
296
|
isInDevelopmentMode={isInDevelopmentMode}
|
|
297
|
+
npmPackageType="provider"
|
|
236
298
|
/>
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
</
|
|
240
|
-
|
|
299
|
+
)}
|
|
300
|
+
</TabPanel>
|
|
301
|
+
</TabPanels>
|
|
302
|
+
</TabGroup>
|
|
241
303
|
<Box paddingTop={7}>
|
|
242
304
|
<MissingPluginBanner />
|
|
243
305
|
</Box>
|
package/admin/src/reducers.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import appReducer from './pages/App/reducer';
|
|
2
1
|
import rbacProviderReducer from './components/RBACProvider/reducer';
|
|
3
|
-
import
|
|
2
|
+
import appReducer from './content-manager/pages/App/reducer';
|
|
4
3
|
import editViewLayoutManagerReducer from './content-manager/pages/EditViewLayoutManager/reducer';
|
|
5
4
|
import listViewReducer from './content-manager/pages/ListView/reducer';
|
|
6
5
|
import rbacManagerReducer from './content-manager/hooks/useSyncRbac/reducer';
|
|
7
6
|
import editViewCrudReducer from './content-manager/sharedReducers/crudReducer/reducer';
|
|
8
7
|
|
|
9
8
|
const contentManagerReducers = {
|
|
10
|
-
'content-manager_app':
|
|
9
|
+
'content-manager_app': appReducer,
|
|
11
10
|
'content-manager_listView': listViewReducer,
|
|
12
11
|
'content-manager_rbacManager': rbacManagerReducer,
|
|
13
12
|
'content-manager_editViewLayoutManager': editViewLayoutManagerReducer,
|
|
@@ -15,7 +14,6 @@ const contentManagerReducers = {
|
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
const reducers = {
|
|
18
|
-
admin_app: appReducer,
|
|
19
17
|
rbacProvider: rbacProviderReducer,
|
|
20
18
|
...contentManagerReducers,
|
|
21
19
|
};
|
|
@@ -232,6 +232,7 @@
|
|
|
232
232
|
"admin.pages.MarketPlacePage.helmet": "Marketplace - Plugins",
|
|
233
233
|
"admin.pages.MarketPlacePage.offline.title": "You are offline",
|
|
234
234
|
"admin.pages.MarketPlacePage.offline.subtitle": "You need to be connected to the Internet to access Strapi Market.",
|
|
235
|
+
"admin.pages.MarketPlacePage.plugins": "Plugins",
|
|
235
236
|
"admin.pages.MarketPlacePage.plugin.copy": "Copy install command",
|
|
236
237
|
"admin.pages.MarketPlacePage.plugin.copy.success": "Install command ready to be pasted in your terminal",
|
|
237
238
|
"admin.pages.MarketPlacePage.plugin.info": "Learn more",
|
|
@@ -240,11 +241,14 @@
|
|
|
240
241
|
"admin.pages.MarketPlacePage.plugin.installed": "Installed",
|
|
241
242
|
"admin.pages.MarketPlacePage.plugin.tooltip.madeByStrapi": "Made by Strapi",
|
|
242
243
|
"admin.pages.MarketPlacePage.plugin.tooltip.verified": "Plugin verified by Strapi",
|
|
243
|
-
"admin.pages.MarketPlacePage.
|
|
244
|
+
"admin.pages.MarketPlacePage.providers": "Providers",
|
|
245
|
+
"admin.pages.MarketPlacePage.search.clear": "Clear the search",
|
|
244
246
|
"admin.pages.MarketPlacePage.search.empty": "No result for \"{target}\"",
|
|
245
|
-
"admin.pages.MarketPlacePage.search.placeholder": "Search
|
|
246
|
-
"admin.pages.MarketPlacePage.submit.plugin.link": "Submit
|
|
247
|
+
"admin.pages.MarketPlacePage.search.placeholder": "Search",
|
|
248
|
+
"admin.pages.MarketPlacePage.submit.plugin.link": "Submit plugin",
|
|
249
|
+
"admin.pages.MarketPlacePage.submit.provider.link": "Submit provider",
|
|
247
250
|
"admin.pages.MarketPlacePage.subtitle": "Get more out of Strapi",
|
|
251
|
+
"admin.pages.MarketPlacePage.tab-group.label": "Plugins and Providers for Strapi",
|
|
248
252
|
"admin.pages.MarketPlacePage.missingPlugin.title": "Missing a plugin?",
|
|
249
253
|
"admin.pages.MarketPlacePage.missingPlugin.description": "Tell us what plugin you are looking for and we'll let our community plugin developers know in case they are in search for inspiration!",
|
|
250
254
|
"anErrorOccurred": "Woops! Something went wrong. Please, try again.",
|