Remove immutable in App page

Signed-off-by: soupette <cyril.lpz@gmail.com>
This commit is contained in:
soupette 2021-05-17 10:54:19 +02:00
parent 949ec26cc7
commit a310d52b72
9 changed files with 46 additions and 254 deletions

View File

@ -36,7 +36,7 @@ import PluginDispatcher from '../PluginDispatcher';
import ProfilePage from '../ProfilePage';
import SettingsPage from '../SettingsPage';
import Logout from './Logout';
import { getInfosDataSucceeded, updatePlugin } from '../App/actions';
import { getInfosDataSucceeded } from '../App/actions';
import makeSelecApp from '../App/selectors';
import { getStrapiLatestReleaseSucceeded, setAppError } from './actions';
import makeSelectAdmin from './selectors';
@ -49,9 +49,7 @@ export class Admin extends React.Component {
// This state is really temporary until we create a menu API
state = { updateMenu: null };
helpers = {
updatePlugin: this.props.updatePlugin,
};
helpers = {};
componentDidMount() {
this.emitEvent('didAccessAuthenticatedAdministration');
@ -173,7 +171,6 @@ export class Admin extends React.Component {
intl: { formatMessage, locale },
// FIXME
plugins,
updatePlugin,
} = this.props;
return (
@ -187,10 +184,9 @@ export class Admin extends React.Component {
disableGlobalOverlayBlocker={() => console.log('todo')}
enableGlobalOverlayBlocker={() => console.log('todo')}
formatMessage={formatMessage}
shouldUpdateStrapi={shouldUpdateStrapi}
plugins={plugins}
shouldUpdateStrapi={shouldUpdateStrapi}
strapiVersion={strapiVersion}
updatePlugin={updatePlugin}
updateMenu={this.state.updateMenu}
>
<Wrapper>
@ -263,7 +259,6 @@ Admin.propTypes = {
}),
plugins: PropTypes.object.isRequired,
setAppError: PropTypes.func.isRequired,
updatePlugin: PropTypes.func.isRequired,
};
const mapStateToProps = createStructuredSelector({
@ -277,7 +272,6 @@ export function mapDispatchToProps(dispatch) {
getInfosDataSucceeded,
getStrapiLatestReleaseSucceeded,
setAppError,
updatePlugin,
},
dispatch
);

View File

@ -1,8 +1,6 @@
import React from 'react';
import { shallow } from 'enzyme';
import { updatePlugin } from '../../App/actions';
import { Admin, mapDispatchToProps } from '../index';
import { setAppError } from '../actions';
@ -28,7 +26,6 @@ describe('<Admin />', () => {
global: {
autoReload: false,
currentEnvironment: 'development',
hasAdminUser: false,
isLoading: true,
strapiVersion: '3',
uuid: false,
@ -38,7 +35,6 @@ describe('<Admin />', () => {
},
location: {},
setAppError: jest.fn(),
updatePlugin: jest.fn(),
};
});
@ -141,21 +137,4 @@ describe('<Admin />, mapDispatchToProps', () => {
expect(dispatch).toHaveBeenCalledWith(setAppError());
});
});
describe('updatePlugin', () => {
it('should be injected', () => {
const dispatch = jest.fn();
const result = mapDispatchToProps(dispatch);
expect(result.updatePlugin).toBeDefined();
});
it('should dispatch the updatePlugin action when called', () => {
const dispatch = jest.fn();
const result = mapDispatchToProps(dispatch);
result.updatePlugin();
expect(dispatch).toHaveBeenCalledWith(updatePlugin());
});
});
});

View File

