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

View File

@ -1,8 +1,6 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { updatePlugin } from '../../App/actions';
import { Admin, mapDispatchToProps } from '../index'; import { Admin, mapDispatchToProps } from '../index';
import { setAppError } from '../actions'; import { setAppError } from '../actions';
@ -28,7 +26,6 @@ describe('<Admin />', () => {
global: { global: {
autoReload: false, autoReload: false,
currentEnvironment: 'development', currentEnvironment: 'development',
hasAdminUser: false,
isLoading: true, isLoading: true,
strapiVersion: '3', strapiVersion: '3',
uuid: false, uuid: false,
@ -38,7 +35,6 @@ describe('<Admin />', () => {
}, },
location: {}, location: {},
setAppError: jest.fn(), setAppError: jest.fn(),
updatePlugin: jest.fn(),
}; };
}); });
@ -141,21 +137,4 @@ describe('<Admin />, mapDispatchToProps', () => {
expect(dispatch).toHaveBeenCalledWith(setAppError()); 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 { import { GET_INFOS_DATA_SUCCEEDED, GET_DATA_SUCCEEDED } from './constants';
GET_INFOS_DATA_SUCCEEDED,
GET_DATA_SUCCEEDED,
LOAD_PLUGIN,
PLUGIN_DELETED,
PLUGIN_LOADED,
UPDATE_PLUGIN,
} from './constants';
export function getInfosDataSucceeded(data) { export function getInfosDataSucceeded(data) {
return { return {
@ -26,33 +19,3 @@ export function getDataSucceeded(data) {
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_DATA_SUCCEEDED = 'app/App/GET_DATA_SUCCEEDED';
export const GET_INFOS_DATA_SUCCEEDED = 'admin/App/GET_INFOS_DATA_SUCCEEDED'; export const GET_INFOS_DATA_SUCCEEDED = 'admin/App/GET_INFOS_DATA_SUCCEEDED';

View File

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

View File

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

View File

@ -1,19 +1,5 @@
import { import { GET_DATA_SUCCEEDED, GET_INFOS_DATA_SUCCEEDED } from '../constants';
GET_DATA_SUCCEEDED, import { getInfosDataSucceeded, getDataSucceeded } from '../actions';
GET_INFOS_DATA_SUCCEEDED,
LOAD_PLUGIN,
PLUGIN_DELETED,
PLUGIN_LOADED,
UPDATE_PLUGIN,
} from '../constants';
import {
loadPlugin,
getInfosDataSucceeded,
getDataSucceeded,
pluginDeleted,
pluginLoaded,
updatePlugin,
} from '../actions';
describe('<App /> actions', () => { describe('<App /> actions', () => {
describe('getDataSucceeded', () => { describe('getDataSucceeded', () => {
@ -39,62 +25,4 @@ describe('<App /> actions', () => {
expect(getInfosDataSucceeded(data)).toEqual(expected); 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 packageJSON from '../../../../../package.json';
import { import { getDataSucceeded, getInfosDataSucceeded } from '../actions';
getDataSucceeded,
getInfosDataSucceeded,
pluginDeleted,
pluginLoaded,
updatePlugin,
} from '../actions';
import appReducer from '../reducer'; import appReducer from '../reducer';
describe('<App /> reducer', () => { describe('<App /> reducer', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
state = fromJS({ state = {
appInfos: {}, appInfos: {},
autoReload: false, autoReload: false,
currentEnvironment: 'development', currentEnvironment: 'development',
hasAdminUser: false,
isLoading: true, isLoading: true,
plugins: {},
strapiVersion: packageJSON.version, strapiVersion: packageJSON.version,
uuid: false, uuid: false,
}); };
}); });
it('should return the initial state', () => { it('should return the initial state', () => {
const expectedResult = state.toJS(); expect(appReducer(undefined, {})).toEqual(state);
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);
}); });
describe('GET_INFOS_DATA_SUCCEEDED', () => { describe('GET_INFOS_DATA_SUCCEEDED', () => {
@ -66,12 +27,10 @@ describe('<App /> reducer', () => {
communityEdition: false, communityEdition: false,
currentEnvironment: 'test', currentEnvironment: 'test',
nodeVersion: 'v12.14.1', nodeVersion: 'v12.14.1',
strapiVersion: '3.2.1', strapiVersion: packageJSON.version,
}; };
const expected = state
.set('appInfos', data) const expected = { ...state, appInfos: data, autoReload: true, currentEnvironment: 'test' };
.set('autoReload', true)
.set('currentEnvironment', 'test');
expect(appReducer(state, getInfosDataSucceeded(data))).toEqual(expected); expect(appReducer(state, getInfosDataSucceeded(data))).toEqual(expected);
}); });
@ -79,10 +38,7 @@ describe('<App /> reducer', () => {
describe('GET_DATA_SUCCEEDED', () => { describe('GET_DATA_SUCCEEDED', () => {
it('should handle the set the data correctly', () => { it('should handle the set the data correctly', () => {
const expected = state const expected = { ...state, uuid: 'true', isLoading: false };
.set('hasAdminUser', true)
.set('uuid', 'true')
.set('isLoading', false);
expect(appReducer(state, getDataSucceeded({ hasAdmin: true, uuid: 'true' }))).toEqual( expect(appReducer(state, getDataSucceeded({ hasAdmin: true, uuid: 'true' }))).toEqual(
expected expected

View File

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