Retrieve plugins' icons URL from API and name Redux store

This commit is contained in:
Aurelsicoko 2018-01-05 16:19:53 +01:00
parent 12d1357d36
commit c9d47b1fed
17 changed files with 94 additions and 26 deletions

View File

@ -215,6 +215,7 @@ window.strapi = Object.assign(window.strapi || {}, {
}),
router: history,
languages,
currentLanguage: window.localStorage.getItem('strapi-admin-language') || window.navigator.language || window.navigator.userLanguage || 'en',
});
const dispatch = store.dispatch;

View File

@ -59,7 +59,7 @@ class InstallPluginPopup extends React.Component {
<div className={styles.wrapper}>
<div className={styles.headerWrapper}>
<div className={styles.logo}><img src={`${this.props.plugin.logo}?sanitize=true`} alt="icon" /></div>
<div className={styles.logo}><img src={`${this.props.plugin.logo}`} alt="icon" /></div>
<div className={styles.headerInfo}>
<div className={styles.name}>{this.props.plugin.name}</div>
<div className={styles.ratings}>
@ -73,7 +73,7 @@ class InstallPluginPopup extends React.Component {
<Official style={{ marginTop: '0' }} />
</div>
<div className={styles.headerDescription}>
<FormattedMessage id={this.props.plugin.description.long || this.props.plugin.description.short} />
{this.props.plugin.description.short}
</div>
<div className={styles.headerButtonContainer}>
<div>
@ -120,7 +120,7 @@ class InstallPluginPopup extends React.Component {
})}
</div>
<div className={styles.pluginDescription}>
{this.props.plugin.longDescription}
{this.props.plugin.description.long || this.props.plugin.description.short}
</div>
</ModalBody>
</Modal>
@ -132,11 +132,17 @@ InstallPluginPopup.contextTypes = {
downloadPlugin: PropTypes.func.isRequired,
};
InstallPluginPopup.defaultProps = {
description: {
short: 'No description available',
},
};
InstallPluginPopup.propTypes = {
description: PropTypes.shape({
long: PropTypes.string,
short: PropTypes.string,
}).isRequired,
}),
history: PropTypes.object.isRequired,
isOpen: PropTypes.bool.isRequired,
plugin: PropTypes.object.isRequired,

View File