@ -4,14 +4,7 @@
*
*/
import {
GET_INFOS_DATA_SUCCEEDED,
GET_DATA_SUCCEEDED,
LOAD_PLUGIN,
PLUGIN_DELETED,
PLUGIN_LOADED,
UPDATE_PLUGIN,
} from './constants';
import { GET_INFOS_DATA_SUCCEEDED, GET_DATA_SUCCEEDED } from './constants';
export function getInfosDataSucceeded(data) {
return {
@ -26,33 +19,3 @@ export function getDataSucceeded(data) {
data,
};
}
export function loadPlugin(newPlugin) {
return {
type: LOAD_PLUGIN,
plugin: newPlugin,
};
}
export function pluginDeleted(plugin) {
return {
type: PLUGIN_DELETED,
plugin,
};
}
export function pluginLoaded(newPlugin) {
return {
type: PLUGIN_LOADED,
plugin: newPlugin,
};
}
export function updatePlugin(pluginId, updatedKey, updatedValue) {
return {
type: UPDATE_PLUGIN,
pluginId,
updatedKey,
updatedValue,
};
}

View File

@ -4,9 +4,5 @@
*
*/
export const LOAD_PLUGIN = 'app/App/LOAD_PLUGIN';
export const PLUGIN_LOADED = 'app/App/PLUGIN_LOADED';
export const PLUGIN_DELETED = 'app/App/PLUGIN_DELETED';
export const UPDATE_PLUGIN = 'app/App/UPDATE_PLUGIN';
export const GET_DATA_SUCCEEDED = 'app/App/GET_DATA_SUCCEEDED';
export const GET_INFOS_DATA_SUCCEEDED = 'admin/App/GET_INFOS_DATA_SUCCEEDED';

View File

@ -1,66 +1,44 @@
// Shared constants
import { fromJS } from 'immutable';
/* eslint-disable consistent-return */
import produce from 'immer';
import packageJSON from '../../../../package.json';
import {
GET_INFOS_DATA_SUCCEEDED,
GET_DATA_SUCCEEDED,
PLUGIN_DELETED,
PLUGIN_LOADED,
UPDATE_PLUGIN,
} from './constants';
import { GET_INFOS_DATA_SUCCEEDED, GET_DATA_SUCCEEDED } from './constants';
const packageVersion = packageJSON.version;
// TODO: remove immutable
const initialState = fromJS({
const initialState = {
appInfos: {},
autoReload: false,
currentEnvironment: 'development',
hasAdminUser: false,
isLoading: true,
plugins: {},
strapiVersion: packageVersion,
uuid: false,
});
};
function appReducer(state = initialState, action) {
switch (action.type) {
case GET_INFOS_DATA_SUCCEEDED: {
if (action.data.strapiVersion !== state.get('strapiVersion')) {
console.error(
`It seems that the built version ${packageVersion} is different than your project's one (${action.data.strapiVersion})`
);
console.error('Please delete your `.cache` and `build` folders and restart your app');
const appReducer = (state = initialState, action) =>
produce(state, draftState => {
switch (action.type) {
case GET_INFOS_DATA_SUCCEEDED: {
if (action.data.strapiVersion !== state.strapiVersion) {
console.error(
`It seems that the built version ${packageVersion} is different than your project's one (${action.data.strapiVersion})`
);
console.error('Please delete your `.cache` and `build` folders and restart your app');
}
draftState.appInfos = action.data;
draftState.autoReload = action.data.autoReload;
draftState.currentEnvironment = action.data.currentEnvironment;
break;
}
case GET_DATA_SUCCEEDED: {
draftState.isLoading = false;
draftState.uuid = action.data.uuid;
break;
}
return (
state
.update('appInfos', () => action.data)
// Keep this for plugins legacy
.update('autoReload', () => action.data.autoReload)
.update('currentEnvironment', () => action.data.currentEnvironment)
);
default:
return draftState;
}
case GET_DATA_SUCCEEDED: {
return state
.update('isLoading', () => false)
.update('hasAdminUser', () => action.data.hasAdmin)
.update('uuid', () => action.data.uuid);
}
case PLUGIN_LOADED:
return state.setIn(['plugins', action.plugin.id], fromJS(action.plugin));
case UPDATE_PLUGIN:
return state.setIn(
['plugins', action.pluginId, action.updatedKey],
fromJS(action.updatedValue)
);
case PLUGIN_DELETED:
return state.deleteIn(['plugins', action.plugin]);
default:
return state;
}
}
});
export default appReducer;

View File

@ -9,7 +9,7 @@ const selectApp = () => state => state.app;
* Select the language locale
*/
const makeSelectApp = () => createSelector(selectApp(), appState => appState.toJS());
const makeSelectApp = () => createSelector(selectApp(), appState => appState);
export default makeSelectApp;
export { selectApp };

View File

@ -1,19 +1,5 @@
import {
GET_DATA_SUCCEEDED,
GET_INFOS_DATA_SUCCEEDED,
LOAD_PLUGIN,
PLUGIN_DELETED,
PLUGIN_LOADED,
UPDATE_PLUGIN,
} from '../constants';
import {
loadPlugin,
getInfosDataSucceeded,
getDataSucceeded,
pluginDeleted,
pluginLoaded,
updatePlugin,
} from '../actions';
import { GET_DATA_SUCCEEDED, GET_INFOS_DATA_SUCCEEDED } from '../constants';
import { getInfosDataSucceeded, getDataSucceeded } from '../actions';
describe('<App /> actions', () => {
describe('getDataSucceeded', () => {
@ -39,62 +25,4 @@ describe('<App /> actions', () => {
expect(getInfosDataSucceeded(data)).toEqual(expected);
});
});
describe('loadPlugin', () => {
it('should return the correct type and the passed data', () => {
const plugin = {
id: 'content-manager',
description: 'Manage your content',
};
const expected = {
type: LOAD_PLUGIN,
plugin,
};
expect(loadPlugin(plugin)).toEqual(expected);
});
});
describe('pluginLoaded', () => {
it('should return the correct type and the passed data', () => {
const plugin = {
id: 'content-manager',
description: 'Manage your content',
};
const expected = {
type: PLUGIN_LOADED,
plugin,
};
expect(pluginLoaded(plugin)).toEqual(expected);
});
});
describe('pluginDeleted', () => {
it('should return the correct type and the passed data', () => {
const plugin = 'content-manager';
const expected = {
type: PLUGIN_DELETED,
plugin,
};
expect(pluginDeleted(plugin)).toEqual(expected);
});
});
describe('updatePlugin', () => {
it('should return the correct type and the passed data', () => {
const pluginId = 'content-manager';
const updatedKey = 'isReady';
const updatedValue = true;
const expected = {
type: UPDATE_PLUGIN,
pluginId,
updatedKey,
updatedValue,
};
expect(updatePlugin(pluginId, updatedKey, updatedValue)).toEqual(expected);
});
});
});

View File

@ -1,62 +1,23 @@
import { fromJS } from 'immutable';
import packageJSON from '../../../../../package.json';
import {
getDataSucceeded,
getInfosDataSucceeded,
pluginDeleted,
pluginLoaded,
updatePlugin,
} from '../actions';
import { getDataSucceeded, getInfosDataSucceeded } from '../actions';
import appReducer from '../reducer';
describe('<App /> reducer', () => {
let state;
beforeEach(() => {
state = fromJS({
state = {
appInfos: {},
autoReload: false,
currentEnvironment: 'development',
hasAdminUser: false,
isLoading: true,
plugins: {},
strapiVersion: packageJSON.version,
uuid: false,
});
};
});
it('should return the initial state', () => {
const expectedResult = state.toJS();
expect(appReducer(undefined, {}).toJS()).toEqual(expectedResult);
});
it('should handle the pluginLoaded action correclty', () => {
const plugin = {
id: 'content-manager',
description: 'Manage your content',
};
const expectedResult = state.setIn(['plugins', 'content-manager'], fromJS(plugin));
expect(appReducer(state, pluginLoaded(plugin))).toEqual(expectedResult);
});
it('should handle the updatePlugin action correclty', () => {
const plugin = { id: 'content-manager', isReady: false };
state = state.setIn(['plugins', 'content-manager'], fromJS(plugin));
const expectedResult = state.setIn(['plugins', 'content-manager', 'isReady'], true);
expect(appReducer(state, updatePlugin('content-manager', 'isReady', true))).toEqual(
expectedResult
);
});
it('should handle the pluginDeleted action correclty', () => {
const plugin = { id: 'content-manager', isReady: false };
state = state.setIn(['plugins', 'content-manager'], fromJS(plugin));
const expectedResult = state.deleteIn(['plugins', 'content-manager']);
expect(appReducer(state, pluginDeleted('content-manager'))).toEqual(expectedResult);
expect(appReducer(undefined, {})).toEqual(state);
});
describe('GET_INFOS_DATA_SUCCEEDED', () => {
@ -66,12 +27,10 @@ describe('<App /> reducer', () => {
communityEdition: false,
currentEnvironment: 'test',
nodeVersion: 'v12.14.1',
strapiVersion: '3.2.1',
strapiVersion: packageJSON.version,
};
const expected = state
.set('appInfos', data)
.set('autoReload', true)
.set('currentEnvironment', 'test');
const expected = { ...state, appInfos: data, autoReload: true, currentEnvironment: 'test' };
expect(appReducer(state, getInfosDataSucceeded(data))).toEqual(expected);
});
@ -79,10 +38,7 @@ describe('<App /> reducer', () => {
describe('GET_DATA_SUCCEEDED', () => {
it('should handle the set the data correctly', () => {
const expected = state
.set('hasAdminUser', true)
.set('uuid', 'true')
.set('isLoading', false);
const expected = { ...state, uuid: 'true', isLoading: false };
expect(appReducer(state, getDataSucceeded({ hasAdmin: true, uuid: 'true' }))).toEqual(
expected

View File

@ -1,11 +1,9 @@
import { fromJS } from 'immutable';
import makeSelectApp, { selectApp } from '../selectors';
describe('<App /> selectors', () => {
describe('selectApp', () => {
it('should select the global state', () => {
const appState = fromJS({});
const appState = {};
const mockedState = {
app: appState,
};
@ -16,12 +14,12 @@ describe('<App /> selectors', () => {
describe('makeSelectApp', () => {
it('should select the appState (.toJS())', () => {
const appState = fromJS({});
const appState = {};
const mockedState = {
app: appState,
};
expect(makeSelectApp()(mockedState)).toEqual(appState.toJS());
expect(makeSelectApp()(mockedState)).toEqual(appState);
});
});
});