Add handler to get the app installed plugins

This commit is contained in:
cyril lopez 2017-11-09 11:25:01 +01:00
parent 2418686b7b
commit f3bddb77c8
9 changed files with 92 additions and 23 deletions

View File

@ -5,15 +5,29 @@
*/
import {
DEFAULT_ACTION,
GET_PLUGINS,
GET_PLUGINS_SUCCEEDED,
ON_DELETE_PLUGIN_CLICK,
ON_DELETE_PLUGIN_CONFIRM,
DELETE_PLUGIN_SUCCEEDED,
} from './constants';
export function defaultAction() {
export function getPlugins() {
return {
type: DEFAULT_ACTION,
type: GET_PLUGINS,
};
}
export function getPluginsSucceeded(data) {
const plugins = Object.keys(data.plugins).reduce((acc, key) => {
acc[key] = data.plugins[key].package.strapi;
return acc;
}, {});
return {
type: GET_PLUGINS_SUCCEEDED,
plugins,
};
}
@ -30,8 +44,9 @@ export function onDeletePluginConfirm() {
};
}
export function deletePluginSucceeded() {
export function deletePluginSucceeded(plugin) {
return {
type: DELETE_PLUGIN_SUCCEEDED,
plugin,
};
}

View File

@ -4,7 +4,8 @@
*
*/
export const DEFAULT_ACTION = 'StrapiAdmin/ListPluginsPage/DEFAULT_ACTION';
export const GET_PLUGINS = 'StrapiAdmin/ListPluginsPage/GET_PLUGINS';
export const GET_PLUGINS_SUCCEEDED = 'StrapiAdmin/ListPluginsPage/GET_PLUGINS_SUCCEEDED';
export const ON_DELETE_PLUGIN_CLICK = 'StrapiAdmin/ListPluginsPage/ON_DELETE_PLUGIN_CLICK';
export const ON_DELETE_PLUGIN_CONFIRM = 'StrapiAdmin/ListPluginsPage/ON_DELETE_PLUGIN_CONFIRM';
export const DELETE_PLUGIN_SUCCEEDED = 'StrapiAdmin/ListPluginsPage/DELETE_PLUGIN_SUCCEEDED';

View File

@ -18,13 +18,17 @@ import ListPlugins from 'components/ListPlugins';
import injectSaga from 'utils/injectSaga';
import injectReducer from 'utils/injectReducer';
import { makeSelectPluginDeleteAction } from './selectors';
import { onDeletePluginClick, onDeletePluginConfirm } from './actions';
import { makeSelectPluginDeleteAction, makeSelectPlugins } from './selectors';
import { getPlugins, onDeletePluginClick, onDeletePluginConfirm } from './actions';
import reducer from './reducer';
import saga from './saga';
import styles from './styles.scss';
export class ListPluginsPage extends React.Component { // eslint-disable-line react/prefer-stateless-function
componentDidMount() {
this.props.getPlugins();
}
render() {
return (
<div>
@ -48,7 +52,7 @@ export class ListPluginsPage extends React.Component { // eslint-disable-line re
/>
<ListPlugins
history={this.props.history}
plugins={this.context.plugins.toJS()}
plugins={this.props.plugins}
pluginActionSucceeded={this.props.pluginActionSucceeded}
onDeleteClick={this.props.onDeletePluginClick}
onDeleteConfirm={this.props.onDeletePluginConfirm}
@ -60,23 +64,27 @@ export class ListPluginsPage extends React.Component { // eslint-disable-line re
}
ListPluginsPage.contextTypes = {
plugins: PropTypes.object,
// plugins: PropTypes.object,
};
ListPluginsPage.propTypes = {
getPlugins: PropTypes.func.isRequired,
history: PropTypes.object.isRequired,
onDeletePluginClick: PropTypes.func.isRequired,
onDeletePluginConfirm: PropTypes.func.isRequired,
pluginActionSucceeded: PropTypes.bool.isRequired,
plugins: PropTypes.object.isRequired,
};
const mapStateToProps = createStructuredSelector({
pluginActionSucceeded: makeSelectPluginDeleteAction(),
plugins: makeSelectPlugins(),
});
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
getPlugins,
onDeletePluginClick,
onDeletePluginConfirm,
},

View File

@ -4,26 +4,37 @@
*
*/
import { fromJS } from 'immutable';
import { fromJS, Map } from 'immutable';
import {
DEFAULT_ACTION,
ON_DELETE_PLUGIN_CLICK,
DELETE_PLUGIN_SUCCEEDED,
GET_PLUGINS_SUCCEEDED,
ON_DELETE_PLUGIN_CLICK,
} from './constants';
const initialState = fromJS({
pluginToDelete: '',
deleteActionSucceeded: false,
plugins: Map({}),
pluginToDelete: '',
});
function listPluginsPageReducer(state = initialState, action) {
switch (action.type) {
case DEFAULT_ACTION:
return state;
case DELETE_PLUGIN_SUCCEEDED: {
if (action.plugin) {
return state
.deleteIn(['plugins', action.plugin])
.set('deleteActionSucceeded', !state.get('deleteActionSucceeded'));
}
return state
.set('deleteActionSucceeded', !state.get('deleteActionSucceeded'));
}
case GET_PLUGINS_SUCCEEDED:
return state
.set('plugins', Map(action.plugins));
case ON_DELETE_PLUGIN_CLICK:
return state.set('pluginToDelete', action.pluginToDelete);
case DELETE_PLUGIN_SUCCEEDED:
return state.set('deleteActionSucceeded', !state.get('deleteActionSucceeded'));
return state
.set('pluginToDelete', action.pluginToDelete);
default:
return state;
}

View File

@ -3,8 +3,8 @@ import { fork, call, put, select, takeLatest } from 'redux-saga/effects';
import { pluginDeleted } from 'containers/App/actions';
import request from 'utils/request';
import { deletePluginSucceeded } from './actions';
import { ON_DELETE_PLUGIN_CONFIRM } from './constants';
import { deletePluginSucceeded, getPluginsSucceeded } from './actions';
import { GET_PLUGINS, ON_DELETE_PLUGIN_CONFIRM } from './constants';
import { makeSelectPluginToDelete } from './selectors';
export function* deletePlugin() {
@ -15,16 +15,27 @@ export function* deletePlugin() {
const resp = yield call(request, requestUrl, { method: 'DELETE' });
if (resp.ok) {
yield put(deletePluginSucceeded());
yield put(deletePluginSucceeded(plugin));
yield put(pluginDeleted(plugin));
}
} catch(error) {
yield put(deletePluginSucceeded());
yield put(deletePluginSucceeded(false));
window.Strapi.notification.error('app.components.listPluginsPage.deletePlugin.error');
}
}
export function* pluginsGet() {
try {
const response = yield call(request, '/admin/plugins', { method: 'GET' });
yield put(getPluginsSucceeded(response));
} catch(err) {
window.Strapi.notification.error('app.components.listPluginsPage.deletePlugin.error');
}
}
// Individual exports for testing
export default function* defaultSaga() {
yield fork(takeLatest, ON_DELETE_PLUGIN_CONFIRM, deletePlugin);
yield fork(takeLatest, GET_PLUGINS, pluginsGet);
}

View File

@ -29,9 +29,15 @@ const makeSelectPluginDeleteAction = () => createSelector(
(substate) => substate.get('deleteActionSucceeded'),
);
const makeSelectPlugins = () => createSelector(
selectListPluginsPageDomain(),
(substate) => substate.get('plugins').toJS(),
);
export default makeSelectListPluginsPage;
export {
selectListPluginsPageDomain,
makeSelectPluginToDelete,
makeSelectPluginDeleteAction,
makeSelectPlugins,
};

View File

@ -8,6 +8,14 @@
"policies": []
}
},
{
"method": "GET",
"path": "/plugins",
"handler": "Admin.plugins",
"config": {
"policies": []
}
},
{
"method": "GET",
"path": "/:plugin/:file",

View File

@ -43,6 +43,14 @@ module.exports = {
}
},
plugins: async ctx => {
try {
ctx.send({ plugins: strapi.plugins });
} catch(err) {
ctx.badRequest(null, [{ messages: [{ id: 'An error occured' }] }]);
}
},
uninstallPlugin: async ctx => {
try {
const { plugin } = ctx.params;

View File

@ -32,7 +32,8 @@ module.exports = function() {
}),
new Promise((resolve, reject) => {
// Load configurations.
glob('./plugins/*/!(config|node_modules)/*.*(js|json)', {}, (err, files) => {
glob('{./plugins/*/!(config|node_modules)/*.*(js|json),./plugins/*/package.json}', {}, (err, files) => {
if (err) {
return reject(err);
}