@ -83,7 +83,7 @@ class PluginCard extends React.Component {
const pluginIcon = this.props.plugin.id !== 'email' ? (
<div className={styles.frame}>
<span className={styles.helper} />
<img src={`${this.props.plugin.logo}?sanitize=true`} alt="icon" />
<img src={`${this.props.plugin.logo}`} alt="icon" />
</div>
) : (
<div className={styles.iconContainer}><i className={`fa fa-${this.props.plugin.icon}`} /></div>
@ -97,7 +97,7 @@ class PluginCard extends React.Component {
<div>{this.props.plugin.name}</div>
</div>
<div className={styles.cardDescription}>
<FormattedMessage id={this.props.plugin.description.short} />
{this.props.plugin.description.short}
&nbsp;<FormattedMessage id="app.components.PluginCard.more-details" />
</div>
<div className={styles.cardScreenshot} style={{ backgroundImage: `url(${Screenshot})` }}>
@ -124,7 +124,7 @@ class PluginCard extends React.Component {
<Button
className={cn(buttonClass, styles.button)}
label={buttonLabel}
onClick={this.props.handleDownloadPlugin}
onClick={this.handleDownloadPlugin}
/>
<a
href="mailto:hi@strapi.io?subject=I'd like to support Strapi"
@ -162,7 +162,6 @@ PluginCard.defaultProps = {
PluginCard.propTypes = {
downloadPlugin: PropTypes.func.isRequired,
handleDownloadPlugin: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
isAlreadyInstalled: PropTypes.bool,
plugin: PropTypes.object,

View File

@ -35,7 +35,7 @@ class Row extends React.Component {
<ListRow>
<div className={cn("col-md-11", styles.nameWrapper)}>
<div className={styles.icoContainer} style={{ marginRight: '30px' }}>
<img src={`${this.props.plugin.logo}?sanitize=true`} alt="icon" />
<img src={`${this.props.plugin.logo}`} alt="icon" />
</div>
<div className={styles.pluginContent}>
<span>{this.props.plugin.name} &nbsp;</span>

View File

@ -11,6 +11,7 @@ import {
import request from 'utils/request';
import { selectLocale } from '../LanguageProvider/selectors';
import {
downloadPluginError,
downloadPluginSucceeded,
@ -19,6 +20,7 @@ import {
import { DOWNLOAD_PLUGIN, GET_PLUGINS } from './constants';
import { makeSelectPluginToDownload } from './selectors';
export function* pluginDownload() {
try {
const pluginToDownload = yield select(makeSelectPluginToDownload());
@ -45,13 +47,23 @@ export function* pluginDownload() {
export function* pluginsGet() {
try {
// Get current locale.
const locale = yield select(selectLocale());
const opts = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
params: {
lang: locale,
},
};
// Retrieve plugins list.
const availablePlugins = yield call(request, 'https://marketplace.strapi.io/plugins', opts);
// Add support us card to the plugins list.
const supportUs = {
description: {
short: 'app.components.InstallPluginPage.plugin.support-us.description',

View File

@ -35,6 +35,8 @@ function languageProviderReducer(state = initialState, action) {
case CHANGE_LOCALE:
// Set user language in local storage.
window.localStorage.setItem(localStorageKey, action.locale);
strapi.currentLanguage = action.locale;
return state
.set('locale', action.locale);
default:

View File

@ -4,6 +4,7 @@ import { pluginDeleted } from 'containers/App/actions';
import auth from 'utils/auth';
import request from 'utils/request';
import { selectLocale } from '../LanguageProvider/selectors';
import { deletePluginSucceeded, getPluginsSucceeded } from './actions';
import { GET_PLUGINS, ON_DELETE_PLUGIN_CONFIRM } from './constants';
import { makeSelectPluginToDelete } from './selectors';
@ -34,12 +35,16 @@ export function* pluginsGet() {
try {
// Fetch plugins.
const response = yield call(request, '/admin/plugins', { method: 'GET' });
const locale = yield select(selectLocale());
const opts = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
params: {
lang: locale,
},
};
// Fetch plugins informations.

View File

@ -33,6 +33,7 @@ export default function configureStore(initialState = {}, history) {
// TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading
// Prevent recomputing reducers for `replaceReducer`
shouldHotReload: false,
name: `Strapi - Dashboard`,
})
: compose;
/* eslint-enable */

File diff suppressed because one or more lines are too long

View File

@ -53,7 +53,7 @@ const apiUrl = `${strapi.backendURL}/${pluginId}`;
const router = strapi.router;
// Create redux store with Strapi admin history
const store = configureStore({}, strapi.router);
const store = configureStore({}, strapi.router, pluginName);
// Define the plugin root component
function Comp(props) {

View File

@ -10,7 +10,7 @@ import createReducer from './reducers';
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, history) {
export default function configureStore(initialState = {}, history, name) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
@ -33,6 +33,7 @@ export default function configureStore(initialState = {}, history) {
// TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading
// Prevent recomputing reducers for `replaceReducer`
shouldHotReload: false,
name: `Plugin - ${name}`,
})
: compose;
/* eslint-enable */

View File

@ -55,7 +55,7 @@ class Plugin extends React.Component { // eslint-disable-line react/prefer-state
<div>
{ icon ? (
<div className={styles.iconContainer}>
<i className={`fa fa-${icon}`} />
<img src={this.props.plugin.information.logo} alt="icon" />
</div>
) : ''}
<div className={styles.name}>{this.props.name}</div>
@ -107,6 +107,7 @@ Plugin.defaultProps = {
plugin: {
description: 'users-permissions.Plugin.permissions.description.empty',
controllers: {},
information: {},
},
};
@ -115,6 +116,9 @@ Plugin.propTypes = {
name: PropTypes.string,
plugin: PropTypes.shape({
description: PropTypes.string,
information: PropTypes.shape({
logo: PropTypes.string.isRequired,
}).isRequired,
}),
pluginSelected: PropTypes.string.isRequired,
};

View File

@ -45,7 +45,13 @@ export function* fetchUser(action) {
export function* permissionsGet() {
try {
const response = yield call(request, '/users-permissions/permissions', { method: 'GET' });
const response = yield call(request, '/users-permissions/permissions', {
method: 'GET',
params: {
lang: strapi.currentLanguage,
},
});
yield put(getPermissionsSucceeded(response));
} catch(err) {
strapi.notification.error('users-permissions.EditPage.notification.permissions.error');
@ -68,7 +74,12 @@ export function* policiesGet() {
export function* roleGet(action) {
try {
const role = yield call(request, `/users-permissions/roles/${action.id}`, { method: 'GET' });
const role = yield call(request, `/users-permissions/roles/${action.id}`, {
method: 'GET',
params: {
lang: strapi.currentLanguage,
},
});
yield put(getRoleSucceeded(role));
} catch(err) {

View File

@ -5,11 +5,6 @@ import { createSelector } from 'reselect';
*/
const selectEditPageDomain = () => (state) => state.get('editPage');
/**
* Other specific selectors
*/
/**
* Default selector used by EditPage
*/

View File

@ -60,7 +60,9 @@ module.exports = {
getPermissions: async (ctx) => {
try {
const permissions = await strapi.plugins['users-permissions'].services.userspermissions.getActions();
const { lang } = ctx.query;
const plugins = await strapi.plugins['users-permissions'].services.userspermissions.getPlugins(lang);
const permissions = await strapi.plugins['users-permissions'].services.userspermissions.getActions(plugins);
ctx.send({ permissions });
} catch(err) {
ctx.badRequest(null, [{ message: [{ id: 'Not Found' }] }]);
@ -75,7 +77,9 @@ module.exports = {
getRole: async (ctx) => {
const { id } = ctx.params;
const role = await strapi.plugins['users-permissions'].services.userspermissions.getRole(id);
const { lang } = ctx.query;
const plugins = await strapi.plugins['users-permissions'].services.userspermissions.getPlugins(lang);
const role = await strapi.plugins['users-permissions'].services.userspermissions.getRole(id, plugins);
if (_.isEmpty(role)) {
return ctx.badRequest(null, [{ messages: [{ id: `Role don't exist` }] }]);

View File

@ -26,6 +26,7 @@
"dependencies": {
"bcryptjs": "^2.4.3",
"jsonwebtoken": "^8.1.0",
"request": "^2.83.0",
"uuid": "^3.1.0"
},
"devDependencies": {

View File

@ -4,6 +4,7 @@ const fs = require('fs')
const path = require('path');
const stringify = JSON.stringify;
const _ = require('lodash');
const request = require('request');
/**
* UsersPermissions.js service
@ -40,7 +41,25 @@ module.exports = {
});
},
getActions: () => {
getPlugins: (plugin, lang = 'en') => {
return new Promise((resolve, reject) => {
request({
uri: `https://marketplace.strapi.io/plugins?lang=${lang}`,
json: true,
headers: {
'cache-control': 'max-age=3600'
}
}, (err, response, body) => {
if (err) {
return reject(err);
}
resolve(body);
});
});
},
getActions: (plugins = []) => {
const generateActions = (data) => (
Object.keys(data).reduce((acc, key) => {
acc[key] = { enabled: false, policy: '' };
@ -60,7 +79,7 @@ module.exports = {
return obj;
}, { controllers: {} });
}, { controllers: {}, information: plugins.find(plugin => plugin.id === key) || {} });
return acc;
}, {});
@ -74,10 +93,17 @@ module.exports = {
return _.merge(permissions, pluginsPermissions);;
},
getRole: async (roleId) => {
const appRoles = strapi.plugins['users-permissions'].config.roles
getRole: async (roleId, plugins) => {
const appRoles = strapi.plugins['users-permissions'].config.roles;
appRoles[roleId].users = await strapi.query('user', 'users-permissions').find(strapi.utils.models.convertParams('user', { role: roleId }));
Object.keys(appRoles[roleId].permissions)
.filter(name => name !== 'application')
.map(name => {
appRoles[roleId].permissions[name].information = plugins.find(plugin => plugin.id === name) || {};
});
return appRoles[roleId];
},