@strapi/admin 4.2.0-alpha.O → 4.2.0-beta.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 +7 -4
- package/admin/src/assets/images/icon_made-by-strapi.svg +5 -0
- package/admin/src/components/AuthenticatedApp/index.js +9 -2
- package/admin/src/components/AuthenticatedApp/utils/api.js +20 -1
- package/admin/src/components/GuidedTour/Homepage/index.js +13 -3
- package/admin/src/components/GuidedTour/Modal/index.js +4 -1
- package/admin/src/components/GuidedTour/layout.js +9 -0
- package/admin/src/components/PrivateRoute/index.js +23 -17
- package/admin/src/content-manager/components/DynamicZone/components/ComponentPicker/Category/index.js +4 -1
- package/admin/src/content-manager/components/Inputs/index.js +3 -4
- package/admin/src/content-manager/components/SelectWrapper/utils/getSelectStyles.js +2 -1
- package/admin/src/content-manager/pages/EditView/index.js +0 -188
- package/admin/src/hooks/index.js +0 -1
- package/admin/src/hooks/useFetchInstalledPlugins/index.js +23 -0
- package/admin/src/{pages/InstalledPluginsPage → hooks/useFetchInstalledPlugins}/utils/api.js +2 -4
- package/admin/src/hooks/useFetchMarketplacePlugins/index.js +23 -0
- package/admin/src/hooks/useFetchMarketplacePlugins/utils/api.js +17 -0
- package/admin/src/pages/Admin/index.js +1 -3
- package/admin/src/pages/AuthPage/index.js +28 -5
- package/admin/src/pages/InstalledPluginsPage/Plugins.js +6 -15
- package/admin/src/pages/MarketplacePage/components/EmptyPluginSearch/EmptyPluginGrid.js +27 -0
- package/admin/src/pages/MarketplacePage/components/EmptyPluginSearch/index.js +30 -0
- package/admin/src/pages/MarketplacePage/components/PluginCard/index.js +186 -0
- package/admin/src/pages/MarketplacePage/index.js +199 -107
- package/admin/src/pages/MarketplacePage/utils/api.js +9 -0
- package/admin/src/translations/en.json +18 -15
- package/admin/src/translations/ja.json +2 -2
- package/admin/src/translations/ko.json +2 -2
- package/admin/src/translations/vi.json +30 -4
- package/build/4362.b3d67035.chunk.js +1 -0
- package/build/90f49a385afb000fb1d4.svg +5 -0
- package/build/9260.4233fae2.chunk.js +2 -0
- package/build/{9260.fa40c7bd.chunk.js.LICENSE.txt → 9260.4233fae2.chunk.js.LICENSE.txt} +0 -0
- package/build/Admin-authenticatedApp.16bed71f.chunk.js +1 -0
- package/build/Admin_homePage.fd1fc572.chunk.js +1 -0
- package/build/Admin_marketplace.89a0a014.chunk.js +1 -0
- package/build/Admin_pluginsPage.97a514db.chunk.js +1 -0
- package/build/admin-users.2740c223.chunk.js +1 -0
- package/build/content-manager.f1c46a88.chunk.js +1 -0
- package/build/en-json.73a610d6.chunk.js +1 -0
- package/build/index.html +1 -1
- package/build/ja-json.e13f04e8.chunk.js +1 -0
- package/build/ko-json.2200c9c9.chunk.js +1 -0
- package/build/main.12d62562.js +2 -0
- package/build/{main.3e719c82.js.LICENSE.txt → main.12d62562.js.LICENSE.txt} +0 -0
- package/build/{runtime~main.66becdbd.js → runtime~main.21bf3a67.js} +1 -1
- package/build/{upload-translation-en-json.c3373c8d.chunk.js → upload-translation-en-json.c334dd82.chunk.js} +1 -1
- package/build/vi-json.1e850069.chunk.js +1 -0
- package/index.js +53 -244
- package/package.json +9 -7
- package/server/controllers/admin.js +12 -1
- package/server/routes/serve-admin-panel.js +1 -1
- package/utils/create-cache-dir.js +119 -0
- package/utils/get-custom-webpack-config.js +38 -0
- package/utils/index.js +13 -0
- package/utils/should-build-admin.js +51 -0
- package/utils/watch-admin-files.js +56 -0
- package/webpack.config.js +36 -3
- package/.env +0 -0
- package/admin/src/hooks/useFetchPluginsFromMarketPlace/index.js +0 -49
- package/admin/src/pages/MarketplacePage/MarketplaceBanner/Wrapper.js +0 -28
- package/admin/src/pages/MarketplacePage/MarketplaceBanner/index.js +0 -37
- package/admin/src/pages/MarketplacePage/PluginCard/Wrapper.js +0 -148
- package/admin/src/pages/MarketplacePage/PluginCard/index.js +0 -185
- package/admin/src/pages/MarketplacePage/Wrapper.js +0 -5
- package/admin/src/pages/MarketplacePage/assets/marketplace-coming-soon.png +0 -0
- package/build/01a600d9e6e0dea21e33.png +0 -0
- package/build/4362.86a4e939.chunk.js +0 -1
- package/build/9260.fa40c7bd.chunk.js +0 -2
- package/build/Admin-authenticatedApp.a5d2c5fa.chunk.js +0 -1
- package/build/Admin_homePage.d6754c66.chunk.js +0 -1
- package/build/Admin_marketplace.419010d8.chunk.js +0 -1
- package/build/Admin_pluginsPage.7d1bd7ce.chunk.js +0 -1
- package/build/admin-users.1fda1f27.chunk.js +0 -1
- package/build/content-manager.8412e024.chunk.js +0 -1
- package/build/en-json.b35c285f.chunk.js +0 -1
- package/build/ja-json.46e29f04.chunk.js +0 -1
- package/build/ko-json.dd36fdc0.chunk.js +0 -1
- package/build/main.3e719c82.js +0 -2
- package/build/vi-json.55a11ac0.chunk.js +0 -1
|
@@ -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.root, 'build');
|
|
8
|
+
let buildDir = resolve(strapi.dirs.dist.root, 'build');
|
|
9
9
|
|
|
10
10
|
if (!fse.pathExistsSync(buildDir)) {
|
|
11
11
|
buildDir = resolve(__dirname, '../../build');
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const _ = require('lodash');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
|
|
7
|
+
const getPkgPath = name => path.dirname(require.resolve(`${name}/package.json`));
|
|
8
|
+
|
|
9
|
+
async function createPluginsJs(plugins, dest) {
|
|
10
|
+
const pluginsArray = plugins.map(({ appPathToPlugin, name }) => {
|
|
11
|
+
const shortName = _.camelCase(name);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* path.join, on windows, it uses backslashes to resolve path.
|
|
15
|
+
* The problem is that Webpack does not windows paths
|
|
16
|
+
* With this tool, we need to rely on "/" and not "\".
|
|
17
|
+
* This is the reason why '..\\..\\..\\node_modules\\@strapi\\plugin-content-type-builder/strapi-admin.js' was not working.
|
|
18
|
+
* The regexp at line 105 aims to replace the windows backslashes by standard slash so that webpack can deal with them.
|
|
19
|
+
* Backslash looks to work only for absolute paths with webpack => https://webpack.js.org/concepts/module-resolution/#absolute-paths
|
|
20
|
+
*/
|
|
21
|
+
const realPath = path
|
|
22
|
+
.join(path.relative(path.resolve(dest, 'admin', 'src'), appPathToPlugin), 'strapi-admin.js')
|
|
23
|
+
.replace(/\\/g, '/');
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
name,
|
|
27
|
+
pathToPlugin: realPath,
|
|
28
|
+
shortName,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const content = `
|
|
33
|
+
${pluginsArray
|
|
34
|
+
.map(({ pathToPlugin, shortName }) => {
|
|
35
|
+
const req = `'${pathToPlugin}'`;
|
|
36
|
+
|
|
37
|
+
return `import ${shortName} from ${req};`;
|
|
38
|
+
})
|
|
39
|
+
.join('\n')}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
const plugins = {
|
|
43
|
+
${[...pluginsArray]
|
|
44
|
+
.map(({ name, shortName }) => {
|
|
45
|
+
return ` '${name}': ${shortName},`;
|
|
46
|
+
})
|
|
47
|
+
.join('\n')}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default plugins;
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
return fs.writeFile(path.resolve(dest, 'admin', 'src', 'plugins.js'), content);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function copyAdmin(dest) {
|
|
57
|
+
const adminPath = getPkgPath('@strapi/admin');
|
|
58
|
+
|
|
59
|
+
// TODO copy ee folders for plugins
|
|
60
|
+
await fs.copy(path.resolve(adminPath, 'ee', 'admin'), path.resolve(dest, 'ee', 'admin'));
|
|
61
|
+
|
|
62
|
+
await fs.ensureDir(path.resolve(dest, 'config'));
|
|
63
|
+
await fs.copy(path.resolve(adminPath, 'admin'), path.resolve(dest, 'admin'));
|
|
64
|
+
|
|
65
|
+
// Copy package.json
|
|
66
|
+
await fs.copy(path.resolve(adminPath, 'package.json'), path.resolve(dest, 'package.json'));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function createCacheDir({ appDir, plugins, useTypeScript }) {
|
|
70
|
+
const cacheDir = path.resolve(appDir, '.cache');
|
|
71
|
+
|
|
72
|
+
const pluginsWithFront = Object.keys(plugins)
|
|
73
|
+
.filter(pluginName => {
|
|
74
|
+
const pluginInfo = plugins[pluginName];
|
|
75
|
+
return fs.existsSync(path.resolve(pluginInfo.pathToPlugin, 'strapi-admin.js'));
|
|
76
|
+
})
|
|
77
|
+
.map(name => ({ name, ...plugins[name] }));
|
|
78
|
+
|
|
79
|
+
// create .cache dir
|
|
80
|
+
await fs.emptyDir(cacheDir);
|
|
81
|
+
|
|
82
|
+
// copy admin core code
|
|
83
|
+
await copyAdmin(cacheDir);
|
|
84
|
+
|
|
85
|
+
// Copy app.js or app.tsx if typescript is enabled
|
|
86
|
+
const customAdminConfigJSFilePath = path.join(appDir, 'src', 'admin', 'app.js');
|
|
87
|
+
const customAdminConfigTSXFilePath = path.join(appDir, 'src', 'admin', 'app.tsx');
|
|
88
|
+
const customAdminConfigFilePath = useTypeScript
|
|
89
|
+
? customAdminConfigTSXFilePath
|
|
90
|
+
: customAdminConfigJSFilePath;
|
|
91
|
+
|
|
92
|
+
if (fs.existsSync(customAdminConfigFilePath)) {
|
|
93
|
+
const defaultAdminConfigFilePath = path.resolve(cacheDir, 'admin', 'src', 'app.js');
|
|
94
|
+
|
|
95
|
+
if (useTypeScript) {
|
|
96
|
+
// Remove the default config file
|
|
97
|
+
await fs.remove(defaultAdminConfigFilePath);
|
|
98
|
+
// Copy the custom one
|
|
99
|
+
await fs.copy(
|
|
100
|
+
customAdminConfigTSXFilePath,
|
|
101
|
+
path.resolve(cacheDir, 'admin', 'src', 'app.tsx')
|
|
102
|
+
);
|
|
103
|
+
} else {
|
|
104
|
+
await fs.copy(customAdminConfigFilePath, path.resolve(cacheDir, 'admin', 'src', 'app.js'));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Copy admin extensions folder
|
|
109
|
+
const adminExtensionFolder = path.join(appDir, 'src', 'admin', 'extensions');
|
|
110
|
+
|
|
111
|
+
if (fs.existsSync(adminExtensionFolder)) {
|
|
112
|
+
await fs.copy(adminExtensionFolder, path.resolve(cacheDir, 'admin', 'src', 'extensions'));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// create plugins.js with plugins requires
|
|
116
|
+
await createPluginsJs(pluginsWithFront, cacheDir);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = createCacheDir;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const _ = require('lodash');
|
|
6
|
+
const webpack = require('webpack');
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const getWebpackConfig = require('../webpack.config');
|
|
9
|
+
|
|
10
|
+
const getCustomWebpackConfig = (dir, config) => {
|
|
11
|
+
const adminConfigPath = path.join(dir, 'src', 'admin', 'webpack.config.js');
|
|
12
|
+
|
|
13
|
+
let webpackConfig = getWebpackConfig(config);
|
|
14
|
+
|
|
15
|
+
if (fs.existsSync(adminConfigPath)) {
|
|
16
|
+
const webpackAdminConfig = require(path.resolve(adminConfigPath));
|
|
17
|
+
|
|
18
|
+
if (_.isFunction(webpackAdminConfig)) {
|
|
19
|
+
// Expose the devServer configuration
|
|
20
|
+
if (config.devServer) {
|
|
21
|
+
webpackConfig.devServer = config.devServer;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
webpackConfig = webpackAdminConfig(webpackConfig, webpack);
|
|
25
|
+
|
|
26
|
+
if (!webpackConfig) {
|
|
27
|
+
console.error(
|
|
28
|
+
`${chalk.red('Error:')} Nothing was returned from your custom webpack configuration`
|
|
29
|
+
);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return webpackConfig;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
module.exports = getCustomWebpackConfig;
|
package/utils/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const createCacheDir = require('./create-cache-dir');
|
|
4
|
+
const getCustomWebpackConfig = require('./get-custom-webpack-config');
|
|
5
|
+
const shouldBuildAdmin = require('./should-build-admin');
|
|
6
|
+
const watchAdminFiles = require('./watch-admin-files');
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
createCacheDir,
|
|
10
|
+
getCustomWebpackConfig,
|
|
11
|
+
shouldBuildAdmin,
|
|
12
|
+
watchAdminFiles,
|
|
13
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
|
|
6
|
+
const DEFAULT_PLUGINS = [
|
|
7
|
+
'content-type-builder',
|
|
8
|
+
'content-manager',
|
|
9
|
+
'upload',
|
|
10
|
+
'email',
|
|
11
|
+
'i18n',
|
|
12
|
+
'users-permissions',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Checks if the project's installed plugins are not the same as a default one.
|
|
17
|
+
* @param {Object} plugins
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
const hasNonDefaultPlugins = plugins => {
|
|
21
|
+
// List of plugins that are not the ones installed in a generated app
|
|
22
|
+
const installedPlugins = Object.keys(plugins).filter(x => !DEFAULT_PLUGINS.includes(x));
|
|
23
|
+
|
|
24
|
+
// List of default plugins uninstalled from a generated app
|
|
25
|
+
const missingPlugins = DEFAULT_PLUGINS.filter(x => !Object.keys(plugins).includes(x));
|
|
26
|
+
|
|
27
|
+
const diff = [...installedPlugins, ...missingPlugins];
|
|
28
|
+
|
|
29
|
+
return diff.length > 0;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const hasCustomAdminCode = async (dir, useTypeScript) => {
|
|
33
|
+
const customAdminPath = path.join(dir, 'src', 'admin');
|
|
34
|
+
const customAdminConfigFileExtension = useTypeScript ? 'app.tsx' : 'app.js';
|
|
35
|
+
const customAdminConfigFile = path.join(customAdminPath, customAdminConfigFileExtension);
|
|
36
|
+
const customAdminWebpackFile = path.join(customAdminPath, 'webpack.config.js');
|
|
37
|
+
|
|
38
|
+
const hasCustomConfigFile = await fs.pathExists(customAdminConfigFile);
|
|
39
|
+
const hasCustomWebpackFile = await fs.pathExists(customAdminWebpackFile);
|
|
40
|
+
|
|
41
|
+
return hasCustomConfigFile || hasCustomWebpackFile;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const shouldBuildAdmin = async ({ appDir, plugins, useTypeScript }) => {
|
|
45
|
+
const appHasCustomAdminCode = await hasCustomAdminCode(appDir, useTypeScript);
|
|
46
|
+
const appHasNonDefaultPlugins = hasNonDefaultPlugins(plugins);
|
|
47
|
+
|
|
48
|
+
return appHasCustomAdminCode || appHasNonDefaultPlugins;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
module.exports = shouldBuildAdmin;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const chokidar = require('chokidar');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Listen to files change and copy the changed files in the .cache/admin folder
|
|
9
|
+
* when using the dev mode
|
|
10
|
+
* @param {string} dir
|
|
11
|
+
*/
|
|
12
|
+
async function watchAdminFiles(dir, useTypeScript) {
|
|
13
|
+
const cacheDir = path.join(dir, '.cache');
|
|
14
|
+
const targetExtensionFile = useTypeScript ? 'app.tsx' : 'app.js';
|
|
15
|
+
const appExtensionFile = path.join(dir, 'src', 'admin', targetExtensionFile);
|
|
16
|
+
const extensionsPath = path.join(dir, 'src', 'admin', 'extensions');
|
|
17
|
+
|
|
18
|
+
// Only watch the admin/app.js file and the files that are in the ./admin/extensions/folder
|
|
19
|
+
const filesToWatch = [appExtensionFile, extensionsPath];
|
|
20
|
+
|
|
21
|
+
const watcher = chokidar.watch(filesToWatch, {
|
|
22
|
+
ignoreInitial: true,
|
|
23
|
+
ignorePermissionErrors: true,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
watcher.on('all', async (event, filePath) => {
|
|
27
|
+
const isAppFile = filePath.includes(appExtensionFile);
|
|
28
|
+
|
|
29
|
+
// The app.js file needs to be copied in the .cache/admin/src/app.js and the other ones needs to
|
|
30
|
+
// be copied in the .cache/admin/src/extensions folder
|
|
31
|
+
const targetPath = isAppFile
|
|
32
|
+
? path.join(path.normalize(filePath.split(appExtensionFile)[1]), targetExtensionFile)
|
|
33
|
+
: path.join('extensions', path.normalize(filePath.split(extensionsPath)[1]));
|
|
34
|
+
|
|
35
|
+
const destFolder = path.join(cacheDir, 'admin', 'src');
|
|
36
|
+
|
|
37
|
+
if (event === 'unlink' || event === 'unlinkDir') {
|
|
38
|
+
// Remove the file or folder
|
|
39
|
+
// We need to copy the original files when deleting an override one
|
|
40
|
+
try {
|
|
41
|
+
fs.removeSync(path.join(destFolder, targetPath));
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.log('An error occured while deleting the file', err);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
// In any other case just copy the file into the .cache/admin/src folder
|
|
47
|
+
try {
|
|
48
|
+
await fs.copy(filePath, path.join(destFolder, targetPath));
|
|
49
|
+
} catch (err) {
|
|
50
|
+
console.log(err);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = watchAdminFiles;
|
package/webpack.config.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const webpack = require('webpack');
|
|
5
5
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
6
|
+
const ForkTsCheckerPlugin = require('fork-ts-checker-webpack-plugin');
|
|
6
7
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
7
8
|
const TerserPlugin = require('terser-webpack-plugin');
|
|
8
9
|
const WebpackBar = require('webpackbar');
|
|
@@ -12,12 +13,13 @@ const alias = require('./webpack.alias');
|
|
|
12
13
|
const getClientEnvironment = require('./env');
|
|
13
14
|
|
|
14
15
|
module.exports = ({
|
|
15
|
-
|
|
16
|
+
appDir,
|
|
16
17
|
cacheDir,
|
|
17
|
-
pluginsPath,
|
|
18
18
|
dest,
|
|
19
|
+
entry,
|
|
19
20
|
env,
|
|
20
21
|
optimize,
|
|
22
|
+
pluginsPath,
|
|
21
23
|
options = {
|
|
22
24
|
backend: 'http://localhost:1337',
|
|
23
25
|
adminPath: '/admin/',
|
|
@@ -27,6 +29,7 @@ module.exports = ({
|
|
|
27
29
|
eeRoot: './ee/admin',
|
|
28
30
|
ceRoot: './admin/src',
|
|
29
31
|
},
|
|
32
|
+
useTypeScript,
|
|
30
33
|
}) => {
|
|
31
34
|
const isProduction = env === 'production';
|
|
32
35
|
|
|
@@ -47,6 +50,35 @@ module.exports = ({
|
|
|
47
50
|
]
|
|
48
51
|
: [];
|
|
49
52
|
|
|
53
|
+
if (useTypeScript) {
|
|
54
|
+
const tsChecker = new ForkTsCheckerPlugin({
|
|
55
|
+
typescript: {
|
|
56
|
+
// FIXME
|
|
57
|
+
configFile: path.join(appDir, 'tsconfig-admin.json'),
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
webpackPlugins.push(tsChecker);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const rules = [];
|
|
65
|
+
|
|
66
|
+
// webpack is quite slow to compile so it is best not to use the ts loader when
|
|
67
|
+
// it is not needed in javascript apps.
|
|
68
|
+
// Users can still add it by using the custom webpack config.
|
|
69
|
+
if (useTypeScript) {
|
|
70
|
+
rules.push({
|
|
71
|
+
test: /\.tsx?$/,
|
|
72
|
+
loader: require.resolve('esbuild-loader'),
|
|
73
|
+
include: [cacheDir, ...pluginsPath],
|
|
74
|
+
exclude: /node_modules/,
|
|
75
|
+
options: {
|
|
76
|
+
loader: 'tsx',
|
|
77
|
+
target: 'es2015',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
50
82
|
return {
|
|
51
83
|
mode: isProduction ? 'production' : 'development',
|
|
52
84
|
bail: isProduction ? true : false,
|
|
@@ -166,12 +198,13 @@ module.exports = ({
|
|
|
166
198
|
},
|
|
167
199
|
},
|
|
168
200
|
},
|
|
201
|
+
...rules,
|
|
169
202
|
],
|
|
170
203
|
},
|
|
171
204
|
resolve: {
|
|
172
205
|
alias,
|
|
173
206
|
symlinks: false,
|
|
174
|
-
extensions: ['.js', '.jsx', '.react.js'],
|
|
207
|
+
extensions: ['.js', '.jsx', '.react.js', '.ts', '.tsx'],
|
|
175
208
|
mainFields: ['browser', 'jsnext:main', 'main'],
|
|
176
209
|
modules: ['node_modules', path.resolve(__dirname, 'node_modules')],
|
|
177
210
|
},
|
package/.env
DELETED
|
File without changes
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import { useIntl } from 'react-intl';
|
|
4
|
-
|
|
5
|
-
const useFetchPluginsFromMarketPlace = () => {
|
|
6
|
-
const { locale: currentLocale } = useIntl();
|
|
7
|
-
const [state, setState] = useState({
|
|
8
|
-
error: false,
|
|
9
|
-
isLoading: true,
|
|
10
|
-
data: null,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
const CancelToken = axios.CancelToken;
|
|
15
|
-
const source = CancelToken.source();
|
|
16
|
-
|
|
17
|
-
const getData = async () => {
|
|
18
|
-
try {
|
|
19
|
-
const { data } = await axios.get('https://marketplace.strapi.io/plugins', {
|
|
20
|
-
cancelToken: source.token,
|
|
21
|
-
params: { lang: currentLocale },
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
setState({
|
|
25
|
-
isLoading: false,
|
|
26
|
-
data,
|
|
27
|
-
error: false,
|
|
28
|
-
});
|
|
29
|
-
} catch (err) {
|
|
30
|
-
if (axios.isCancel(err)) {
|
|
31
|
-
// Silent
|
|
32
|
-
} else {
|
|
33
|
-
// handle error
|
|
34
|
-
setState(prev => ({ ...prev, isLoading: false, error: true }));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
getData();
|
|
40
|
-
|
|
41
|
-
return () => {
|
|
42
|
-
source.cancel();
|
|
43
|
-
};
|
|
44
|
-
}, [currentLocale]);
|
|
45
|
-
|
|
46
|
-
return state;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export default useFetchPluginsFromMarketPlace;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import styled from 'styled-components';
|
|
2
|
-
|
|
3
|
-
// TODO : To migrate with @strapi/design-system
|
|
4
|
-
const Wrapper = styled.div`
|
|
5
|
-
display: flex;
|
|
6
|
-
align-items: center;
|
|
7
|
-
margin-top: 2rem;
|
|
8
|
-
border-radius: 4px;
|
|
9
|
-
border-left: 4px solid ${({ theme }) => theme.main.colors.mediumBlue};
|
|
10
|
-
box-shadow: 0 2px 4px ${({ theme }) => theme.main.colors.darkGrey};
|
|
11
|
-
padding: 8px 16px;
|
|
12
|
-
|
|
13
|
-
.bannerImage {
|
|
14
|
-
width: 48px;
|
|
15
|
-
height: 48px;
|
|
16
|
-
margin-right: 16px;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.bannerLink {
|
|
20
|
-
color: ${({ theme }) => theme.main.colors.mediumBlue};
|
|
21
|
-
font-weight: ${({ theme }) => theme.main.fontWeights.bold};
|
|
22
|
-
svg {
|
|
23
|
-
margin-left: 4px;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
`;
|
|
27
|
-
|
|
28
|
-
export default Wrapper;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { FormattedMessage, useIntl } from 'react-intl';
|
|
3
|
-
import { useTracking } from '@strapi/helper-plugin';
|
|
4
|
-
import Wrapper from './Wrapper';
|
|
5
|
-
import LogoStrapi from '../../../assets/images/banner_strapi-rocket.png';
|
|
6
|
-
|
|
7
|
-
const MarketplaceBanner = () => {
|
|
8
|
-
const { formatMessage } = useIntl();
|
|
9
|
-
const { trackUsage } = useTracking();
|
|
10
|
-
|
|
11
|
-
return (
|
|
12
|
-
<Wrapper>
|
|
13
|
-
<img
|
|
14
|
-
className="bannerImage"
|
|
15
|
-
src={LogoStrapi}
|
|
16
|
-
alt={formatMessage({ id: 'app.components.MarketplaceBanner.image.alt' })}
|
|
17
|
-
/>
|
|
18
|
-
<div>
|
|
19
|
-
<div>
|
|
20
|
-
<FormattedMessage id="app.components.MarketplaceBanner" />
|
|
21
|
-
</div>
|
|
22
|
-
<a
|
|
23
|
-
href="https://github.com/strapi/awesome-strapi"
|
|
24
|
-
target="_blank"
|
|
25
|
-
rel="noopener noreferrer"
|
|
26
|
-
className="bannerLink"
|
|
27
|
-
onClick={() => trackUsage('didGoToStrapiAwesome')}
|
|
28
|
-
>
|
|
29
|
-
<FormattedMessage id="app.components.MarketplaceBanner.link" />
|
|
30
|
-
<i className="fa fa-external-link-alt" />
|
|
31
|
-
</a>
|
|
32
|
-
</div>
|
|
33
|
-
</Wrapper>
|
|
34
|
-
);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export default MarketplaceBanner;
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import styled from 'styled-components';
|
|
2
|
-
|
|
3
|
-
const Wrapper = styled.div`
|
|
4
|
-
.wrapper {
|
|
5
|
-
position: relative;
|
|
6
|
-
min-height: 216px;
|
|
7
|
-
margin-bottom: 3.6rem;
|
|
8
|
-
padding: 1.2rem 1.5rem;
|
|
9
|
-
padding-bottom: 0;
|
|
10
|
-
background-color: #fff;
|
|
11
|
-
box-shadow: 0 2px 4px #e3e9f3;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.cardTitle {
|
|
16
|
-
display: flex;
|
|
17
|
-
font-size: 13px;
|
|
18
|
-
font-weight: 600;
|
|
19
|
-
text-transform: uppercase;
|
|
20
|
-
letter-spacing: 0.5px;
|
|
21
|
-
|
|
22
|
-
> div:first-child {
|
|
23
|
-
margin-right: 14px;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
> div:last-child {
|
|
27
|
-
height: 36px;
|
|
28
|
-
line-height: 36px;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
i,
|
|
32
|
-
svg {
|
|
33
|
-
margin-left: 7px;
|
|
34
|
-
color: #b3b5b9;
|
|
35
|
-
font-size: 1rem;
|
|
36
|
-
vertical-align: baseline;
|
|
37
|
-
cursor: pointer;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.cardDescription {
|
|
42
|
-
height: 54px;
|
|
43
|
-
margin-top: 27px;
|
|
44
|
-
margin-bottom: 9px;
|
|
45
|
-
font-size: 13px;
|
|
46
|
-
font-weight: 400;
|
|
47
|
-
|
|
48
|
-
> span:last-child {
|
|
49
|
-
color: #1c5de7;
|
|
50
|
-
}
|
|
51
|
-
-webkit-font-smoothing: antialiased;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
.cardFooter {
|
|
55
|
-
position: absolute;
|
|
56
|
-
bottom: 0;
|
|
57
|
-
left: 0;
|
|
58
|
-
display: flex;
|
|
59
|
-
width: 100%;
|
|
60
|
-
height: 45px;
|
|
61
|
-
padding: 0.9rem 1.5rem 1rem;
|
|
62
|
-
background-color: #fafafb;
|
|
63
|
-
justify-content: space-between;
|
|
64
|
-
flex-direction: row-reverse;
|
|
65
|
-
cursor: initial;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.compatible {
|
|
69
|
-
margin-top: 3px;
|
|
70
|
-
color: #5a9e06;
|
|
71
|
-
font-size: 1.3rem;
|
|
72
|
-
font-style: italic;
|
|
73
|
-
|
|
74
|
-
> i,
|
|
75
|
-
> svg {
|
|
76
|
-
margin-right: 7px;
|
|
77
|
-
font-size: 12px;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
.settings {
|
|
82
|
-
margin-top: 3px;
|
|
83
|
-
color: #323740;
|
|
84
|
-
font-size: 1.3rem;
|
|
85
|
-
font-weight: 500;
|
|
86
|
-
cursor: pointer;
|
|
87
|
-
|
|
88
|
-
> i,
|
|
89
|
-
> svg {
|
|
90
|
-
margin-right: 7px;
|
|
91
|
-
font-size: 11px;
|
|
92
|
-
vertical-align: inherit;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.button {
|
|
97
|
-
height: 26px;
|
|
98
|
-
min-width: 89px !important;
|
|
99
|
-
padding: 0 15px;
|
|
100
|
-
margin: 0;
|
|
101
|
-
border-radius: 2px !important;
|
|
102
|
-
line-height: 23px;
|
|
103
|
-
font-size: 13px;
|
|
104
|
-
cursor: pointer;
|
|
105
|
-
span {
|
|
106
|
-
display: inline-block;
|
|
107
|
-
width: 100%;
|
|
108
|
-
height: 100%;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
.frame {
|
|
113
|
-
width: 70px;
|
|
114
|
-
height: 36px;
|
|
115
|
-
margin: auto 0;
|
|
116
|
-
text-align: center;
|
|
117
|
-
border: 1px solid #f3f3f7;
|
|
118
|
-
border-radius: 3px;
|
|
119
|
-
white-space: nowrap;
|
|
120
|
-
> img {
|
|
121
|
-
max-height: 36px;
|
|
122
|
-
vertical-align: middle;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.helper {
|
|
127
|
-
display: inline-block;
|
|
128
|
-
height: 100%;
|
|
129
|
-
vertical-align: middle;
|
|
130
|
-
}
|
|
131
|
-
.primary {
|
|
132
|
-
background: linear-gradient(315deg, #0097f6 0%, #005eea 100%);
|
|
133
|
-
color: white;
|
|
134
|
-
font-weight: 500;
|
|
135
|
-
-webkit-font-smoothing: antialiased;
|
|
136
|
-
|
|
137
|
-
&:active {
|
|
138
|
-
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.15);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
.secondary {
|
|
143
|
-
border: 1px solid #dfe0e1;
|
|
144
|
-
font-weight: 600;
|
|
145
|
-
}
|
|
146
|
-
`;
|
|
147
|
-
|
|
148
|
-
export default Wrapper;
|