Merge pull request #10330 from strapi/chore/admin-notifications

Remove window.strapi.notification
This commit is contained in:
cyril lopez 2021-05-18 08:50:09 +02:00 committed by GitHub
commit 1a010e528b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
87 changed files with 645 additions and 587 deletions

View File

@ -125,6 +125,7 @@
"component": "default.restaurantservice",
"repeatable": true,
"type": "component",
"max": 1,
"pluginOptions": {
"i18n": {
"localized": true

View File

@ -152,14 +152,16 @@ class StrapiApp {
<StrapiAppProvider getPlugin={this.getPlugin} plugins={this.plugins}>
<LibraryProvider components={components} fields={fields}>
<LanguageProvider messages={this.translations}>
<>
<AutoReloadOverlayBlocker />
<OverlayBlocker />
<Notifications />
<BrowserRouter basename={basename}>
<App store={store} />
</BrowserRouter>
</>
<Notifications>
<>
<AutoReloadOverlayBlocker />
<OverlayBlocker />
<BrowserRouter basename={basename}>
<App store={store} />
</BrowserRouter>
</>
</Notifications>
</LanguageProvider>
</LibraryProvider>
</StrapiAppProvider>

View File

@ -1,6 +1,7 @@
import { useEffect, useRef } from 'react';
import { useUser } from '@strapi/helper-plugin';
import { useUser, useNotification } from '@strapi/helper-plugin';
import { useSelector, useDispatch } from 'react-redux';
import getCtOrStLinks from './utils/getCtOrStLinks';
import getPluginSectionLinks from './utils/getPluginSectionLinks';
import getGeneralLinks from './utils/getGeneralLinks';
@ -10,6 +11,7 @@ import toPluginLinks from './utils/toPluginLinks';
import selectMenuLinks from './selectors';
const useMenuSections = (plugins, shouldUpdateStrapi) => {
const toggleNotification = useNotification();
const state = useSelector(selectMenuLinks);
const dispatch = useDispatch();
const { userPermissions } = useUser();
@ -30,7 +32,8 @@ const useMenuSections = (plugins, shouldUpdateStrapi) => {
const resolvePermissions = async (permissions = userPermissions) => {
const pluginsSectionLinks = toPluginLinks(pluginsRef.current);
const { authorizedCtLinks, authorizedStLinks, contentTypes } = await getCtOrStLinks(
permissions
permissions,
toggleNotification
);
const authorizedPluginSectionLinks = await getPluginSectionLinks(

View File

@ -2,7 +2,7 @@ import { request } from '@strapi/helper-plugin';
import generateModelsLinks from './generateModelsLinks';
import checkPermissions from './checkPermissions';
const getCtOrStLinks = async userPermissions => {
const getCtOrStLinks = async (userPermissions, toggleNotification) => {
const requestURL = '/content-manager/content-types';
try {
@ -37,7 +37,7 @@ const getCtOrStLinks = async userPermissions => {
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -135,14 +135,14 @@ describe('checkPermissions', () => {
it('creates an array of boolean corresponding to the permission state', async () => {
console.error = () => undefined;
strapi.notification.toggle = jest.fn();
const toggleNotification = jest.fn();
const userPermissions = [];
request.mockImplementation(() => {
throw new Error('Something went wrong');
});
await getCtOrStLinks(userPermissions);
expect(strapi.notification.toggle).toBeCalled();
await getCtOrStLinks(userPermissions, toggleNotification);
expect(toggleNotification).toBeCalled();
});
});

View File

@ -1,11 +1,13 @@
import React, { useEffect, useReducer } from 'react';
import { NotificationsProvider } from '@strapi/helper-plugin';
import React, { useReducer } from 'react';
import PropTypes from 'prop-types';
import { CSSTransition } from 'react-transition-group';
import Notification from './Notification';
import reducer, { initialState } from './reducer';
import NotificationsWrapper from './Wrapper';
const Notifications = () => {
const Notifications = ({ children }) => {
const [{ notifications }, dispatch] = useReducer(reducer, initialState);
const displayNotification = config => {
@ -15,32 +17,29 @@ const Notifications = () => {
});
};
useEffect(() => {
window.strapi = Object.assign(window.strapi || {}, {
notification: {
toggle: config => {
displayNotification(config);
},
},
});
}, []);
return (
<NotificationsWrapper>
{notifications.map(notification => (
<CSSTransition
key={notification.id}
classNames="notification"
timeout={{
enter: 500,
exit: 300,
}}
>
<Notification dispatch={dispatch} notification={notification} />
</CSSTransition>
))}
</NotificationsWrapper>
<NotificationsProvider toggleNotification={displayNotification}>
<NotificationsWrapper>
{notifications.map(notification => (
<CSSTransition
key={notification.id}
classNames="notification"
timeout={{
enter: 500,
exit: 300,
}}
>
<Notification dispatch={dispatch} notification={notification} />
</CSSTransition>
))}
</NotificationsWrapper>
{children}
</NotificationsProvider>
);
};
Notifications.propTypes = {
children: PropTypes.element.isRequired,
};
export default Notifications;

View File

@ -1,6 +1,7 @@
// This component is a work in progress
// It's made to be used when the users API is ready
import React from 'react';
import { useNotification } from '@strapi/helper-plugin';
import { Flex, Text } from '@buffetjs/core';
import { Duplicate } from '@buffetjs/icons';
import PropTypes from 'prop-types';
@ -10,8 +11,10 @@ import Envelope from './Envelope';
import Wrapper from './Wrapper';
const LinkNotification = ({ target, children }) => {
const toggleNotification = useNotification();
const handleCopy = () => {
strapi.notification.toggle({ type: 'info', message: { id: 'notification.link-copied' } });
toggleNotification({ type: 'info', message: { id: 'notification.link-copied' } });
};
return (

View File

@ -1,6 +1,6 @@
import React, { forwardRef, useReducer, useImperativeHandle, useRef } from 'react';
import PropTypes from 'prop-types';
import { BaselineAlignment, ModalSection, request } from '@strapi/helper-plugin';
import { BaselineAlignment, ModalSection, request, useNotification } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { get } from 'lodash';
import { Padded, Text } from '@buffetjs/core';
@ -19,6 +19,7 @@ import RoleSettingsModalSection from '../RoleSettingsModalSection';
// This component accepts a ref so we can have access to the submit handler.
const ModalCreateBody = forwardRef(
({ isDisabled, onSubmit, registrationToken, setIsSubmiting, showMagicLink }, ref) => {
const toggleNotification = useNotification();
const [reducerState, dispatch] = useReducer(reducer, initialState, init);
const { formErrors, modifiedData } = reducerState;
const buttonSubmitRef = useRef(null);
@ -62,7 +63,7 @@ const ModalCreateBody = forwardRef(
} catch (err) {
const message = get(err, ['response', 'payload', 'message'], 'An error occured');
strapi.notification.toggle({ type: 'warning', message });
toggleNotification({ type: 'warning', message });
} finally {
strapi.unlockApp();
setIsSubmiting(false);

View File

@ -1,8 +1,9 @@
import { useCallback, useReducer, useEffect } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import reducer, { initialState } from './reducer';
const useFetchRole = id => {
const toggleNotification = useNotification();
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
@ -38,7 +39,7 @@ const useFetchRole = id => {
dispatch({
type: 'GET_DATA_ERROR',
});
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,13 +1,14 @@
import { useReducer, useEffect } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import reducer, { initialState } from './reducer';
const useModels = () => {
const toggleNotification = useNotification();
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
fetchModels();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const fetchModels = async () => {
@ -31,7 +32,7 @@ const useModels = () => {
dispatch({
type: 'GET_MODELS_ERROR',
});
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,10 +1,11 @@
import { useEffect, useReducer } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { get } from 'lodash';
import init from './init';
import reducer, { initialState } from './reducer';
const useRolesList = (shouldFetchData = true) => {
const toggleNotification = useNotification();
const [{ roles, isLoading }, dispatch] = useReducer(reducer, initialState, () =>
init(initialState, shouldFetchData)
);
@ -13,6 +14,7 @@ const useRolesList = (shouldFetchData = true) => {
if (shouldFetchData) {
fetchRolesList();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [shouldFetchData]);
const fetchRolesList = async () => {
@ -35,7 +37,7 @@ const useRolesList = (shouldFetchData = true) => {
});
if (message !== 'Forbidden') {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message,
});

View File

@ -1,5 +1,5 @@
import { useEffect, useReducer } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { get, has, omit } from 'lodash';
import { checkFormValidity, formatAPIErrors } from '../../utils';
import { initialState, reducer } from './reducer';
@ -10,6 +10,7 @@ const useSettingsForm = (endPoint, schema, cbSuccess, fieldsToPick) => {
{ formErrors, initialData, isLoading, modifiedData, showHeaderButtonLoader, showHeaderLoader },
dispatch,
] = useReducer(reducer, initialState, () => init(initialState, fieldsToPick));
const toggleNotification = useNotification();
useEffect(() => {
const getData = async () => {
@ -23,7 +24,7 @@ const useSettingsForm = (endPoint, schema, cbSuccess, fieldsToPick) => {
});
} catch (err) {
console.error(err.response);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -95,7 +96,7 @@ const useSettingsForm = (endPoint, schema, cbSuccess, fieldsToPick) => {
data,
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'notification.success.saved' },
});
@ -103,12 +104,12 @@ const useSettingsForm = (endPoint, schema, cbSuccess, fieldsToPick) => {
const data = get(err, 'response.payload', { data: {} });
if (has(data, 'data') && typeof data.data === 'string') {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: data.data,
});
} else {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: data.message,
});

View File

@ -19,6 +19,7 @@ import {
GlobalContextProvider,
CheckPagePermissions,
request,
NotificationsContext,
} from '@strapi/helper-plugin';
import { checkLatestStrapiVersion } from '../../utils';
@ -36,7 +37,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';
@ -45,13 +46,12 @@ import Content from './Content';
export class Admin extends React.Component {
// eslint-disable-line react/prefer-stateless-function
static contextType = NotificationsContext;
// This state is really temporary until we create a menu API
state = { updateMenu: null };
helpers = {
updatePlugin: this.props.updatePlugin,
};
helpers = {};
componentDidMount() {
this.emitEvent('didAccessAuthenticatedAdministration');
@ -103,7 +103,10 @@ export class Admin extends React.Component {
this.props.getInfosDataSucceeded(data);
} catch (err) {
console.error(err);
strapi.notification.error('notification.error');
this.context.toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
}
};
@ -129,7 +132,7 @@ export class Admin extends React.Component {
}
if (shouldUpdateStrapi) {
strapi.notification.toggle({
this.context.toggleNotification({
type: 'info',
message: { id: 'notification.version.update.message' },
link: {
@ -173,7 +176,6 @@ export class Admin extends React.Component {
intl: { formatMessage, locale },
// FIXME
plugins,
updatePlugin,
} = this.props;
return (
@ -187,10 +189,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 +264,6 @@ Admin.propTypes = {
}),
plugins: PropTypes.object.isRequired,
setAppError: PropTypes.func.isRequired,
updatePlugin: PropTypes.func.isRequired,
};
const mapStateToProps = createStructuredSelector({
@ -277,7 +277,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

@ -9,7 +9,7 @@ import PropTypes from 'prop-types';
import { Switch, Route } from 'react-router-dom';
import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { LoadingIndicatorPage, auth, request } from '@strapi/helper-plugin';
import { LoadingIndicatorPage, auth, request, useNotification } from '@strapi/helper-plugin';
import PluginsInitializer from '../../components/PluginsInitializer';
import PrivateRoute from '../../components/PrivateRoute';
import AuthPage from '../AuthPage';
@ -25,6 +25,7 @@ window.strapi = Object.assign(window.strapi || {}, {
});
function App(props) {
const toggleNotification = useNotification();
const getDataRef = useRef();
const [{ isLoading, hasAdmin }, setState] = useState({ isLoading: true, hasAdmin: false });
getDataRef.current = props.getDataSucceeded;
@ -89,7 +90,7 @@ function App(props) {
getDataRef.current(data);
setState({ isLoading: false, hasAdmin: data.hasAdmin });
} catch (err) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'app.containers.App.notification.error.init' },
});
@ -97,7 +98,7 @@ function App(props) {
};
getData();
}, []);
}, [toggleNotification]);
const setHasAdmin = hasAdmin => setState(prev => ({ ...prev, hasAdmin }));

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);
});
});
});

View File

@ -2,7 +2,7 @@ import React, { useEffect, useReducer } from 'react';
import axios from 'axios';
import { camelCase, get, omit, upperFirst } from 'lodash';
import { Redirect, useRouteMatch, useHistory } from 'react-router-dom';
import { BaselineAlignment, auth, useQuery } from '@strapi/helper-plugin';
import { BaselineAlignment, auth, useNotification, useQuery } from '@strapi/helper-plugin';
import { Padded } from '@buffetjs/core';
import PropTypes from 'prop-types';
import forms from 'ee_else_ce/pages/AuthPage/utils/forms';
@ -17,6 +17,7 @@ import { initialState, reducer } from './reducer';
import useChangeLanguage from '../../components/LanguageProvider/hooks/useChangeLanguage';
const AuthPage = ({ hasAdmin, setHasAdmin }) => {
const toggleNotification = useNotification();
const { push } = useHistory();
const changeLocale = useChangeLanguage();
const {
@ -71,7 +72,7 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => {
} catch (err) {
const errorMessage = get(err, ['response', 'data', 'message'], 'An error occurred');
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: errorMessage,
});
@ -145,7 +146,7 @@ const AuthPage = ({ hasAdmin, setHasAdmin }) => {
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,5 +1,5 @@
import React from 'react';
import { useGlobalContext, request } from '@strapi/helper-plugin';
import { useGlobalContext, request, useNotification } from '@strapi/helper-plugin';
import { Header, List } from '@buffetjs/custom';
import PageTitle from '../../components/PageTitle';
import ContainerFluid from '../../components/ContainerFluid';
@ -8,6 +8,7 @@ import Row from './Row';
import generateRows from './utils/generateRows';
const InstalledPluginsPage = () => {
const toggleNotification = useNotification();
const { formatMessage, plugins } = useGlobalContext();
const onConfirm = async id => {
try {
@ -28,7 +29,7 @@ const InstalledPluginsPage = () => {
}
} catch (err) {
strapi.unlockAppWithAutoreload();
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'app.components.listPluginsPage.deletePlugin.error' },
});

View File

@ -1,14 +1,19 @@
import React from 'react';
import { LoadingIndicatorPage, useGlobalContext, request } from '@strapi/helper-plugin';
import {
LoadingIndicatorPage,
useGlobalContext,
request,
useNotification,
} from '@strapi/helper-plugin';
import { Header } from '@buffetjs/custom';
import { useHistory } from 'react-router-dom';
import { useFetchPluginsFromMarketPlace } from '../../hooks';
import PageTitle from '../../components/PageTitle';
import PluginCard from './PluginCard';
import Wrapper from './Wrapper';
const MarketPlacePage = () => {
const toggleNotification = useNotification();
const history = useHistory();
const { autoReload, currentEnvironment, formatMessage, plugins } = useGlobalContext();
const { error, isLoading, data } = useFetchPluginsFromMarketPlace();
@ -43,7 +48,7 @@ const MarketPlacePage = () => {
}
} catch (err) {
strapi.unlockApp();
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,7 +1,12 @@
import React, { useState, useRef } from 'react';
import { useRouteMatch } from 'react-router-dom';
import get from 'lodash/get';
import { BaselineAlignment, useGlobalContext, request } from '@strapi/helper-plugin';
import {
BaselineAlignment,
useGlobalContext,
request,
useNotification,
} from '@strapi/helper-plugin';
import { Header } from '@buffetjs/custom';
import { Padded } from '@buffetjs/core';
import { Formik } from 'formik';
@ -13,6 +18,7 @@ import { useFetchRole, useFetchPermissionsLayout } from '../../../hooks';
import schema from './utils/schema';
const EditPage = () => {
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const { emitEvent } = useGlobalContext();
const {
@ -89,7 +95,7 @@ const EditPage = () => {
permissionsRef.current.setFormAfterSubmit();
onSubmitSucceeded({ name: data.name, description: data.description });
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'notification.success.saved' },
});
@ -99,7 +105,7 @@ const EditPage = () => {
const errorMessage = get(err, 'response.payload.message', 'An error occured');
const message = get(err, 'response.payload.data.permissions[0]', errorMessage);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message,
});

View File

@ -6,6 +6,7 @@ import {
useUserPermissions,
LoadingIndicatorPage,
PopUpWarning,
useNotification,
} from '@strapi/helper-plugin';
import { get } from 'lodash';
import { useHistory, useLocation } from 'react-router-dom';
@ -25,6 +26,7 @@ const ListPage = () => {
isLoading: isLoadingForPermissions,
allowedActions: { canCreate, canDelete, canRead, canUpdate },
} = useUserPermissions(adminPermissions.settings.users);
const toggleNotification = useNotification();
const [isWarningDeleteAllOpened, setIsWarningDeleteAllOpened] = useState(false);
const [isModalOpened, setIsModalOpened] = useState(false);
const { toggleHeaderSearch } = useSettingsHeaderSearchContext();
@ -78,7 +80,7 @@ const ListPage = () => {
});
} catch (err) {
console.error(err.response);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -185,7 +187,7 @@ const ListPage = () => {
} catch (err) {
const errorMessage = get(err, 'response.payload.data', 'An error occured');
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: errorMessage,
});
@ -199,7 +201,7 @@ const ListPage = () => {
}
handleToggleModal();
}, [dataToDelete]);
}, [dataToDelete, toggleNotification]);
const handleToggle = () => setIsModalOpened(prev => !prev);

View File

@ -1,11 +1,12 @@
import React, { useEffect, useMemo } from 'react';
import { useUserPermissions, LoadingIndicatorPage } from '@strapi/helper-plugin';
import { useUserPermissions, LoadingIndicatorPage, useNotification } from '@strapi/helper-plugin';
import { Redirect, useLocation } from 'react-router-dom';
import { get } from 'lodash';
import adminPermissions from '../../../permissions';
import EditPage from '../EditPage';
const ProtectedEditPage = () => {
const toggleNotification = useNotification();
const permissions = useMemo(() => {
return {
read: adminPermissions.settings.users.read,
@ -23,13 +24,13 @@ const ProtectedEditPage = () => {
useEffect(() => {
if (!isLoading) {
if (!canRead && !canUpdate) {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: 'notification.permission.not-allowed-read' },
});
}
}
}, [isLoading, canRead, canUpdate]);
}, [isLoading, canRead, canUpdate, toggleNotification]);
if (isLoading) {
return <LoadingIndicatorPage />;

View File

@ -15,6 +15,7 @@ import {
getYupInnerErrors,
BackHeader,
LoadingIndicatorPage,
useNotification,
} from '@strapi/helper-plugin';
import { useModels } from '../../../hooks';
import PageTitle from '../../../components/SettingsPageTitle';
@ -25,7 +26,7 @@ import Wrapper from './Wrapper';
function EditView() {
const { isLoading: isLoadingForModels, collectionTypes } = useModels();
const toggleNotification = useNotification();
const isMounted = useRef();
const { formatMessage } = useGlobalContext();
const [submittedOnce, setSubmittedOnce] = useState(false);
@ -69,7 +70,7 @@ function EditView() {
dispatch({ type: 'UNSET_LOADER' });
if (err.code !== 20) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -179,7 +180,7 @@ function EditView() {
setErrors(getYupInnerErrors(err));
if (submit) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.form.error.fields' },
});
@ -200,14 +201,14 @@ function EditView() {
dispatch({
type: 'SUBMIT_SUCCEEDED',
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'Settings.webhooks.created' },
});
replace(`/settings/webhooks/${data.id}`);
} catch (err) {
setIsSubmitting(false);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -272,7 +273,7 @@ function EditView() {
} catch (err) {
if (isMounted.current) {
if (err.code !== 20) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -368,13 +369,13 @@ function EditView() {
dispatch({
type: 'SUBMIT_SUCCEEDED',
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'notification.form.success.fields' },
});
} catch (err) {
setIsSubmitting(false);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -18,6 +18,7 @@ import {
useUserPermissions,
LoadingIndicatorPage,
EmptyState,
useNotification,
} from '@strapi/helper-plugin';
import adminPermissions from '../../../permissions';
import PageTitle from '../../../components/SettingsPageTitle';
@ -30,7 +31,7 @@ function ListView() {
isLoading,
allowedActions: { canCreate, canRead, canUpdate, canDelete },
} = useUserPermissions(adminPermissions.settings.webhooks);
const toggleNotification = useNotification();
const isMounted = useRef(true);
const { formatMessage } = useIntl();
const [showModal, setShowModal] = useState(false);
@ -52,6 +53,7 @@ function ListView() {
if (canRead) {
fetchData();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [canRead]);
const getWebhookIndex = id => webhooks.findIndex(webhook => webhook.id === id);
@ -138,7 +140,7 @@ function ListView() {
} catch (err) {
if (isMounted.current) {
if (err.code !== 20) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -175,7 +177,7 @@ function ListView() {
});
} catch (err) {
if (err.code !== 20) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -203,7 +205,7 @@ function ListView() {
} catch (err) {
if (isMounted.current) {
if (err.code !== 20) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -255,7 +257,7 @@ function ListView() {
});
if (err.code !== 20) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,10 +1,10 @@
import React from 'react';
import { Router, Route, Switch } from 'react-router-dom';
// import { render, cleanup } from '@testing-library/react';
import { shallow } from 'enzyme';
import { createMemoryHistory } from 'history';
import { GlobalContextProvider, UserProvider } from '@strapi/helper-plugin';
import { IntlProvider } from 'react-intl';
import Notifications from '../../../../components/Notifications';
import translationMessages from '../../../../translations/en.json';
@ -14,15 +14,6 @@ const history = createMemoryHistory();
describe('Admin | containers | ListView', () => {
it('should not crash', () => {
const intlProvider = new IntlProvider(
{
locale: 'en',
messages: translationMessages,
},
{}
);
const { intl: originalIntl } = intlProvider.state;
shallow(
<IntlProvider
locale="en"
@ -30,17 +21,19 @@ describe('Admin | containers | ListView', () => {
messages={translationMessages}
textComponent="span"
>
<GlobalContextProvider formatMessage={originalIntl.formatMessage}>
<UserProvider permissions={[]}>
<Router history={history}>
<Switch>
<Route path="/settings/webhooks">
<ListView />
</Route>
</Switch>
</Router>
</UserProvider>
</GlobalContextProvider>
<Notifications>
<GlobalContextProvider formatMessage={jest.fn()}>
<UserProvider permissions={[]}>
<Router history={history}>
<Switch>
<Route path="/settings/webhooks">
<ListView />
</Route>
</Switch>
</Router>
</UserProvider>
</GlobalContextProvider>
</Notifications>
</IntlProvider>
);
});

View File

@ -1,11 +1,12 @@
import { useReducer, useEffect } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { getRequestUrl } from '../../../../admin/src/utils';
import reducer, { initialState } from './reducer';
const useAuthProviders = ({ ssoEnabled }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const toggleNotification = useNotification();
useEffect(() => {
fetchAuthProviders();
@ -37,7 +38,7 @@ const useAuthProviders = ({ ssoEnabled }) => {
type: 'GET_DATA_ERROR',
});
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
centered: true,

View File

@ -10,6 +10,7 @@ import {
CheckPagePermissions,
request,
useGlobalContext,
useNotification,
} from '@strapi/helper-plugin';
import { useHistory, useRouteMatch } from 'react-router-dom';
import adminPermissions from '../../../../../admin/src/permissions';
@ -24,6 +25,7 @@ import Permissions from '../../../../../admin/src/components/Roles/Permissions';
import schema from './utils/schema';
const CreatePage = () => {
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const [isSubmiting, setIsSubmiting] = useState(false);
const { replace } = useHistory();
@ -95,7 +97,7 @@ const CreatePage = () => {
})
.then(res => {
setIsSubmiting(false);
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'Settings.roles.created' },
});
@ -104,7 +106,7 @@ const CreatePage = () => {
.catch(err => {
console.error(err);
setIsSubmiting(false);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,6 +1,7 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { useNotification } from '@strapi/helper-plugin';
import { Pencil, Duplicate } from '@buffetjs/icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RoleRow as RoleRowBase } from '../../../../../admin/src/components/Roles';
@ -17,6 +18,7 @@ const RoleRow = ({
selectedRoles,
}) => {
const { push } = useHistory();
const toggleNotification = useNotification();
const handleRoleSelection = e => {
e.stopPropagation();
@ -29,7 +31,7 @@ const RoleRow = ({
e.stopPropagation();
if (role.usersCount) {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: 'Roles.ListPage.notification.delete-not-allowed' },
});

View File

@ -11,6 +11,7 @@ import {
PopUpWarning,
request,
useUserPermissions,
useNotification,
LoadingIndicatorPage,
} from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
@ -24,6 +25,7 @@ import BaselineAlignment from './BaselineAlignment';
import reducer, { initialState } from './reducer';
const RoleListPage = () => {
const toggleNotification = useNotification();
const [isWarningDeleteAllOpened, setIsWarningDeleteAllOpenend] = useState(false);
const { formatMessage } = useIntl();
const { push } = useHistory();
@ -85,7 +87,7 @@ const RoleListPage = () => {
});
if (selectedRoles.length !== filteredRoles.length) {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: 'Roles.ListPage.notification.delete-all-not-allowed' },
});
@ -111,12 +113,12 @@ const RoleListPage = () => {
if (errorIds && Array.isArray(errorIds)) {
const errorsMsg = errorIds.join('\n');
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: errorsMsg,
});
} else {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -4,7 +4,7 @@ import isEqual from 'react-fast-compare';
import PropTypes from 'prop-types';
import { FormattedMessage, useIntl } from 'react-intl';
import { Flex } from '@buffetjs/core';
import { LabelIconWrapper, NotAllowedInput } from '@strapi/helper-plugin';
import { LabelIconWrapper, NotAllowedInput, useNotification } from '@strapi/helper-plugin';
import pluginId from '../../pluginId';
import connect from './utils/connect';
import select from './utils/select';
@ -35,6 +35,7 @@ const DynamicZone = ({
fieldSchema,
metadatas,
}) => {
const toggleNotification = useNotification();
const [isOpen, setIsOpen] = useState(false);
const { formatMessage } = useIntl();
// We cannot use the default props here
@ -71,7 +72,10 @@ const DynamicZone = ({
if (dynamicDisplayedComponentsLength < max) {
setIsOpen(prev => !prev);
} else {
strapi.notification.info(`${pluginId}.components.notification.info.maximum-requirement`);
toggleNotification({
type: 'info',
message: { id: `${pluginId}.components.notification.info.maximum-requirement` },
});
}
};

View File

@ -4,6 +4,7 @@ import { useDrop } from 'react-dnd';
import PropTypes from 'prop-types';
import { get, take } from 'lodash';
import { FormattedMessage } from 'react-intl';
import { useNotification } from '@strapi/helper-plugin';
import { ErrorMessage } from '@buffetjs/styles';
import pluginId from '../../pluginId';
import { getMaxTempKey } from '../../utils';
@ -27,6 +28,7 @@ const RepeatableComponent = ({
min,
name,
}) => {
const toggleNotification = useNotification();
const [collapseToOpen, setCollapseToOpen] = useState('');
const [, drop] = useDrop({ accept: ItemTypes.COMPONENT });
const { getComponentLayout } = useContentTypeLayout();
@ -67,7 +69,10 @@ const RepeatableComponent = ({
setCollapseToOpen(nextTempKey);
} else if (componentValueLength >= max) {
strapi.notification.info(`${pluginId}.components.notification.info.maximum-requirement`);
toggleNotification({
type: 'info',
message: { id: `${pluginId}.components.notification.info.maximum-requirement` },
});
}
}
}, [
@ -79,6 +84,7 @@ const RepeatableComponent = ({
max,
name,
nextTempKey,
toggleNotification,
]);
return (

View File

@ -1,5 +1,4 @@
import { fromJS } from 'immutable';
import getTrad from '../../utils/getTrad';
const initialState = fromJS({ collapses: [] });
@ -33,11 +32,6 @@ const reducer = (state, action) => {
// https://github.com/react-dnd/react-dnd/issues/1368
// https://github.com/frontend-collective/react-sortable-tree/issues/490
if (oldList.size !== newList.size) {
strapi.notification.toggle({
type: 'warning',
message: getTrad('components.repeatable.reorder.error'),
});
return oldList;
}

View File

@ -4,6 +4,7 @@ import { get } from 'lodash';
import {
request,
useGlobalContext,
useNotification,
useQueryParams,
formatComponentData,
contentManagementUtilRemoveFieldsFromData,
@ -28,6 +29,7 @@ import { getRequestUrl } from './utils';
// This container is used to handle the CRUD
const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }) => {
const toggleNotification = useNotification();
const { emitEvent } = useGlobalContext();
const { push, replace } = useHistory();
const [{ rawQuery }] = useQueryParams();
@ -152,7 +154,10 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
// Not allowed to read a document
if (resStatus === 403) {
strapi.notification.info(getTrad('permissions.not-allowed.update'));
toggleNotification({
type: 'info',
message: { id: getTrad('permissions.not-allowed.update') },
});
push(redirectionLink);
}
@ -178,23 +183,35 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
return () => {
abortController.abort();
};
}, [cleanClonedData, cleanReceivedData, push, requestURL, dispatch, rawQuery, redirectionLink]);
}, [
cleanClonedData,
cleanReceivedData,
push,
requestURL,
dispatch,
rawQuery,
redirectionLink,
toggleNotification,
]);
const displayErrors = useCallback(err => {
const errorPayload = err.response.payload;
console.error(errorPayload);
const displayErrors = useCallback(
err => {
const errorPayload = err.response.payload;
console.error(errorPayload);
let errorMessage = get(errorPayload, ['message'], 'Bad Request');
let errorMessage = get(errorPayload, ['message'], 'Bad Request');
// TODO handle errors correctly when back-end ready
if (Array.isArray(errorMessage)) {
errorMessage = get(errorMessage, ['0', 'messages', '0', 'id']);
}
// TODO handle errors correctly when back-end ready
if (Array.isArray(errorMessage)) {
errorMessage = get(errorMessage, ['0', 'messages', '0', 'id']);
}
if (typeof errorMessage === 'string') {
strapi.notification.error(errorMessage);
}
}, []);
if (typeof errorMessage === 'string') {
toggleNotification({ type: 'warning', message: errorMessage });
}
},
[toggleNotification]
);
const onDelete = useCallback(
async trackerProperty => {
@ -205,7 +222,10 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
method: 'DELETE',
});
strapi.notification.success(getTrad('success.record.delete'));
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.delete') },
});
emitEventRef.current('didDeleteEntry', trackerProperty);
@ -216,7 +236,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
return Promise.reject(err);
}
},
[id, slug]
[id, slug, toggleNotification]
);
const onDeleteSucceeded = useCallback(() => {
@ -234,7 +254,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
const response = await request(endPoint, { method: 'POST', body });
emitEventRef.current('didCreateEntry', trackerProperty);
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.save') },
});
@ -250,7 +270,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
dispatch(setStatus('resolved'));
}
},
[cleanReceivedData, displayErrors, replace, slug, dispatch, rawQuery]
[cleanReceivedData, displayErrors, replace, slug, dispatch, rawQuery, toggleNotification]
);
const onPublish = useCallback(async () => {
@ -267,7 +287,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
dispatch(submitSucceeded(cleanReceivedData(data)));
dispatch(setStatus('resolved'));
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.publish') },
});
@ -275,7 +295,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
displayErrors(err);
dispatch(setStatus('resolved'));
}
}, [cleanReceivedData, displayErrors, id, slug, dispatch]);
}, [cleanReceivedData, displayErrors, id, slug, dispatch, toggleNotification]);
const onPut = useCallback(
async (body, trackerProperty) => {
@ -289,7 +309,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
const response = await request(endPoint, { method: 'PUT', body });
emitEventRef.current('didEditEntry', { trackerProperty });
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.save') },
});
@ -304,7 +324,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
dispatch(setStatus('resolved'));
}
},
[cleanReceivedData, displayErrors, slug, id, dispatch]
[cleanReceivedData, displayErrors, slug, id, dispatch, toggleNotification]
);
const onUnpublish = useCallback(async () => {
@ -318,7 +338,10 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
const response = await request(endPoint, { method: 'POST' });
emitEventRef.current('didUnpublishEntry');
strapi.notification.success(getTrad('success.record.unpublish'));
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.unpublish') },
});
dispatch(submitSucceeded(cleanReceivedData(response)));
dispatch(setStatus('resolved'));
@ -326,7 +349,7 @@ const CollectionTypeFormWrapper = ({ allLayoutData, children, slug, id, origin }
dispatch(setStatus('resolved'));
displayErrors(err);
}
}, [cleanReceivedData, displayErrors, id, slug, dispatch]);
}, [cleanReceivedData, displayErrors, id, slug, dispatch, toggleNotification]);
return children({
componentsDataStructure,

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { useHistory } from 'react-router-dom';
import { useSelector, shallowEqual } from 'react-redux';
import { cloneDeep, flatMap, get, set, pick } from 'lodash';
import { request, useGlobalContext } from '@strapi/helper-plugin';
import { request, useGlobalContext, useNotification } from '@strapi/helper-plugin';
import { Inputs as Input } from '@buffetjs/custom';
import { FormattedMessage } from 'react-intl';
import pluginId from '../../pluginId';
@ -25,6 +25,7 @@ import LinkToCTB from './LinkToCTB';
const EditSettingsView = ({ components, mainLayout, isContentTypeView, slug, updateLayout }) => {
const { push } = useHistory();
const { emitEvent } = useGlobalContext();
const toggleNotification = useNotification();
const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
init(initialState, mainLayout, components)
@ -134,7 +135,7 @@ const EditSettingsView = ({ components, mainLayout, isContentTypeView, slug, upd
emitEvent('didEditEditSettings');
} catch (err) {
strapi.notification.error('notification.error');
toggleNotification({ type: 'warning', message: { id: 'notification.error' } });
}
};

View File

@ -4,7 +4,7 @@ import { get } from 'lodash';
import isEqual from 'react-fast-compare';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Text } from '@buffetjs/core';
import { PopUpWarning } from '@strapi/helper-plugin';
import { PopUpWarning, useNotification } from '@strapi/helper-plugin';
import PropTypes from 'prop-types';
import pluginId from '../../../pluginId';
import { getTrad } from '../../../utils';
@ -16,6 +16,7 @@ const DeleteLink = ({ isCreatingEntry, onDelete, onDeleteSucceeded, trackerPrope
const [didDeleteEntry, setDidDeleteEntry] = useState(false);
const [isModalConfirmButtonLoading, setIsModalConfirmButtonLoading] = useState(false);
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const toggleWarningDelete = () => setWarningDelete(prevState => !prevState);
@ -36,7 +37,7 @@ const DeleteLink = ({ isCreatingEntry, onDelete, onDeleteSucceeded, trackerPrope
'response.payload.message',
formatMessage({ id: `${pluginId}.error.record.delete` })
);
strapi.notification.error(errorMessage);
toggleNotification({ type: 'warning', message: errorMessage });
} finally {
setIsModalConfirmButtonLoading(false);
toggleWarningDelete();

View File

@ -7,6 +7,7 @@ import {
useGlobalContext,
OverlayBlocker,
ContentManagerEditViewDataManagerContext,
useNotification,
} from '@strapi/helper-plugin';
import { getTrad, removeKeyInObject } from '../../utils';
import reducer, { initialState } from './reducer';
@ -43,6 +44,7 @@ const EditViewDataManagerProvider = ({
modifiedDZName,
shouldCheckErrors,
} = reducerState.toJS();
const toggleNotification = useNotification();
const currentContentTypeLayout = get(allLayoutData, ['contentType'], {});
@ -83,9 +85,12 @@ const EditViewDataManagerProvider = ({
useEffect(() => {
if (shouldRedirectToHomepageWhenEditingEntry) {
strapi.notification.info(getTrad('permissions.not-allowed.update'));
toggleNotification({
type: 'info',
message: { id: getTrad('permissions.not-allowed.update') },
});
}
}, [shouldRedirectToHomepageWhenEditingEntry]);
}, [shouldRedirectToHomepageWhenEditingEntry, toggleNotification]);
useEffect(() => {
dispatch({

View File

@ -1,7 +1,7 @@
import React, { memo, useMemo, useReducer, useState } from 'react';
import PropTypes from 'prop-types';
import { get, pick } from 'lodash';
import { request, useGlobalContext } from '@strapi/helper-plugin';
import { request, useGlobalContext, useNotification } from '@strapi/helper-plugin';
import { FormattedMessage, useIntl } from 'react-intl';
import { useDrop } from 'react-dnd';
import { DropdownItem } from 'reactstrap';
@ -22,6 +22,7 @@ import reducer, { initialState } from './reducer';
import forms from './forms.json';
const ListSettingsView = ({ layout, slug, updateLayout }) => {
const toggleNotification = useNotification();
const [reducerState, dispatch] = useReducer(reducer, initialState, () =>
init(initialState, layout)
);
@ -103,7 +104,7 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
});
emitEvent('didEditListSettings');
} catch (err) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -211,7 +212,7 @@ const ListSettingsView = ({ layout, slug, updateLayout }) => {
e.stopPropagation();
if (displayedFields.length === 1) {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: `${pluginId}.notification.info.minimumFields` },
});

View File

@ -15,6 +15,7 @@ import {
InjectionZoneList,
PopUpWarning,
useGlobalContext,
useNotification,
useQueryParams,
useUser,
request,
@ -86,7 +87,7 @@ function ListView({
settings: { bulkable: isBulkable, filterable: isFilterable, searchable: isSearchable },
},
} = layout;
const toggleNotification = useNotification();
const { emitEvent } = useGlobalContext();
const { fetchUserPermissions } = useUser();
const emitEventRef = useRef(emitEvent);
@ -142,7 +143,10 @@ function ListView({
if (resStatus === 403) {
await fetchPermissionsRef.current();
strapi.notification.info(getTrad('permissions.not-allowed.update'));
toggleNotification({
type: 'info',
message: { id: getTrad('permissions.not-allowed.update') },
});
push('/');
@ -151,11 +155,14 @@ function ListView({
if (err.name !== 'AbortError') {
console.error(err);
strapi.notification.error(getTrad('error.model.fetch'));
toggleNotification({
type: 'warning',
message: { id: getTrad('error.model.fetch') },
});
}
}
},
[getData, getDataSucceeded, push]
[getData, getDataSucceeded, push, toggleNotification]
);
const handleChangeListLabels = useCallback(
@ -163,7 +170,7 @@ function ListView({
// Display a notification if trying to remove the last displayed field
if (value && displayedHeaders.length === 1) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'content-manager.notification.error.displayedFields' },
});
@ -173,7 +180,7 @@ function ListView({
onChangeListHeaders({ name, value });
}
},
[displayedHeaders, onChangeListHeaders]
[displayedHeaders, onChangeListHeaders, toggleNotification]
);
const handleConfirmDeleteAllData = useCallback(async () => {
@ -188,9 +195,18 @@ function ListView({
onDeleteSeveralDataSucceeded();
emitEventRef.current('didBulkDeleteEntries');
} catch (err) {
strapi.notification.error(`${pluginId}.error.record.delete`);
toggleNotification({
type: 'warning',
message: { id: getTrad('error.record.delete') },
});
}
}, [entriesToDelete, onDeleteSeveralDataSucceeded, slug, setModalLoadingState]);
}, [
entriesToDelete,
onDeleteSeveralDataSucceeded,
slug,
setModalLoadingState,
toggleNotification,
]);
const handleConfirmDeleteData = useCallback(async () => {
try {
@ -211,9 +227,9 @@ function ListView({
method: 'DELETE',
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: `${pluginId}.success.record.delete` },
message: { id: getTrad('success.record.delete') },
});
// Close the modal and refetch data
@ -223,10 +239,10 @@ function ListView({
const errorMessage = get(
err,
'response.payload.message',
formatMessage({ id: `${pluginId}.error.record.delete` })
formatMessage({ id: getTrad('error.record.delete') })
);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: errorMessage,
});
@ -234,6 +250,7 @@ function ListView({
onDeleteDataError();
}
}, [
toggleNotification,
hasDraftAndPublish,
setModalLoadingState,
slug,

View File

@ -8,6 +8,7 @@ import {
LoadingIndicatorPage,
NotFound,
request,
useNotification,
} from '@strapi/helper-plugin';
import { DndProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
@ -22,6 +23,8 @@ import { getData, getDataSucceeded, resetProps } from './actions';
import makeSelectMain from './selectors';
function Main({ getData, getDataSucceeded, isLoading, resetProps }) {
const toggleNotification = useNotification();
useEffect(() => {
const abortController = new AbortController();
const { signal } = abortController;
@ -39,7 +42,7 @@ function Main({ getData, getDataSucceeded, isLoading, resetProps }) {
getDataSucceeded(models, components);
} catch (err) {
console.error(err);
strapi.notification.error('notification.error');
toggleNotification({ type: 'warning', message: { id: 'notification.error' } });
}
};
@ -49,7 +52,7 @@ function Main({ getData, getDataSucceeded, isLoading, resetProps }) {
abortController.abort();
resetProps();
};
}, [getData, getDataSucceeded, resetProps]);
}, [getData, getDataSucceeded, resetProps, toggleNotification]);
if (isLoading) {
return <LoadingIndicatorPage />;

View File

@ -6,6 +6,7 @@ import {
useGlobalContext,
formatComponentData,
useQueryParams,
useNotification,
} from '@strapi/helper-plugin';
import { useSelector, useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
@ -31,8 +32,9 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
const [isCreatingEntry, setIsCreatingEntry] = useState(true);
const [{ query, rawQuery }] = useQueryParams();
const searchToSend = buildQueryString(query);
const toggleNotification = useNotification();
const dispatch = useDispatch();
const {
componentsDataStructure,
contentTypeDataStructure,
@ -122,7 +124,10 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
}
if (responseStatus === 403) {
strapi.notification.info(getTrad('permissions.not-allowed.update'));
toggleNotification({
type: 'info',
message: { id: getTrad('permissions.not-allowed.update') },
});
push('/');
}
@ -132,23 +137,26 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
fetchData(signal);
return () => abortController.abort();
}, [cleanReceivedData, push, slug, dispatch, searchToSend, rawQuery]);
}, [cleanReceivedData, push, slug, dispatch, searchToSend, rawQuery, toggleNotification]);
const displayErrors = useCallback(err => {
const errorPayload = err.response.payload;
console.error(errorPayload);
const displayErrors = useCallback(
err => {
const errorPayload = err.response.payload;
console.error(errorPayload);
let errorMessage = get(errorPayload, ['message'], 'Bad Request');
let errorMessage = get(errorPayload, ['message'], 'Bad Request');
// TODO handle errors correctly when back-end ready
if (Array.isArray(errorMessage)) {
errorMessage = get(errorMessage, ['0', 'messages', '0', 'id']);
}
// TODO handle errors correctly when back-end ready
if (Array.isArray(errorMessage)) {
errorMessage = get(errorMessage, ['0', 'messages', '0', 'id']);
}
if (typeof errorMessage === 'string') {
strapi.notification.error(errorMessage);
}
}, []);
if (typeof errorMessage === 'string') {
toggleNotification({ type: 'warning', message: errorMessage });
}
},
[toggleNotification]
);
const onDelete = useCallback(
async trackerProperty => {
@ -159,7 +167,10 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
method: 'DELETE',
});
strapi.notification.success(getTrad('success.record.delete'));
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.delete') },
});
emitEventRef.current('didDeleteEntry', trackerProperty);
@ -170,7 +181,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
return Promise.reject(err);
}
},
[slug]
[slug, toggleNotification]
);
const onDeleteSucceeded = useCallback(() => {
@ -189,7 +200,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
const response = await request(endPoint, { method: 'PUT', body });
emitEventRef.current('didCreateEntry', trackerProperty);
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.save') },
});
@ -206,7 +217,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
dispatch(setStatus('resolved'));
}
},
[cleanReceivedData, displayErrors, slug, dispatch, rawQuery]
[cleanReceivedData, displayErrors, slug, dispatch, rawQuery, toggleNotification]
);
const onPublish = useCallback(async () => {
try {
@ -218,7 +229,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
const data = await request(endPoint, { method: 'POST' });
emitEventRef.current('didPublishEntry');
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.publish') },
});
@ -231,7 +242,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
dispatch(setStatus('resolved'));
}
}, [cleanReceivedData, displayErrors, slug, searchToSend, dispatch]);
}, [cleanReceivedData, displayErrors, slug, searchToSend, dispatch, toggleNotification]);
const onPut = useCallback(
async (body, trackerProperty) => {
@ -244,7 +255,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
const response = await request(endPoint, { method: 'PUT', body });
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.save') },
});
@ -262,7 +273,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
dispatch(setStatus('resolved'));
}
},
[cleanReceivedData, displayErrors, slug, dispatch, rawQuery]
[cleanReceivedData, displayErrors, slug, dispatch, rawQuery, toggleNotification]
);
// The publish and unpublish method could be refactored but let's leave the duplication for now
@ -277,7 +288,10 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
const response = await request(endPoint, { method: 'POST' });
emitEventRef.current('didUnpublishEntry');
strapi.notification.success(getTrad('success.record.unpublish'));
toggleNotification({
type: 'success',
message: { id: getTrad('success.record.unpublish') },
});
dispatch(submitSucceeded(cleanReceivedData(response)));
@ -286,7 +300,7 @@ const SingleTypeFormWrapper = ({ allLayoutData, children, slug }) => {
dispatch(setStatus('resolved'));
displayErrors(err);
}
}, [cleanReceivedData, displayErrors, slug, dispatch, searchToSend]);
}, [cleanReceivedData, toggleNotification, displayErrors, slug, dispatch, searchToSend]);
return children({
componentsDataStructure,

View File

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useGlobalContext } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { useNotification } from '@strapi/helper-plugin';
import { Flex } from '@buffetjs/core';
import styled from 'styled-components';
import CTIcon from './CT';
@ -25,11 +26,13 @@ const STHackSpan = styled.span`
`;
const BooleanBox = ({ label, name, onChange, onChangeCallback, options, value }) => {
const { formatMessage } = useGlobalContext();
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const handleChange = e => {
onChange(e);
onChangeCallback();
onChangeCallback({ toggleNotification });
};
return (

View File

@ -1,11 +1,16 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { ThemeProvider } from 'styled-components';
import defaultThemes from '../../../../../../admin/admin/src/themes';
import BooleanBox from '..';
jest.mock('react-intl', () => ({
useIntl: () => ({ formatMessage: ({ id }) => id }),
}));
jest.mock('@strapi/helper-plugin', () => ({
useGlobalContext: () => ({ formatMessage: ({ id }) => id }),
useNotification: () => jest.fn(),
}));
describe('BooleanBox', () => {

View File

@ -6,6 +6,7 @@ import {
LoadingIndicatorPage,
useGlobalContext,
PopUpWarning,
useNotification,
useStrapiApp,
useUser,
} from '@strapi/helper-plugin';
@ -63,6 +64,7 @@ const DataManagerProvider = ({
reservedNames,
}) => {
const dispatch = useDispatch();
const toggleNotification = useNotification();
const { getPlugin } = useStrapiApp();
@ -124,7 +126,7 @@ const DataManagerProvider = ({
});
} catch (err) {
console.error({ err });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -146,12 +148,12 @@ const DataManagerProvider = ({
useEffect(() => {
if (!autoReload) {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: getTrad('notification.info.autoreaload-disable') },
});
}
}, [autoReload]);
}, [autoReload, toggleNotification]);
const didModifiedComponents =
getCreatedAndModifiedComponents(modifiedData.components || {}, components).length > 0;
@ -258,7 +260,7 @@ const DataManagerProvider = ({
}
} catch (err) {
console.error({ err });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -309,7 +311,7 @@ const DataManagerProvider = ({
}
} catch (err) {
console.error({ err });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -339,7 +341,7 @@ const DataManagerProvider = ({
getDataRef.current();
} catch (err) {
console.error({ err });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -495,7 +497,7 @@ const DataManagerProvider = ({
}
console.error({ err: err.response });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -87,8 +87,8 @@ const forms = {
name: 'kind',
type: 'booleanBox',
size: 12,
onChangeCallback: () =>
strapi.notification.toggle({
onChangeCallback: ({ toggleNotification }) =>
toggleNotification({
type: 'info',
message: { id: getTrad('contentType.kind.change.warning') },
}),

View File

@ -9,6 +9,7 @@ import {
PopUpWarning,
getYupInnerErrors,
useGlobalContext,
useNotification,
useQuery,
useStrapiApp,
InputsIndex,
@ -68,6 +69,7 @@ const FormModal = () => {
const [showConfirmModal, setShowConfirmModal] = useState(false);
const formModalSelector = useMemo(makeSelectFormModal, []);
const dispatch = useDispatch();
const toggleNotification = useNotification();
const reducerState = useSelector(state => formModalSelector(state), shallowEqual);
const { push } = useHistory();
const { search } = useLocation();
@ -704,7 +706,7 @@ const FormModal = () => {
push({ search: '' });
submitData(modifiedData);
} else {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.contentType.relations.conflict' },
});

View File

@ -8,7 +8,7 @@ import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import { sortBy, camelCase, upperFirst } from 'lodash';
import { useHistory } from 'react-router-dom';
import { LeftMenuList, useGlobalContext } from '@strapi/helper-plugin';
import { LeftMenuList, useGlobalContext, useNotification } from '@strapi/helper-plugin';
import { Text } from '@buffetjs/core';
import pluginId from '../../pluginId';
import getTrad from '../../utils/getTrad';
@ -19,13 +19,6 @@ import Wrapper from './Wrapper';
/* eslint-disable indent */
const displayNotificationCTNotSaved = () => {
strapi.notification.toggle({
type: 'info',
message: { id: `${pluginId}.notification.info.creating.notSaved` },
});
};
function LeftMenu({ wait }) {
const {
components,
@ -34,8 +27,10 @@ function LeftMenu({ wait }) {
isInDevelopmentMode,
sortedContentTypesList,
} = useDataManager();
const toggleNotification = useNotification();
const { emitEvent, formatMessage } = useGlobalContext();
const { push } = useHistory();
const componentsData = sortBy(
Object.keys(componentsGroupedByCategory).map(category => ({
name: category,
@ -107,7 +102,10 @@ function LeftMenu({ wait }) {
search,
});
} else {
displayNotificationCTNotSaved();
toggleNotification({
type: 'info',
message: { id: `${pluginId}.notification.info.creating.notSaved` },
});
}
};

View File

@ -1,3 +1,4 @@
/* eslint-disable react/jsx-wrap-multilines */
import React, { useState, useEffect, useRef } from 'react';
import { useIntl, FormattedMessage } from 'react-intl';
import { get } from 'lodash';
@ -12,6 +13,7 @@ import {
getYupInnerErrors,
BaselineAlignment,
CheckPagePermissions,
useNotification,
} from '@strapi/helper-plugin';
import getTrad from '../../utils/getTrad';
import { AlignedButton, Text } from './components';
@ -19,6 +21,7 @@ import schema from '../../utils/schema';
import pluginPermissions from '../../permissions';
const SettingsPage = () => {
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const [formErrors, setFormErrors] = useState({});
const [isTestButtonLoading, setIsTestButtonLoading] = useState(false);
@ -50,14 +53,17 @@ const SettingsPage = () => {
});
setTestSuccess(true);
strapi.notification.success(
formatMessage({ id: getTrad('Settings.notification.test.success') }, { to: testAddress })
const message = formatMessage(
{ id: getTrad('Settings.notification.test.success') },
{ to: testAddress }
);
toggleNotification({ type: 'success', message });
} catch (err) {
strapi.notification.error(
formatMessage({ id: getTrad('Settings.notification.test.error') }, { to: testAddress })
const message = formatMessage(
{ id: getTrad('Settings.notification.test.error') },
{ to: testAddress }
);
toggleNotification({ type: 'warning', message });
} finally {
if (isMounted.current) {
setIsTestButtonLoading(false);
@ -83,15 +89,16 @@ const SettingsPage = () => {
setTestAddress(get(data, 'config.settings.testAddress'));
})
.catch(() =>
strapi.notification.error(
formatMessage({ id: getTrad('Settings.notification.config.error') })
)
toggleNotification({
type: 'warning',
message: { id: getTrad('Settings.notification.config.error') },
})
)
.finally(() => setShowLoader(false));
};
fetchEmailSettings();
}, [formatMessage]);
}, [formatMessage, toggleNotification]);
useEffect(() => {
return () => {
@ -178,12 +185,12 @@ const SettingsPage = () => {
<AlignedButton
color="success"
disabled={testSuccess}
icon={(
icon={
<Envelope
fill={testSuccess ? colors.button.disabled.color : null}
style={{ verticalAlign: 'middle', marginRight: '10px' }}
/>
)}
}
isLoading={isTestButtonLoading}
style={{ fontWeight: 600 }}
type="submit"

View File

@ -1,6 +1,7 @@
import React, { useEffect, useRef, useState } from 'react';
import { Redirect } from 'react-router-dom';
import PropTypes from 'prop-types';
import useNotification from '../../hooks/useNotification';
import useUser from '../../hooks/useUser';
import hasPermissions from '../../utils/hasPermissions';
import LoadingIndicatorPage from '../LoadingIndicatorPage';
@ -9,6 +10,7 @@ const CheckPagePermissions = ({ permissions, children }) => {
const abortController = new AbortController();
const { signal } = abortController;
const { userPermissions } = useUser();
const toggleNotification = useNotification();
const [state, setState] = useState({ isLoading: true, canAccess: false });
const isMounted = useRef(true);
@ -27,7 +29,7 @@ const CheckPagePermissions = ({ permissions, children }) => {
if (isMounted.current) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import useNotification from '../../hooks/useNotification';
import useUser from '../../hooks/useUser';
import hasPermissions from '../../utils/hasPermissions';
@ -9,6 +9,7 @@ import hasPermissions from '../../utils/hasPermissions';
const CheckPermissions = ({ permissions, children }) => {
const { userPermissions } = useUser();
const toggleNotification = useNotification();
const [state, setState] = useState({ isLoading: true, canAccess: false });
const isMounted = useRef(true);
const abortController = new AbortController();
@ -27,7 +28,7 @@ const CheckPermissions = ({ permissions, children }) => {
} catch (err) {
if (isMounted.current) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -0,0 +1,11 @@
/**
*
* NotificationsContext
*
*/
import { createContext } from 'react';
const NotificationsContext = createContext();
export default NotificationsContext;

View File

@ -0,0 +1,19 @@
/**
*
* useNotification
*
*/
import { useContext, useRef } from 'react';
import NotificationsContext from '../../contexts/NotificationsContext';
const useNotification = () => {
const { toggleNotification } = useContext(NotificationsContext);
// Use a ref so we can safely add the toggleNotification
// to a hook dependencies array
const toggleNotificationRef = useRef(toggleNotification);
return toggleNotificationRef.current;
};
export default useNotification;

View File

@ -105,6 +105,7 @@ export { default as PopUpWarningIcon } from './components/PopUpWarning/Icon';
export { default as PopUpWarningModal } from './components/PopUpWarning/StyledModal';
// Contexts
export { default as NotificationsContext } from './contexts/NotificationsContext';
export { GlobalContext, GlobalContextProvider, useGlobalContext } from './contexts/GlobalContext';
export { default as UserContext } from './contexts/UserContext';
export { default as ContentManagerEditViewDataManagerContext } from './contexts/ContentManagerEditViewDataManagerContext';
@ -113,6 +114,7 @@ export { default as ContentManagerEditViewDataManagerContext } from './contexts/
export { default as useContentManagerEditViewDataManager } from './hooks/useContentManagerEditViewDataManager';
export { default as useQuery } from './hooks/useQuery';
export { default as useLibrary } from './hooks/useLibrary';
export { default as useNotification } from './hooks/useNotification';
export { default as useStrapiApp } from './hooks/useStrapiApp';
export { default as useUser } from './hooks/useUser';
export { default as useUserPermissions } from './hooks/useUserPermissions';
@ -120,6 +122,7 @@ export { default as useQueryParams } from './hooks/useQueryParams';
// Providers
export { default as LibraryProvider } from './providers/LibraryProvider';
export { default as NotificationsProvider } from './providers/NotificationsProvider';
export { default as StrapiAppProvider } from './providers/StrapiAppProvider';
// Utils

View File

@ -0,0 +1,23 @@
/**
*
* NotificationsProvider
*
*/
import React from 'react';
import PropTypes from 'prop-types';
import NotificationsContext from '../../contexts/NotificationsContext';
const NotificationsProvider = ({ children, toggleNotification }) => {
return (
<NotificationsContext.Provider value={{ toggleNotification }}>
{children}
</NotificationsContext.Provider>
);
};
NotificationsProvider.propTypes = {
children: PropTypes.node.isRequired,
toggleNotification: PropTypes.func.isRequired,
};
export default NotificationsProvider;

View File

@ -14,7 +14,11 @@ import { get } from 'lodash';
import PropTypes from 'prop-types';
import { Row } from 'reactstrap';
import { Inputs } from '@buffetjs/custom';
import { useGlobalContext, prefixFileUrlWithBackendUrl } from '@strapi/helper-plugin';
import {
useGlobalContext,
useNotification,
prefixFileUrlWithBackendUrl,
} from '@strapi/helper-plugin';
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
import { createFileToDownloadName } from '../../utils';
@ -53,6 +57,7 @@ const EditForm = forwardRef(
},
ref
) => {
const toggleNotification = useNotification();
const { formatMessage } = useGlobalContext();
const [isCropping, setIsCropping] = useState(false);
const [infos, setInfos] = useState({ width: null, height: null });
@ -193,7 +198,7 @@ const EditForm = forwardRef(
};
const handleCopy = () => {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: 'notification.link-copied' },
});

View File

@ -6,6 +6,7 @@ import {
CheckPermissions,
LabelIconWrapper,
prefixFileUrlWithBackendUrl,
useNotification,
} from '@strapi/helper-plugin';
import pluginPermissions from '../../permissions';
import { getTrad, formatFileForEditing } from '../../utils';
@ -33,6 +34,7 @@ const InputMedia = ({
error,
labelIcon,
}) => {
const toggleNotification = useNotification();
const [modal, setModal] = useState({
isOpen: false,
step: 'list',
@ -108,7 +110,7 @@ const InputMedia = ({
};
const handleCopy = () => {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: 'notification.link-copied' },
});

View File

@ -10,6 +10,7 @@ import {
generateSearchFromFilters,
request,
useQuery,
useNotification,
} from '@strapi/helper-plugin';
import { formatFileForEditing, getRequestUrl, getTrad } from '../../utils';
import { useAppContext, useSelectTimestamps } from '../../hooks';
@ -21,6 +22,7 @@ import init from './init';
import reducer, { initialState } from './reducer';
const HomePage = () => {
const toggleNotification = useNotification();
const { allowedActions } = useAppContext();
const { canRead } = allowedActions;
const { formatMessage } = useGlobalContext();
@ -91,7 +93,7 @@ const HomePage = () => {
} catch (err) {
if (isMounted.current) {
dispatch({ type: 'GET_DATA_ERROR' });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -114,7 +116,7 @@ const HomePage = () => {
} catch (err) {
if (isMounted.current) {
dispatch({ type: 'GET_DATA_ERROR' });
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -232,7 +234,7 @@ const HomePage = () => {
type: 'ON_DELETE_MEDIAS_SUCCEEDED',
});
} catch (err) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: err,
});
@ -243,7 +245,7 @@ const HomePage = () => {
} finally {
setIsPopupOpen(false);
}
}, [dataToDelete]);
}, [dataToDelete, toggleNotification]);
const handleClosedModalDeleteAll = useCallback(() => {
if (shouldRefetchData) {

View File

@ -8,7 +8,7 @@ import { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { useDispatch } from 'react-redux';
import get from 'lodash/get';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import pluginId from '../../pluginId';
import { setFileModelTimestamps } from './actions';
@ -16,6 +16,7 @@ const Initializer = ({ setPlugin }) => {
const ref = useRef();
const dispatch = useDispatch();
ref.current = setPlugin;
const toggleNotification = useNotification();
useEffect(() => {
const getData = async () => {
@ -35,7 +36,7 @@ const Initializer = ({ setPlugin }) => {
ref.current(pluginId);
} catch (err) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'content-manager.error.model.fetch' },
});
@ -43,7 +44,7 @@ const Initializer = ({ setPlugin }) => {
};
getData();
}, [dispatch]);
}, [dispatch, toggleNotification]);
return null;
};

View File

@ -1,6 +1,13 @@
import React, { useEffect, useState, useRef, memo } from 'react';
import PropTypes from 'prop-types';
import { Modal, ModalFooter, PopUpWarning, useGlobalContext, request } from '@strapi/helper-plugin';
import {
Modal,
ModalFooter,
PopUpWarning,
useGlobalContext,
useNotification,
request,
} from '@strapi/helper-plugin';
import { Button } from '@buffetjs/core';
import { get, isEmpty, isEqual } from 'lodash';
import { getRequestUrl, getTrad } from '../../utils';
@ -19,6 +26,7 @@ const InputModalStepper = ({
const { emitEvent, formatMessage } = useGlobalContext();
const [shouldDeleteFile, setShouldDeleteFile] = useState(false);
const [displayNextButton, setDisplayNextButton] = useState(false);
const toggleNotification = useNotification();
const {
addFilesToUpload,
currentStep,
@ -210,7 +218,7 @@ const InputModalStepper = ({
['response', 'payload', 'message', '0', 'messages', '0', 'message'],
get(err, ['response', 'payload', 'message'], statusText)
);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: errorMessage,
});

View File

@ -1,6 +1,11 @@
import React, { useReducer, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { request, generateSearchFromFilters, useGlobalContext } from '@strapi/helper-plugin';
import {
request,
generateSearchFromFilters,
useGlobalContext,
useNotification,
} from '@strapi/helper-plugin';
import { clone, get, isEmpty, set } from 'lodash';
import { useIntl } from 'react-intl';
import axios from 'axios';
@ -37,6 +42,7 @@ const InputModalStepperProvider = ({
step,
}) => {
const [formErrors, setFormErrors] = useState(null);
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const { emitEvent } = useGlobalContext();
@ -338,7 +344,7 @@ const InputModalStepperProvider = ({
});
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -368,7 +374,7 @@ const InputModalStepperProvider = ({
});
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -2,7 +2,14 @@ import React, { useCallback, useEffect, useState, useReducer, useRef } from 'rea
import axios from 'axios';
import PropTypes from 'prop-types';
import { isEqual, isEmpty, get, set } from 'lodash';
import { Modal, ModalFooter, PopUpWarning, useGlobalContext, request } from '@strapi/helper-plugin';
import {
Modal,
ModalFooter,
PopUpWarning,
useGlobalContext,
request,
useNotification,
} from '@strapi/helper-plugin';
import { Button } from '@buffetjs/core';
import pluginId from '../../pluginId';
import { getFilesToDownload, getTrad, getYupError, urlSchema } from '../../utils';
@ -20,6 +27,7 @@ const ModalStepper = ({
onRemoveFileFromDataToDelete,
onToggle,
}) => {
const toggleNotification = useNotification();
const { allowedActions } = useAppContext();
const { emitEvent, formatMessage } = useGlobalContext();
const [isWarningDeleteOpen, setIsWarningDeleteOpen] = useState(false);
@ -191,7 +199,7 @@ const ModalStepper = ({
} catch (err) {
const errorMessage = get(err, 'response.payload.message', 'An error occured');
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: errorMessage,
});

View File

@ -3,7 +3,12 @@ import { Header, Inputs } from '@buffetjs/custom';
import { Helmet } from 'react-helmet';
import { Text } from '@buffetjs/core';
import { isEqual } from 'lodash';
import { LoadingIndicatorPage, useGlobalContext, request } from '@strapi/helper-plugin';
import {
LoadingIndicatorPage,
useGlobalContext,
useNotification,
request,
} from '@strapi/helper-plugin';
import { getRequestUrl, getTrad } from '../../utils';
import SectionTitleWrapper from './SectionTitleWrapper';
@ -17,6 +22,8 @@ const SettingsPage = () => {
const { initialData, isLoading, modifiedData } = reducerState.toJS();
const isMounted = useRef(true);
const getDataRef = useRef();
const toggleNotification = useNotification();
const abortController = new AbortController();
getDataRef.current = async () => {
@ -58,7 +65,7 @@ const SettingsPage = () => {
});
}
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'notification.form.success.fields' },
});

View File

@ -1,11 +1,13 @@
import React from 'react';
import { auth, InputsIndex as Input } from '@strapi/helper-plugin';
import { auth, InputsIndex as Input, useNotification } from '@strapi/helper-plugin';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import getTrad from '../../utils/getTrad';
const Copy = () => {
const toggleNotification = useNotification();
const handleCopy = () => {
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: getTrad('containers.HomePage.copied') },
});

View File

@ -1,13 +1,15 @@
import { useQuery, useMutation, useQueryClient } from 'react-query';
import { useNotification } from '@strapi/helper-plugin';
import { fetchData, deleteDoc, regenerateDoc, submit } from './utils/api';
import getTrad from '../../utils/getTrad';
const useHomePage = () => {
const queryClient = useQueryClient();
const { isLoading, data } = useQuery('get-documentation', fetchData);
const toggleNotification = useNotification();
const { isLoading, data } = useQuery('get-documentation', () => fetchData(toggleNotification));
const handleError = err => {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: err.response.payload.message,
});
@ -16,7 +18,7 @@ const useHomePage = () => {
const deleteMutation = useMutation(deleteDoc, {
onSuccess: () => {
queryClient.invalidateQueries('get-documentation');
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: getTrad('notification.delete.success') },
});
@ -28,7 +30,7 @@ const useHomePage = () => {
onSuccess: () => {
queryClient.invalidateQueries('get-documentation');
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('notification.update.success') },
});
@ -40,7 +42,7 @@ const useHomePage = () => {
onSuccess: () => {
queryClient.invalidateQueries('get-documentation');
strapi.notification.toggle({
toggleNotification({
type: 'info',
message: { id: getTrad('notification.generate.success') },
});

View File

@ -5,17 +5,18 @@ const deleteDoc = ({ prefix, version }) => {
return request(`${prefix}/deleteDoc/${version}`, { method: 'DELETE' });
};
const fetchData = async () => {
const fetchData = async toggleNotification => {
try {
const data = await request(`/${pluginId}/getInfos`, { method: 'GET' });
return data;
} catch (err) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
// FIXME
return null;
}
};

View File

@ -12,6 +12,7 @@ import {
ModalConfirm,
selectStyles,
useContentManagerEditViewDataManager,
useNotification,
request,
} from '@strapi/helper-plugin';
import { getTrad } from '../../utils';
@ -28,6 +29,7 @@ const CMEditViewCopyLocale = props => {
const Content = ({ appLocales, currentLocale, localizations, readPermissions }) => {
const options = generateOptions(appLocales, currentLocale, localizations, readPermissions);
const toggleNotification = useNotification();
const { formatMessage } = useIntl();
const dispatch = useDispatch();
const { allLayoutData, slug } = useContentManagerEditViewDataManager();
@ -52,7 +54,7 @@ const Content = ({ appLocales, currentLocale, localizations, readPermissions })
dispatch({ type: 'ContentManager/CrudReducer/GET_DATA_SUCCEEDED', data: cleanedData });
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: {
id: getTrad('CMEditViewCopyLocale.copy-success'),
@ -62,7 +64,7 @@ const Content = ({ appLocales, currentLocale, localizations, readPermissions })
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: {
id: getTrad('CMEditViewCopyLocale.copy-failure'),

View File

@ -8,6 +8,8 @@ import { fireEvent, render, screen, within, waitFor } from '@testing-library/rea
import { ThemeProvider } from 'styled-components';
import { QueryClient, QueryClientProvider } from 'react-query';
import LocaleSettingsPage from '..';
// eslint-disable-next-line import/extensions
import '@fortawesome/fontawesome-free/js/all.min.js';
// TODO: move to @strapi/helper-plugin
import themes from '../../../../../../../core/admin/admin/src/themes';
import i18nReducers, { initialState } from '../../../hooks/reducers';
@ -28,6 +30,8 @@ const TestWrapper = ({ children }) => {
);
};
const toggleNotificationMock = jest.fn();
// TODO: we should not be forced to mock this module
// but it bugs somehow when run with jest
jest.mock('@strapi/helper-plugin', () => ({
@ -65,6 +69,7 @@ jest.mock('@strapi/helper-plugin', () => ({
selectStyles: () => ({ control: () => ({}), indicatorsContainer: () => ({}) }),
useGlobalContext: () => ({ updateMenu: jest.fn() }),
useUser: () => ({ fetchUserPermissions: jest.fn() }),
useNotification: () => toggleNotificationMock,
}));
jest.mock('../../../utils', () => ({
@ -100,8 +105,6 @@ describe('i18n settings page', () => {
isLoading: false,
allowedActions: { canRead: true, canUpdate: true, canCreate: true, canDelete: true },
}));
strapi.notification.toggle = jest.fn();
});
afterEach(() => {
@ -175,7 +178,7 @@ describe('i18n settings page', () => {
fireEvent.click(screen.getByText('Confirm'));
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'success',
message: { id: 'Settings.locales.modal.delete.success' },
})
@ -215,7 +218,7 @@ describe('i18n settings page', () => {
fireEvent.click(screen.getByText('Confirm'));
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'warning',
message: { id: 'notification.error' },
})
@ -316,7 +319,7 @@ describe('i18n settings page', () => {
fireEvent.click(screen.getByText('Settings.locales.modal.edit.confirmation'));
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'warning',
message: { id: 'notification.error' },
})
@ -363,7 +366,7 @@ describe('i18n settings page', () => {
fireEvent.click(screen.getByText('Settings.locales.modal.edit.confirmation'));
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'success',
message: { id: 'Settings.locales.modal.edit.success' },
})
@ -422,7 +425,7 @@ describe('i18n settings page', () => {
fireEvent.click(screen.getByText('Settings.locales.modal.edit.confirmation'));
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'success',
message: { id: 'Settings.locales.modal.edit.success' },
})
@ -448,7 +451,7 @@ describe('i18n settings page', () => {
);
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'warning',
message: { id: 'notification.error' },
})
@ -697,7 +700,7 @@ describe('i18n settings page', () => {
fireEvent.click(confirmationButton);
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'warning',
message: { id: 'notification.error' },
})
@ -732,7 +735,7 @@ describe('i18n settings page', () => {
fireEvent.click(confirmationButton);
await waitFor(() =>
expect(strapi.notification.toggle).toBeCalledWith({
expect(toggleNotificationMock).toBeCalledWith({
type: 'success',
message: { id: 'Settings.locales.modal.create.success' },
})

View File

@ -1,11 +1,11 @@
import { useState } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { useDispatch } from 'react-redux';
import get from 'lodash/get';
import { getTrad } from '../../utils';
import { ADD_LOCALE } from '../constants';
const addLocale = async ({ code, name, isDefault }) => {
const addLocale = async ({ code, name, isDefault }, toggleNotification) => {
const data = await request(`/i18n/locales`, {
method: 'POST',
body: {
@ -15,7 +15,7 @@ const addLocale = async ({ code, name, isDefault }) => {
},
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('Settings.locales.modal.create.success') },
});
@ -26,23 +26,24 @@ const addLocale = async ({ code, name, isDefault }) => {
const useAddLocale = () => {
const [isLoading, setLoading] = useState(false);
const dispatch = useDispatch();
const toggleNotification = useNotification();
const persistLocale = async locale => {
setLoading(true);
try {
const newLocale = await addLocale(locale);
const newLocale = await addLocale(locale, toggleNotification);
dispatch({ type: ADD_LOCALE, newLocale });
} catch (e) {
const message = get(e, 'response.payload.message', null);
if (message && message.includes('already exists')) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: getTrad('Settings.locales.modal.create.alreadyExist') },
});
} else {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,7 +1,7 @@
import { useQuery } from 'react-query';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
const fetchDefaultLocalesList = async () => {
const fetchDefaultLocalesList = async toggleNotification => {
try {
const data = await request('/i18n/iso-locales', {
method: 'GET',
@ -9,7 +9,7 @@ const fetchDefaultLocalesList = async () => {
return data;
} catch (e) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -19,7 +19,10 @@ const fetchDefaultLocalesList = async () => {
};
const useDefaultLocales = () => {
const { isLoading, data } = useQuery('default-locales', fetchDefaultLocalesList);
const toggleNotification = useNotification();
const { isLoading, data } = useQuery('default-locales', () =>
fetchDefaultLocalesList(toggleNotification)
);
return { defaultLocales: data, isLoading };
};

View File

@ -1,23 +1,23 @@
import { useState } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { useDispatch } from 'react-redux';
import { getTrad } from '../../utils';
import { DELETE_LOCALE } from '../constants';
const deleteLocale = async id => {
const deleteLocale = async (id, toggleNotification) => {
try {
const data = await request(`/i18n/locales/${id}`, {
method: 'DELETE',
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('Settings.locales.modal.delete.success') },
});
return data;
} catch (e) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -29,11 +29,12 @@ const deleteLocale = async id => {
const useDeleteLocale = () => {
const [isLoading, setLoading] = useState(false);
const dispatch = useDispatch();
const toggleNotification = useNotification();
const removeLocale = async id => {
setLoading(true);
await deleteLocale(id);
await deleteLocale(id, toggleNotification);
dispatch({ type: DELETE_LOCALE, id });
setLoading(false);

View File

@ -1,24 +1,24 @@
import { useState } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { useDispatch } from 'react-redux';
import { getTrad } from '../../utils';
import { UPDATE_LOCALE } from '../constants';
const editLocale = async (id, payload) => {
const editLocale = async (id, payload, toggleNotification) => {
try {
const data = await request(`/i18n/locales/${id}`, {
method: 'PUT',
body: payload,
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('Settings.locales.modal.edit.success') },
});
return data;
} catch {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -30,11 +30,12 @@ const editLocale = async (id, payload) => {
const useEditLocale = () => {
const [isLoading, setLoading] = useState(false);
const dispatch = useDispatch();
const toggleNotification = useNotification();
const modifyLocale = async (id, payload) => {
setLoading(true);
const editedLocale = await editLocale(id, payload);
const editedLocale = await editLocale(id, payload, toggleNotification);
dispatch({ type: UPDATE_LOCALE, editedLocale });
setLoading(false);

View File

@ -1,9 +1,9 @@
import { useEffect } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { useSelector, useDispatch } from 'react-redux';
import { RESOLVE_LOCALES } from '../constants';
const fetchLocalesList = async () => {
const fetchLocalesList = async toggleNotification => {
try {
const data = await request('/i18n/locales', {
method: 'GET',
@ -11,7 +11,7 @@ const fetchLocalesList = async () => {
return data;
} catch (e) {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -22,12 +22,15 @@ const fetchLocalesList = async () => {
const useLocales = () => {
const dispatch = useDispatch();
const toggleNotification = useNotification();
const locales = useSelector(state => state.i18n_locales.locales);
const isLoading = useSelector(state => state.i18n_locales.isLoading);
useEffect(() => {
fetchLocalesList().then(locales => dispatch({ type: RESOLVE_LOCALES, locales }));
}, [dispatch]);
fetchLocalesList(toggleNotification).then(locales =>
dispatch({ type: RESOLVE_LOCALES, locales })
);
}, [dispatch, toggleNotification]);
return { locales, isLoading };
};

View File

@ -9,6 +9,7 @@ import {
SizedInput,
useUserPermissions,
request,
useNotification,
} from '@strapi/helper-plugin';
import pluginPermissions from '../../permissions';
import { getTrad, getRequestURL } from '../../utils';
@ -18,6 +19,7 @@ import reducer, { initialState } from './reducer';
const AdvancedSettingsPage = () => {
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const [showModalWarning, setShowModalWarning] = useState(false);
const pageTitle = formatMessage({ id: getTrad('HeaderNav.link.advancedSettings') });
const updatePermissions = useMemo(() => {
@ -54,7 +56,7 @@ const AdvancedSettingsPage = () => {
type: 'GET_DATA_ERROR',
});
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -98,7 +100,7 @@ const AdvancedSettingsPage = () => {
type: 'ON_SUBMIT_SUCCEEDED',
});
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('notification.success.submit') },
});
@ -107,7 +109,7 @@ const AdvancedSettingsPage = () => {
type: 'ON_SUBMIT_ERROR',
});
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -115,7 +117,7 @@ const AdvancedSettingsPage = () => {
strapi.unlockApp();
},
[modifiedData]
[modifiedData, toggleNotification]
);
const handleConfirmReset = useCallback(() => {

View File

@ -9,6 +9,7 @@ import {
useGlobalContext,
request,
getYupInnerErrors,
useNotification,
} from '@strapi/helper-plugin';
import { Row } from 'reactstrap';
import pluginPermissions from '../../permissions';
@ -23,6 +24,7 @@ import schema from './utils/schema';
const EmailTemplatesPage = () => {
const { formatMessage } = useIntl();
const { emitEvent } = useGlobalContext();
const toggleNotification = useNotification();
const emitEventRef = useRef(emitEvent);
const buttonSubmitRef = useRef(null);
const pageTitle = formatMessage({ id: getTrad('HeaderNav.link.emailTemplates') });
@ -111,7 +113,7 @@ const EmailTemplatesPage = () => {
emitEventRef.current('didEditEmailTemplates');
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('notification.success.submit') },
});
@ -122,7 +124,7 @@ const EmailTemplatesPage = () => {
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -136,7 +138,14 @@ const EmailTemplatesPage = () => {
dispatchSetFormErrors(errors);
},
[dispatchSetFormErrors, dispatchSubmitSucceeded, modifiedData, templateToEdit, handleToggle]
[
dispatchSetFormErrors,
dispatchSubmitSucceeded,
modifiedData,
templateToEdit,
handleToggle,
toggleNotification,
]
);
const handleClick = useCallback(() => {

View File

@ -9,6 +9,7 @@ import {
useGlobalContext,
getYupInnerErrors,
request,
useNotification,
} from '@strapi/helper-plugin';
import { get, upperFirst, has } from 'lodash';
import { Row } from 'reactstrap';
@ -30,6 +31,7 @@ const ProvidersPage = () => {
const buttonSubmitRef = useRef(null);
const [showForm, setShowForm] = useState(false);
const [providerToEditName, setProviderToEditName] = useState(null);
const toggleNotification = useNotification();
const updatePermissions = useMemo(() => {
return { update: pluginPermissions.updateProviders };
@ -150,7 +152,7 @@ const ProvidersPage = () => {
emitEventRef.current('didEditAuthenticationProvider');
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('notification.success.submit') },
});
@ -160,7 +162,7 @@ const ProvidersPage = () => {
handleToggle();
} catch (err) {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});
@ -183,6 +185,7 @@ const ProvidersPage = () => {
handleToggle,
modifiedData,
providerToEditName,
toggleNotification,
]
);

View File

@ -4,7 +4,7 @@ import { Header } from '@buffetjs/custom';
import { Padded } from '@buffetjs/core';
import { Formik } from 'formik';
import { useIntl } from 'react-intl';
import { request, useGlobalContext } from '@strapi/helper-plugin';
import { request, useGlobalContext, useNotification } from '@strapi/helper-plugin';
import BaselineAlignement from '../../../components/BaselineAlignement';
import ContainerFluid from '../../../components/ContainerFluid';
import FormCard from '../../../components/FormBloc';
@ -18,6 +18,7 @@ import schema from './utils/schema';
const CreatePage = () => {
const { formatMessage } = useIntl();
const { emitEvent } = useGlobalContext();
const toggleNotification = useNotification();
const { goBack } = useHistory();
const [isSubmiting, setIsSubmiting] = useState(false);
const { permissions, routes, policies, isLoading } = usePlugins();
@ -68,7 +69,7 @@ const CreatePage = () => {
)
.then(() => {
emitEvent('didCreateRole');
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: 'Settings.roles.created' },
});
@ -78,7 +79,7 @@ const CreatePage = () => {
})
.catch(err => {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -4,7 +4,7 @@ import { Padded } from '@buffetjs/core';
import { Formik } from 'formik';
import { useIntl } from 'react-intl';
import { useRouteMatch } from 'react-router-dom';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import BaselineAlignement from '../../../components/BaselineAlignement';
import ContainerFluid from '../../../components/ContainerFluid';
@ -20,6 +20,7 @@ import schema from './utils/schema';
const EditPage = () => {
const { formatMessage } = useIntl();
const [isSubmiting, setIsSubmiting] = useState(false);
const toggleNotification = useNotification();
const {
params: { id },
} = useRouteMatch(`/settings/${pluginId}/roles/:id`);
@ -73,14 +74,14 @@ const EditPage = () => {
.then(() => {
onSubmitSucceeded({ name: data.name, description: data.description });
permissionsRef.current.setFormAfterSubmit();
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('Settings.roles.edited') },
});
})
.catch(err => {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -4,7 +4,13 @@ import { Helmet } from 'react-helmet';
import { useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { useUserPermissions, PopUpWarning, request, useGlobalContext } from '@strapi/helper-plugin';
import {
useUserPermissions,
PopUpWarning,
request,
useGlobalContext,
useNotification,
} from '@strapi/helper-plugin';
import permissions from '../../../permissions';
import { EmptyRole, RoleListWrapper, RoleRow } from '../../../components/Roles';
@ -17,6 +23,7 @@ const RoleListPage = () => {
const { formatMessage } = useIntl();
const { emitEvent } = useGlobalContext();
const { push } = useHistory();
const toggleNotification = useNotification();
const [modalToDelete, setModalDelete] = useState();
const [shouldRefetchData, setShouldRefetchData] = useState(false);
@ -56,14 +63,14 @@ const RoleListPage = () => {
)
.then(() => {
setShouldRefetchData(true);
strapi.notification.toggle({
toggleNotification({
type: 'success',
message: { id: getTrad('Settings.roles.deleted') },
});
})
.catch(err => {
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,12 +1,11 @@
import { useCallback, useReducer, useEffect } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import reducer, { initialState } from './reducer';
import pluginId from '../../pluginId';
const useFetchRole = id => {
const [state, dispatch] = useReducer(reducer, initialState);
const toggleNotification = useNotification();
useEffect(() => {
if (id) {
@ -35,7 +34,7 @@ const useFetchRole = id => {
dispatch({
type: 'GET_DATA_ERROR',
});
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,5 +1,5 @@
import { useCallback, useEffect, useReducer, useRef } from 'react';
import { useUserPermissions, request } from '@strapi/helper-plugin';
import { useUserPermissions, request, useNotification } from '@strapi/helper-plugin';
import { getRequestURL } from '../../utils';
import reducer, { initialState } from './reducer';
@ -9,7 +9,7 @@ const useUserForm = (endPoint, permissions) => {
reducer,
initialState
);
const toggleNotification = useNotification();
const isMounted = useRef(true);
const abortController = new AbortController();
@ -35,7 +35,7 @@ const useUserForm = (endPoint, permissions) => {
type: 'GET_DATA_ERROR',
});
console.error(err);
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message: { id: 'notification.error' },
});

View File

@ -1,5 +1,5 @@
import { useCallback, useEffect, useReducer } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { useIntl } from 'react-intl';
import { get } from 'lodash';
import init from './init';
@ -9,6 +9,7 @@ import reducer, { initialState } from './reducer';
const usePlugins = (shouldFetchData = true) => {
const { formatMessage } = useIntl();
const toggleNotification = useNotification();
const [{ permissions, routes, policies, isLoading }, dispatch] = useReducer(
reducer,
initialState,
@ -47,13 +48,13 @@ const usePlugins = (shouldFetchData = true) => {
});
if (message !== 'Forbidden') {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message,
});
}
}
}, [formatMessage]);
}, [formatMessage, toggleNotification]);
useEffect(() => {
if (shouldFetchData) {

View File

@ -1,5 +1,5 @@
import { useEffect, useReducer, useRef } from 'react';
import { request } from '@strapi/helper-plugin';
import { request, useNotification } from '@strapi/helper-plugin';
import { get } from 'lodash';
import init from './init';
import pluginId from '../../pluginId';
@ -9,6 +9,7 @@ const useRolesList = (shouldFetchData = true) => {
const [{ roles, isLoading }, dispatch] = useReducer(reducer, initialState, () =>
init(initialState, shouldFetchData)
);
const toggleNotification = useNotification();
const isMounted = useRef(true);
const abortController = new AbortController();
@ -47,7 +48,7 @@ const useRolesList = (shouldFetchData = true) => {
});
if (message !== 'Forbidden') {
strapi.notification.toggle({
toggleNotification({
type: 'warning',
message,
});