@strapi/admin 4.2.0-beta.2 → 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/assets/images/homepage-logo.png +0 -0
- package/admin/src/components/AutoReloadOverlayBlockerProvider/Blocker.js +2 -6
- package/admin/src/components/ConfigurationsProvider/index.js +51 -0
- package/admin/src/components/ConfigurationsProvider/reducer.js +28 -0
- package/admin/src/components/GuidedTour/Homepage/index.js +1 -2
- package/admin/src/components/GuidedTour/Modal/components/Stepper.js +1 -2
- package/admin/src/components/LeftMenu/index.js +19 -7
- package/admin/src/components/Notifications/Notification/index.js +2 -2
- package/admin/src/components/Providers/index.js +8 -4
- package/admin/src/components/UnauthenticatedLogo/index.js +4 -2
- package/admin/src/components/UpgradePlanModal/index.js +6 -2
- package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker/Category/ComponentCard/index.js +1 -1
- package/admin/src/content-manager/components/SelectMany/ListItem.js +1 -2
- package/admin/src/content-manager/components/SelectWrapper/index.js +8 -7
- package/admin/src/content-manager/components/SelectWrapper/utils/getSelectStyles.js +1 -1
- package/admin/src/content-manager/components/SingleTypeFormWrapper/index.js +2 -2
- package/admin/src/content-manager/components/Wysiwyg/Editor.js +2 -0
- package/admin/src/content-manager/pages/App/LeftMenu/index.js +8 -7
- package/admin/src/content-manager/pages/EditSettingsView/components/ComponentFieldList.js +1 -1
- package/admin/src/content-manager/pages/EditSettingsView/components/LinkToCTB.js +1 -2
- package/admin/src/content-manager/pages/EditSettingsView/index.js +1 -2
- package/admin/src/content-manager/pages/EditView/Header/index.js +3 -3
- package/admin/src/content-manager/pages/EditView/index.js +1 -4
- package/admin/src/content-manager/pages/ListSettingsView/index.js +1 -2
- package/admin/src/content-manager/pages/ListView/index.js +1 -1
- package/admin/src/content-manager/pages/NoContentType/index.js +1 -2
- 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 +9 -18
- package/admin/src/pages/AuthPage/components/ForgotPassword/index.js +1 -2
- package/admin/src/pages/AuthPage/components/ForgotPasswordSuccess/index.js +1 -1
- package/admin/src/pages/AuthPage/components/Login/BaseLogin.js +1 -2
- package/admin/src/pages/AuthPage/components/Oops/index.js +1 -2
- package/admin/src/pages/AuthPage/components/Register/index.js +12 -12
- package/admin/src/pages/AuthPage/components/ResetPassword/index.js +3 -4
- package/admin/src/pages/HomePage/ContentBlocks.js +15 -2
- package/admin/src/pages/HomePage/HomeHeader.js +2 -2
- package/admin/src/pages/HomePage/SocialLinks.js +4 -3
- package/admin/src/pages/InternalErrorPage/index.js +1 -2
- 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 +26 -13
- package/admin/src/pages/MarketplacePage/components/NpmPackagesGrid/index.js +42 -0
- package/admin/src/pages/MarketplacePage/components/PageHeader/index.js +14 -6
- package/admin/src/pages/MarketplacePage/index.js +99 -37
- package/admin/src/pages/NotFoundPage/index.js +1 -2
- package/admin/src/pages/SettingsPage/components/SettingsNav/index.js +5 -4
- package/admin/src/pages/SettingsPage/pages/ApiTokens/EditView/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/DynamicTable/UpdateButton/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/ApiTokens/ListView/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/index.js +85 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/init.js +13 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/Form/reducer.js +43 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/index.js +118 -0
- package/admin/src/pages/{App → SettingsPage/pages/ApplicationInfosPage/components/LogoInput}/reducer.js +13 -7
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoInput/stepper.js +25 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/AddLogoDialog.js +67 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromComputerForm.js +176 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/FromUrlForm.js +82 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/ImageCardAsset.js +51 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/PendingLogoDialog.js +97 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/index.js +85 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/components/LogoModalStepper/reducer.js +28 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/index.js +155 -87
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/api.js +16 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/constants.js +3 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/getFormData.js +17 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/parseFileMetadatas.js +76 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/prefixAllUrls.js +17 -0
- package/admin/src/pages/SettingsPage/pages/ApplicationInfosPage/utils/urlToFile.js +21 -0
- package/admin/src/pages/SettingsPage/pages/Roles/EditPage/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Users/EditPage/index.js +1 -1
- package/admin/src/pages/SettingsPage/pages/Webhooks/EditView/components/WebhookForm/index.js +1 -2
- package/admin/src/pages/SettingsPage/pages/Webhooks/ListView/index.js +1 -1
- package/admin/src/reducers.js +2 -4
- package/admin/src/translations/en.json +33 -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/4800.d3ebc81d.chunk.js +1 -0
- package/build/4982.c57c5675.chunk.js +308 -0
- package/build/7197.ed8d6752.chunk.js +113 -0
- package/build/7589.577cf729.chunk.js +194 -0
- package/build/{7393.8ae60738.chunk.js → 7757.f6eb5e92.chunk.js} +89 -87
- 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/9115.abdf4e3b.chunk.js +1 -0
- package/build/9158.e48d88af.chunk.js +503 -0
- package/build/{7191.3bde3cbf.chunk.js → 9298.cb3b6bc1.chunk.js} +112 -113
- package/build/9420.ba035f29.chunk.js +508 -0
- package/build/948.d64fb515.chunk.js +2 -0
- package/build/Admin-authenticatedApp.e7ed0550.chunk.js +80 -0
- package/build/Admin_homePage.8c00145e.chunk.js +71 -0
- package/build/Admin_marketplace.a88d5bda.chunk.js +11 -0
- package/build/Admin_pluginsPage.e895d79f.chunk.js +1 -0
- package/build/{Admin_profilePage.62c203ad.chunk.js → Admin_profilePage.33cfed9b.chunk.js} +2 -2
- package/build/Admin_settingsPage.fe33e0a2.chunk.js +180 -0
- package/build/admin-edit-roles-page.e77a2acc.chunk.js +1 -0
- 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.618b3e40.chunk.js +1 -0
- package/build/api-tokens-edit-page.8d19dfe1.chunk.js +1 -0
- package/build/api-tokens-list-page.274e1c80.chunk.js +15 -0
- 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.04b93497.chunk.js +1204 -0
- 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/fb376b132d18bf4522ca.png +0 -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.a32b12c8.js → runtime~main.de49adfd.js} +1 -1
- package/build/sso-settings-page.0b4d2106.chunk.js +1 -0
- package/build/upload-settings.cadfd452.chunk.js +101 -0
- package/build/upload-translation-ca-json.79159984.chunk.js +1 -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.28bf6bdc.chunk.js +30 -0
- package/build/vi-json.bf3424be.chunk.js +1 -0
- package/build/webhook-edit-page.ca670f8d.chunk.js +23 -0
- package/build/webhook-list-page.7057f1e8.chunk.js +133 -0
- package/ee/admin/pages/AuthPage/components/Providers/index.js +1 -1
- package/ee/admin/pages/SettingsPage/pages/Roles/CreatePage/index.js +1 -1
- package/ee/server/controllers/user.js +4 -0
- package/index.js +239 -53
- package/package.json +8 -12
- package/scripts/build.js +3 -17
- package/server/config/admin-actions.js +14 -0
- package/server/controllers/admin.js +29 -12
- package/server/controllers/user.js +4 -0
- package/server/policies/index.js +0 -1
- package/server/routes/admin.js +28 -9
- package/server/routes/serve-admin-panel.js +1 -1
- package/server/services/index.js +1 -0
- package/server/services/permission/permissions-manager/sanitize.js +22 -0
- package/server/services/project-settings.js +173 -0
- package/server/services/user.js +1 -1
- package/server/utils/index.d.ts +2 -0
- package/server/validation/project-settings.js +39 -0
- package/webpack.config.js +5 -28
- package/admin/src/content-manager/components/DynamicComponentCard/index.js +0 -43
- package/admin/src/pages/App/constants.js +0 -1
- package/admin/src/tsconfig.json +0 -10
- package/build/1856.521a99fd.chunk.js +0 -172
- package/build/20.cf744c35.chunk.js +0 -308
- package/build/2077.51485bfb.chunk.js +0 -194
- package/build/2135.95ee6de1.chunk.js +0 -162
- package/build/2524.688d0355.chunk.js +0 -1
- package/build/2897.8e7d5853.chunk.js +0 -184
- package/build/2912.79c2b3c8.chunk.js +0 -253
- package/build/2a9e9ef5c4c775bb7c7b.png +0 -0
- package/build/4073.f3936352.chunk.js +0 -1
- package/build/4715.77e04177.chunk.js +0 -385
- package/build/5232.928fea74.chunk.js +0 -989
- package/build/6229.26d93336.chunk.js +0 -194
- package/build/6281.f10a7e3a.chunk.js +0 -1
- package/build/6404.80bf5858.chunk.js +0 -506
- package/build/7009.79fce86d.chunk.js +0 -164
- package/build/7841.f0e7d629.chunk.js +0 -253
- package/build/7863.c1938f3f.chunk.js +0 -112
- package/build/9066.118ecccd.chunk.js +0 -101
- package/build/Admin-authenticatedApp.1f76af8f.chunk.js +0 -80
- package/build/Admin_homePage.8b391120.chunk.js +0 -71
- package/build/Admin_marketplace.21730109.chunk.js +0 -11
- package/build/Admin_pluginsPage.788fb2f6.chunk.js +0 -1
- package/build/Admin_settingsPage.9ce20f16.chunk.js +0 -170
- package/build/admin-edit-roles-page.75380ed4.chunk.js +0 -1
- package/build/admin-edit-users.05f7f389.chunk.js +0 -10
- package/build/admin-users.e03db115.chunk.js +0 -11
- package/build/api-tokens-create-page.c44e0c62.chunk.js +0 -1
- package/build/api-tokens-edit-page.30d0924d.chunk.js +0 -1
- package/build/api-tokens-list-page.6049cd23.chunk.js +0 -15
- package/build/codemirror-theme.cf9f9eb6.chunk.js +0 -34
- package/build/content-manager.2f0f9b15.chunk.js +0 -1204
- package/build/content-type-builder.ce7b7f42.chunk.js +0 -141
- package/build/email-settings-page.f67d13b2.chunk.js +0 -103
- package/build/en-json.3e1a222e.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.e6045245.js +0 -7909
- package/build/pl-json.94f05d2c.chunk.js +0 -1
- package/build/sso-settings-page.e9034e22.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/users-roles-settings-page.c01bec1d.chunk.js +0 -30
- package/build/vi-json.3d14e91e.chunk.js +0 -1
- package/build/webhook-edit-page.d457087d.chunk.js +0 -23
- package/build/webhook-list-page.a4217ff2.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/scripts/build.js
CHANGED
|
@@ -3,11 +3,7 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const webpack = require('webpack');
|
|
5
5
|
const { isObject } = require('lodash');
|
|
6
|
-
// eslint-disable-next-line node/no-extraneous-require
|
|
7
|
-
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
|
|
8
|
-
|
|
9
6
|
const webpackConfig = require('../webpack.config');
|
|
10
|
-
const getPluginsPath = require('../utils/get-plugins-path');
|
|
11
7
|
const {
|
|
12
8
|
getCorePluginsPath,
|
|
13
9
|
getPluginToInstallPath,
|
|
@@ -16,39 +12,29 @@ const {
|
|
|
16
12
|
|
|
17
13
|
const PLUGINS_TO_INSTALL = ['i18n', 'users-permissions'];
|
|
18
14
|
|
|
19
|
-
// Wrapper that outputs the webpack speed
|
|
20
|
-
const smp = new SpeedMeasurePlugin();
|
|
21
|
-
|
|
22
15
|
const buildAdmin = async () => {
|
|
23
16
|
const entry = path.join(__dirname, '..', 'admin', 'src');
|
|
24
17
|
const dest = path.join(__dirname, '..', 'build');
|
|
25
|
-
const tsConfigFilePath = path.join(__dirname, '..', 'admin', 'src', 'tsconfig.json');
|
|
26
|
-
|
|
27
18
|
const corePlugins = getCorePluginsPath();
|
|
28
19
|
const plugins = getPluginToInstallPath(PLUGINS_TO_INSTALL);
|
|
29
20
|
const allPlugins = { ...corePlugins, ...plugins };
|
|
30
|
-
const pluginsPath = getPluginsPath();
|
|
31
21
|
|
|
32
22
|
await createPluginsFile(allPlugins);
|
|
33
23
|
|
|
34
24
|
const args = {
|
|
35
25
|
entry,
|
|
36
26
|
dest,
|
|
37
|
-
cacheDir: path.
|
|
38
|
-
pluginsPath,
|
|
27
|
+
cacheDir: path.resolve(__dirname, '..'),
|
|
28
|
+
pluginsPath: [path.resolve(__dirname, '../../../../packages')],
|
|
39
29
|
env: 'production',
|
|
40
30
|
optimize: true,
|
|
41
31
|
options: {
|
|
42
32
|
backend: 'http://localhost:1337',
|
|
43
33
|
adminPath: '/admin/',
|
|
44
34
|
},
|
|
45
|
-
tsConfigFilePath,
|
|
46
35
|
};
|
|
47
36
|
|
|
48
|
-
const
|
|
49
|
-
process.env.MESURE_BUILD_SPEED === 'true' ? smp.wrap(webpackConfig(args)) : webpackConfig(args);
|
|
50
|
-
|
|
51
|
-
const compiler = webpack(config);
|
|
37
|
+
const compiler = webpack(webpackConfig(args));
|
|
52
38
|
|
|
53
39
|
console.log('Building the admin panel');
|
|
54
40
|
|
|
@@ -146,5 +146,19 @@ module.exports = {
|
|
|
146
146
|
section: 'settings',
|
|
147
147
|
category: 'api tokens',
|
|
148
148
|
},
|
|
149
|
+
{
|
|
150
|
+
uid: 'project-settings.update',
|
|
151
|
+
displayName: 'Update the project level settings',
|
|
152
|
+
pluginName: 'admin',
|
|
153
|
+
section: 'settings',
|
|
154
|
+
category: 'project',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
uid: 'project-settings.read',
|
|
158
|
+
displayName: 'Read the project level settings',
|
|
159
|
+
pluginName: 'admin',
|
|
160
|
+
section: 'settings',
|
|
161
|
+
category: 'project',
|
|
162
|
+
},
|
|
149
163
|
],
|
|
150
164
|
};
|
|
@@ -5,10 +5,14 @@ const execa = require('execa');
|
|
|
5
5
|
const _ = require('lodash');
|
|
6
6
|
const { exists } = require('fs-extra');
|
|
7
7
|
const { ValidationError } = require('@strapi/utils').errors;
|
|
8
|
-
const { isUsingTypeScript } = require('@strapi/typescript-utils');
|
|
9
8
|
// eslint-disable-next-line node/no-extraneous-require
|
|
10
9
|
const ee = require('@strapi/strapi/lib/utils/ee');
|
|
11
10
|
|
|
11
|
+
const {
|
|
12
|
+
validateUpdateProjectSettings,
|
|
13
|
+
validateUpdateProjectSettingsFiles,
|
|
14
|
+
validateUpdateProjectSettingsImagesDimensions,
|
|
15
|
+
} = require('../validation/project-settings');
|
|
12
16
|
const { getService } = require('../utils');
|
|
13
17
|
|
|
14
18
|
const PLUGIN_NAME_REGEX = /^[A-Za-z][A-Za-z0-9-_]+$/;
|
|
@@ -40,6 +44,7 @@ module.exports = {
|
|
|
40
44
|
async init() {
|
|
41
45
|
let uuid = strapi.config.get('uuid', false);
|
|
42
46
|
const hasAdmin = await getService('user').exists();
|
|
47
|
+
const { menuLogo } = await getService('project-settings').getProjectSettings();
|
|
43
48
|
// set to null if telemetryDisabled flag not avaialble in package.json
|
|
44
49
|
const telemetryDisabled = strapi.config.get('packageJsonStrapi.telemetryDisabled', null);
|
|
45
50
|
|
|
@@ -47,23 +52,35 @@ module.exports = {
|
|
|
47
52
|
uuid = false;
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
return { data: { uuid, hasAdmin } };
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
async telemetryProperties() {
|
|
54
|
-
const useTypescriptOnServer = await isUsingTypeScript(strapi.dirs.app.root);
|
|
55
|
-
const useTypescriptOnAdmin = await isUsingTypeScript(
|
|
56
|
-
path.join(strapi.dirs.app.root, 'src', 'admin')
|
|
57
|
-
);
|
|
58
|
-
|
|
59
55
|
return {
|
|
60
56
|
data: {
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
uuid,
|
|
58
|
+
hasAdmin,
|
|
59
|
+
menuLogo: menuLogo ? menuLogo.url : null,
|
|
63
60
|
},
|
|
64
61
|
};
|
|
65
62
|
},
|
|
66
63
|
|
|
64
|
+
async getProjectSettings() {
|
|
65
|
+
return getService('project-settings').getProjectSettings();
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
async updateProjectSettings(ctx) {
|
|
69
|
+
const projectSettingsService = getService('project-settings');
|
|
70
|
+
|
|
71
|
+
const {
|
|
72
|
+
request: { files, body },
|
|
73
|
+
} = ctx;
|
|
74
|
+
|
|
75
|
+
await validateUpdateProjectSettings(body);
|
|
76
|
+
await validateUpdateProjectSettingsFiles(files);
|
|
77
|
+
|
|
78
|
+
const formatedFiles = await projectSettingsService.parseFilesData(files);
|
|
79
|
+
await validateUpdateProjectSettingsImagesDimensions(formatedFiles);
|
|
80
|
+
|
|
81
|
+
return projectSettingsService.updateProjectSettings({ ...body, ...formatedFiles });
|
|
82
|
+
},
|
|
83
|
+
|
|
67
84
|
async information() {
|
|
68
85
|
const currentEnvironment = strapi.config.get('environment');
|
|
69
86
|
const autoReload = strapi.config.get('autoReload', false);
|
|
@@ -36,6 +36,10 @@ module.exports = {
|
|
|
36
36
|
|
|
37
37
|
const userInfo = getService('user').sanitizeUser(createdUser);
|
|
38
38
|
|
|
39
|
+
// Note: We need to assign manually the registrationToken to the
|
|
40
|
+
// final user payload so that it's not removed in the sanitation process.
|
|
41
|
+
Object.assign(userInfo, { registrationToken: createdUser.registrationToken });
|
|
42
|
+
|
|
39
43
|
// Send 201 created
|
|
40
44
|
ctx.created({ data: userInfo });
|
|
41
45
|
},
|
package/server/policies/index.js
CHANGED
package/server/routes/admin.js
CHANGED
|
@@ -7,6 +7,34 @@ module.exports = [
|
|
|
7
7
|
handler: 'admin.init',
|
|
8
8
|
config: { auth: false },
|
|
9
9
|
},
|
|
10
|
+
{
|
|
11
|
+
method: 'GET',
|
|
12
|
+
path: '/project-settings',
|
|
13
|
+
handler: 'admin.getProjectSettings',
|
|
14
|
+
config: {
|
|
15
|
+
policies: [
|
|
16
|
+
'admin::isAuthenticatedAdmin',
|
|
17
|
+
{
|
|
18
|
+
name: 'admin::hasPermissions',
|
|
19
|
+
config: { actions: ['admin::project-settings.read'] },
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
method: 'POST',
|
|
26
|
+
path: '/project-settings',
|
|
27
|
+
handler: 'admin.updateProjectSettings',
|
|
28
|
+
config: {
|
|
29
|
+
policies: [
|
|
30
|
+
'admin::isAuthenticatedAdmin',
|
|
31
|
+
{
|
|
32
|
+
name: 'admin::hasPermissions',
|
|
33
|
+
config: { actions: ['admin::project-settings.update'] },
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
},
|
|
10
38
|
{
|
|
11
39
|
method: 'GET',
|
|
12
40
|
path: '/project-type',
|
|
@@ -21,15 +49,6 @@ module.exports = [
|
|
|
21
49
|
policies: ['admin::isAuthenticatedAdmin'],
|
|
22
50
|
},
|
|
23
51
|
},
|
|
24
|
-
{
|
|
25
|
-
method: 'GET',
|
|
26
|
-
path: '/telemetry-properties',
|
|
27
|
-
handler: 'admin.telemetryProperties',
|
|
28
|
-
config: {
|
|
29
|
-
auth: false,
|
|
30
|
-
policies: ['admin::isTelemetryEnabled'],
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
52
|
{
|
|
34
53
|
method: 'GET',
|
|
35
54
|
path: '/plugins',
|
|
@@ -5,7 +5,7 @@ const fse = require('fs-extra');
|
|
|
5
5
|
const koaStatic = require('koa-static');
|
|
6
6
|
|
|
7
7
|
const registerAdminPanelRoute = ({ strapi }) => {
|
|
8
|
-
let buildDir = resolve(strapi.dirs.
|
|
8
|
+
let buildDir = resolve(strapi.dirs.root, 'build');
|
|
9
9
|
|
|
10
10
|
if (!fse.pathExistsSync(buildDir)) {
|
|
11
11
|
buildDir = resolve(__dirname, '../../build');
|
package/server/services/index.js
CHANGED
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
uniq,
|
|
15
15
|
intersection,
|
|
16
16
|
pick,
|
|
17
|
+
getOr,
|
|
17
18
|
} = require('lodash/fp');
|
|
18
19
|
|
|
19
20
|
const { contentTypes, traverseEntity, sanitize, pipeAsync } = require('@strapi/utils');
|
|
@@ -46,6 +47,8 @@ module.exports = ({ action, ability, model }) => {
|
|
|
46
47
|
const permittedFields = fields.shouldIncludeAll ? null : getOutputFields(fields.permitted);
|
|
47
48
|
|
|
48
49
|
return pipeAsync(
|
|
50
|
+
// Remove fields hidden from the admin
|
|
51
|
+
traverseEntity(omitHiddenFields, { schema }),
|
|
49
52
|
// Remove unallowed fields from admin::user relations
|
|
50
53
|
traverseEntity(pickAllowedAdminUserFields, { schema }),
|
|
51
54
|
// Remove not allowed fields (RBAC)
|
|
@@ -61,6 +64,8 @@ module.exports = ({ action, ability, model }) => {
|
|
|
61
64
|
const permittedFields = fields.shouldIncludeAll ? null : getInputFields(fields.permitted);
|
|
62
65
|
|
|
63
66
|
return pipeAsync(
|
|
67
|
+
// Remove fields hidden from the admin
|
|
68
|
+
traverseEntity(omitHiddenFields, { schema }),
|
|
64
69
|
// Remove not allowed fields (RBAC)
|
|
65
70
|
traverseEntity(allowedFields(permittedFields), { schema }),
|
|
66
71
|
// Remove roles from createdBy & updateBy fields
|
|
@@ -107,8 +112,25 @@ module.exports = ({ action, ability, model }) => {
|
|
|
107
112
|
return defaults({ subject: asSubject(model, data), action }, options);
|
|
108
113
|
};
|
|
109
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Omit creator fields' (createdBy & updatedBy) roles from the admin API responses
|
|
117
|
+
*/
|
|
110
118
|
const omitCreatorRoles = omit([`${CREATED_BY_ATTRIBUTE}.roles`, `${UPDATED_BY_ATTRIBUTE}.roles`]);
|
|
111
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Visitor used to remove hidden fields from the admin API responses
|
|
122
|
+
*/
|
|
123
|
+
const omitHiddenFields = ({ key, schema }, { remove }) => {
|
|
124
|
+
const isHidden = getOr(false, ['config', 'attributes', key, 'hidden'], schema);
|
|
125
|
+
|
|
126
|
+
if (isHidden) {
|
|
127
|
+
remove(key);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Visitor used to only select needed fields from the admin users entities & avoid leaking sensitive information
|
|
133
|
+
*/
|
|
112
134
|
const pickAllowedAdminUserFields = ({ attribute, key, value }, { set }) => {
|
|
113
135
|
const pickAllowedFields = pick(['id', 'firstname', 'lastname', 'username']);
|
|
114
136
|
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const { pick } = require('lodash');
|
|
5
|
+
|
|
6
|
+
const PROJECT_SETTINGS_FILE_INPUTS = ['menuLogo'];
|
|
7
|
+
const DEFAULT_PROJECT_SETTINGS = {
|
|
8
|
+
menuLogo: null,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const parseFilesData = async files => {
|
|
12
|
+
const formatedFilesData = {};
|
|
13
|
+
|
|
14
|
+
await Promise.all(
|
|
15
|
+
PROJECT_SETTINGS_FILE_INPUTS.map(async inputName => {
|
|
16
|
+
const file = files[inputName];
|
|
17
|
+
|
|
18
|
+
// Skip empty file inputs
|
|
19
|
+
if (!file) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const getStream = () => fs.createReadStream(file.path);
|
|
24
|
+
|
|
25
|
+
// Add formated data for the upload provider
|
|
26
|
+
formatedFilesData[inputName] = strapi
|
|
27
|
+
.plugin('upload')
|
|
28
|
+
.service('upload')
|
|
29
|
+
.formatFileInfo({
|
|
30
|
+
filename: file.name,
|
|
31
|
+
type: file.type,
|
|
32
|
+
size: file.size,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Add image dimensions
|
|
36
|
+
Object.assign(
|
|
37
|
+
formatedFilesData[inputName],
|
|
38
|
+
await strapi
|
|
39
|
+
.plugin('upload')
|
|
40
|
+
.service('image-manipulation')
|
|
41
|
+
.getDimensions({ getStream })
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Add file path, and stream
|
|
45
|
+
Object.assign(formatedFilesData[inputName], {
|
|
46
|
+
stream: getStream(),
|
|
47
|
+
tmpPath: file.path,
|
|
48
|
+
provider: strapi.config.get('plugin.upload').provider,
|
|
49
|
+
});
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
return formatedFilesData;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const getProjectSettings = async () => {
|
|
57
|
+
const store = strapi.store({ type: 'core', name: 'admin' });
|
|
58
|
+
const projectSettings = {
|
|
59
|
+
...DEFAULT_PROJECT_SETTINGS,
|
|
60
|
+
...(await store.get({ key: 'project-settings' })),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Filter file input fields
|
|
64
|
+
PROJECT_SETTINGS_FILE_INPUTS.forEach(inputName => {
|
|
65
|
+
if (!projectSettings[inputName]) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
projectSettings[inputName] = pick(projectSettings[inputName], [
|
|
70
|
+
'name',
|
|
71
|
+
'url',
|
|
72
|
+
'width',
|
|
73
|
+
'height',
|
|
74
|
+
'ext',
|
|
75
|
+
'size',
|
|
76
|
+
]);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return projectSettings;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const uploadFiles = async (files = {}) => {
|
|
83
|
+
// Call the provider upload function for each file
|
|
84
|
+
return Promise.all(
|
|
85
|
+
Object.values(files)
|
|
86
|
+
.filter(file => file.stream instanceof fs.ReadStream)
|
|
87
|
+
.map(file => strapi.plugin('upload').provider.uploadStream(file))
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const deleteOldFiles = async ({ previousSettings, newSettings }) => {
|
|
92
|
+
return Promise.all(
|
|
93
|
+
PROJECT_SETTINGS_FILE_INPUTS.map(async inputName => {
|
|
94
|
+
// Skip if the store doesn't contain project settings
|
|
95
|
+
if (!previousSettings) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Skip if there was no previous file
|
|
100
|
+
if (!previousSettings[inputName]) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Skip if the file was not changed
|
|
105
|
+
if (
|
|
106
|
+
newSettings[inputName] &&
|
|
107
|
+
previousSettings[inputName].hash === newSettings[inputName].hash
|
|
108
|
+
) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Skip if the file was not uploaded with the current provider
|
|
113
|
+
if (strapi.config.get('plugin.upload').provider !== previousSettings[inputName].provider) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// There was a previous file and an new file was uploaded
|
|
118
|
+
// Remove the previous file
|
|
119
|
+
strapi.plugin('upload').provider.delete(previousSettings[inputName]);
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const updateProjectSettings = async newSettings => {
|
|
125
|
+
const store = strapi.store({ type: 'core', name: 'admin' });
|
|
126
|
+
const previousSettings = await store.get({ key: 'project-settings' });
|
|
127
|
+
const files = pick(newSettings, PROJECT_SETTINGS_FILE_INPUTS);
|
|
128
|
+
|
|
129
|
+
await uploadFiles(files);
|
|
130
|
+
|
|
131
|
+
PROJECT_SETTINGS_FILE_INPUTS.forEach(inputName => {
|
|
132
|
+
// If the user input exists but is not a formdata "file" remove it
|
|
133
|
+
if (newSettings[inputName] !== undefined && !(typeof newSettings[inputName] === 'object')) {
|
|
134
|
+
newSettings[inputName] = null;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// If the user input is undefined reuse previous setting (do not update field)
|
|
139
|
+
if (!newSettings[inputName]) {
|
|
140
|
+
newSettings[inputName] = previousSettings[inputName];
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Update the file
|
|
145
|
+
newSettings[inputName] = pick(newSettings[inputName], [
|
|
146
|
+
'name',
|
|
147
|
+
'hash',
|
|
148
|
+
'url',
|
|
149
|
+
'width',
|
|
150
|
+
'height',
|
|
151
|
+
'ext',
|
|
152
|
+
'size',
|
|
153
|
+
'provider',
|
|
154
|
+
]);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// No await to proceed asynchronously
|
|
158
|
+
deleteOldFiles({ previousSettings, newSettings });
|
|
159
|
+
|
|
160
|
+
await store.set({
|
|
161
|
+
key: 'project-settings',
|
|
162
|
+
value: { ...previousSettings, ...newSettings },
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return getProjectSettings();
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
module.exports = {
|
|
169
|
+
deleteOldFiles,
|
|
170
|
+
parseFilesData,
|
|
171
|
+
getProjectSettings,
|
|
172
|
+
updateProjectSettings,
|
|
173
|
+
};
|
package/server/services/user.js
CHANGED
|
@@ -17,7 +17,7 @@ const sanitizeUserRoles = role => _.pick(role, ['id', 'name', 'description', 'co
|
|
|
17
17
|
*/
|
|
18
18
|
const sanitizeUser = user => {
|
|
19
19
|
return {
|
|
20
|
-
..._.omit(user, ['password', 'resetPasswordToken', 'roles']),
|
|
20
|
+
..._.omit(user, ['password', 'resetPasswordToken', 'registrationToken', 'roles']),
|
|
21
21
|
roles: user.roles && user.roles.map(sanitizeUserRoles),
|
|
22
22
|
};
|
|
23
23
|
};
|
package/server/utils/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as metrics from '../services/metrics';
|
|
|
6
6
|
import * as token from '../services/token';
|
|
7
7
|
import * as auth from '../services/auth';
|
|
8
8
|
import * as apiToken from '../services/api-token';
|
|
9
|
+
import * as projectSettings from '../services/project-settings';
|
|
9
10
|
|
|
10
11
|
type S = {
|
|
11
12
|
role: typeof role;
|
|
@@ -16,6 +17,7 @@ type S = {
|
|
|
16
17
|
auth: typeof auth;
|
|
17
18
|
metrics: typeof metrics;
|
|
18
19
|
'api-token': typeof apiToken;
|
|
20
|
+
'project-settings': typeof projectSettings;
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
export function getService<T extends keyof S>(name: T): S[T];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { yup, validateYupSchemaSync } = require('@strapi/utils');
|
|
4
|
+
|
|
5
|
+
const MAX_IMAGE_WIDTH = 750;
|
|
6
|
+
const MAX_IMAGE_HEIGHT = MAX_IMAGE_WIDTH;
|
|
7
|
+
const MAX_IMAGE_FILE_SIZE = 1024 * 1024; // 1Mo
|
|
8
|
+
const ALLOWED_IMAGE_FILE_TYPES = ['image/jpeg', 'image/png', 'image/svg+xml'];
|
|
9
|
+
|
|
10
|
+
const updateProjectSettings = yup
|
|
11
|
+
.object({
|
|
12
|
+
menuLogo: yup.string(),
|
|
13
|
+
})
|
|
14
|
+
.noUnknown();
|
|
15
|
+
|
|
16
|
+
const updateProjectSettingsFiles = yup
|
|
17
|
+
.object({
|
|
18
|
+
menuLogo: yup.object({
|
|
19
|
+
name: yup.string(),
|
|
20
|
+
type: yup.string().oneOf(ALLOWED_IMAGE_FILE_TYPES),
|
|
21
|
+
size: yup.number().max(MAX_IMAGE_FILE_SIZE),
|
|
22
|
+
}),
|
|
23
|
+
})
|
|
24
|
+
.noUnknown();
|
|
25
|
+
|
|
26
|
+
const updateProjectSettingsImagesDimensions = yup.object({
|
|
27
|
+
menuLogo: yup.object({
|
|
28
|
+
width: yup.number().max(MAX_IMAGE_WIDTH),
|
|
29
|
+
height: yup.number().max(MAX_IMAGE_HEIGHT),
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
module.exports = {
|
|
34
|
+
validateUpdateProjectSettings: validateYupSchemaSync(updateProjectSettings),
|
|
35
|
+
validateUpdateProjectSettingsFiles: validateYupSchemaSync(updateProjectSettingsFiles),
|
|
36
|
+
validateUpdateProjectSettingsImagesDimensions: validateYupSchemaSync(
|
|
37
|
+
updateProjectSettingsImagesDimensions
|
|
38
|
+
),
|
|
39
|
+
};
|
package/webpack.config.js
CHANGED
|
@@ -4,7 +4,6 @@ const path = require('path');
|
|
|
4
4
|
const fse = require('fs-extra');
|
|
5
5
|
const webpack = require('webpack');
|
|
6
6
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
7
|
-
const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
|
|
8
7
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
9
8
|
const { ESBuildMinifyPlugin } = require('esbuild-loader');
|
|
10
9
|
const WebpackBar = require('webpackbar');
|
|
@@ -15,12 +14,12 @@ const getClientEnvironment = require('./env');
|
|
|
15
14
|
const EE_REGEX = /from.* ['"]ee_else_ce\//;
|
|
16
15
|
|
|
17
16
|
module.exports = ({
|
|
17
|
+
entry,
|
|
18
18
|
cacheDir,
|
|
19
|
+
pluginsPath,
|
|
19
20
|
dest,
|
|
20
|
-
entry,
|
|
21
21
|
env,
|
|
22
22
|
optimize,
|
|
23
|
-
pluginsPath,
|
|
24
23
|
options = {
|
|
25
24
|
backend: 'http://localhost:1337',
|
|
26
25
|
adminPath: '/admin/',
|
|
@@ -30,7 +29,6 @@ module.exports = ({
|
|
|
30
29
|
eeRoot: './ee/admin',
|
|
31
30
|
ceRoot: './admin/src',
|
|
32
31
|
},
|
|
33
|
-
tsConfigFilePath,
|
|
34
32
|
}) => {
|
|
35
33
|
const isProduction = env === 'production';
|
|
36
34
|
|
|
@@ -51,9 +49,6 @@ module.exports = ({
|
|
|
51
49
|
]
|
|
52
50
|
: [];
|
|
53
51
|
|
|
54
|
-
// Directly inject a polyfill in the webpack entry point before the entry point
|
|
55
|
-
// FIXME: I have noticed a bug regarding the helper-plugin and esbuild-loader
|
|
56
|
-
// The only I could fix it was to inject the babel polyfill
|
|
57
52
|
const babelPolyfill = '@babel/polyfill/dist/polyfill.min.js';
|
|
58
53
|
|
|
59
54
|
return {
|
|
@@ -84,16 +79,6 @@ module.exports = ({
|
|
|
84
79
|
},
|
|
85
80
|
module: {
|
|
86
81
|
rules: [
|
|
87
|
-
{
|
|
88
|
-
test: /\.tsx?$/,
|
|
89
|
-
loader: require.resolve('esbuild-loader'),
|
|
90
|
-
include: [cacheDir, ...pluginsPath],
|
|
91
|
-
exclude: /node_modules/,
|
|
92
|
-
options: {
|
|
93
|
-
loader: 'tsx',
|
|
94
|
-
target: 'es2015',
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
82
|
{
|
|
98
83
|
test: /\.m?jsx?$/,
|
|
99
84
|
include: cacheDir,
|
|
@@ -109,10 +94,6 @@ module.exports = ({
|
|
|
109
94
|
try {
|
|
110
95
|
const fileContent = fse.readFileSync(filePath).toString();
|
|
111
96
|
|
|
112
|
-
if (fileContent.match(/from.* ['"]ee_else_ce\//)) {
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
97
|
return EE_REGEX.test(fileContent);
|
|
117
98
|
} catch (e) {
|
|
118
99
|
return false;
|
|
@@ -209,7 +190,7 @@ module.exports = ({
|
|
|
209
190
|
resolve: {
|
|
210
191
|
alias,
|
|
211
192
|
symlinks: false,
|
|
212
|
-
extensions: ['.js', '.jsx', '.react.js'
|
|
193
|
+
extensions: ['.js', '.jsx', '.react.js'],
|
|
213
194
|
mainFields: ['browser', 'jsnext:main', 'main'],
|
|
214
195
|
modules: ['node_modules', path.resolve(__dirname, 'node_modules')],
|
|
215
196
|
},
|
|
@@ -217,16 +198,12 @@ module.exports = ({
|
|
|
217
198
|
new HtmlWebpackPlugin({
|
|
218
199
|
inject: true,
|
|
219
200
|
template: path.resolve(__dirname, 'index.html'),
|
|
201
|
+
// FIXME
|
|
202
|
+
// favicon: path.resolve(__dirname, 'admin/src/favicon.ico'),
|
|
220
203
|
}),
|
|
221
204
|
new webpack.DefinePlugin(envVariables),
|
|
222
205
|
|
|
223
206
|
new NodePolyfillPlugin(),
|
|
224
|
-
|
|
225
|
-
new ForkTsCheckerPlugin({
|
|
226
|
-
typescript: {
|
|
227
|
-
configFile: tsConfigFilePath,
|
|
228
|
-
},
|
|
229
|
-
}),
|
|
230
207
|
...webpackPlugins,
|
|
231
208
|
],
|
|
232
209
|
};
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
4
|
-
import Wrapper from './Wrapper';
|
|
5
|
-
|
|
6
|
-
const DynamicComponentCard = ({ children, componentUid, friendlyName, icon, onClick }) => {
|
|
7
|
-
return (
|
|
8
|
-
<Wrapper
|
|
9
|
-
onClick={e => {
|
|
10
|
-
e.preventDefault();
|
|
11
|
-
e.stopPropagation();
|
|
12
|
-
|
|
13
|
-
onClick(componentUid);
|
|
14
|
-
}}
|
|
15
|
-
>
|
|
16
|
-
<button className="component-icon" type="button">
|
|
17
|
-
<FontAwesomeIcon icon={icon} />
|
|
18
|
-
</button>
|
|
19
|
-
|
|
20
|
-
<div className="component-uid">
|
|
21
|
-
<span>{friendlyName}</span>
|
|
22
|
-
</div>
|
|
23
|
-
{children}
|
|
24
|
-
</Wrapper>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
DynamicComponentCard.defaultProps = {
|
|
29
|
-
children: null,
|
|
30
|
-
friendlyName: '',
|
|
31
|
-
onClick: () => {},
|
|
32
|
-
icon: 'smile',
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
DynamicComponentCard.propTypes = {
|
|
36
|
-
children: PropTypes.node,
|
|
37
|
-
componentUid: PropTypes.string.isRequired,
|
|
38
|
-
friendlyName: PropTypes.string,
|
|
39
|
-
icon: PropTypes.string,
|
|
40
|
-
onClick: PropTypes.func,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export default DynamicComponentCard;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const SET_APP_RUNTIME_STATUS = 'StrapiAdmin/APP/SET_APP_RUNTIME_STATUS';
|
package/admin/src/tsconfig.json
DELETED