Display errors

Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
soupette 2021-09-03 09:34:15 +02:00
parent d1609eb111
commit 7e2f8063a8
4 changed files with 50 additions and 20 deletions

View File

@ -1,7 +1,8 @@
import React, { useMemo } from 'react'; import React, { useMemo, useState } from 'react';
// TODO: DS add loader // TODO: DS add loader
import { LoadingIndicatorPage, AppInfosContext } from '@strapi/helper-plugin'; import { auth, LoadingIndicatorPage, AppInfosContext } from '@strapi/helper-plugin';
import { useQueries } from 'react-query'; import { useQueries } from 'react-query';
import get from 'lodash/get';
import packageJSON from '../../../../package.json'; import packageJSON from '../../../../package.json';
import { useConfigurations } from '../../hooks'; import { useConfigurations } from '../../hooks';
import PluginsInitializer from '../PluginsInitializer'; import PluginsInitializer from '../PluginsInitializer';
@ -12,6 +13,9 @@ import checkLatestStrapiVersion from './utils/checkLatestStrapiVersion';
const strapiVersion = packageJSON.version; const strapiVersion = packageJSON.version;
const AuthenticatedApp = () => { const AuthenticatedApp = () => {
const userInfo = auth.getUserInfo();
const userName = get(userInfo, 'username', `${userInfo.firstname} ${userInfo.lastname}`);
const [userDisplayName, setUserDisplayName] = useState(userName);
const { showReleaseNotification } = useConfigurations(); const { showReleaseNotification } = useConfigurations();
const [ const [
{ data: appInfos, status }, { data: appInfos, status },
@ -54,7 +58,13 @@ const AuthenticatedApp = () => {
return ( return (
<AppInfosContext.Provider <AppInfosContext.Provider
value={{ ...appInfos, latestStrapiReleaseTag: tag_name, shouldUpdateStrapi }} value={{
...appInfos,
latestStrapiReleaseTag: tag_name,
setUserDisplayName,
shouldUpdateStrapi,
userDisplayName,
}}
> >
<RBACProvider permissions={permissions} refetchPermissions={refetch}> <RBACProvider permissions={permissions} refetchPermissions={refetch}>
<PluginsInitializer /> <PluginsInitializer />

View File

@ -9,6 +9,11 @@ import AuthenticatedApp from '..';
const strapiVersion = packageJSON.version; const strapiVersion = packageJSON.version;
jest.mock('@strapi/helper-plugin', () => ({
...jest.requireActual('@strapi/helper-plugin'),
auth: { getUserInfo: () => ({ firstname: 'kai', lastname: 'doe' }) },
}));
jest.mock('../utils/api', () => ({ jest.mock('../utils/api', () => ({
fetchStrapiLatestRelease: jest.fn(), fetchStrapiLatestRelease: jest.fn(),
fetchAppInfo: jest.fn(), fetchAppInfo: jest.fn(),

View File

@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import get from 'lodash/get';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { import {
MainNav, MainNav,
@ -16,23 +16,14 @@ import {
Button, Button,
} from '@strapi/parts'; } from '@strapi/parts';
import ContentIcon from '@strapi/icons/ContentIcon'; import ContentIcon from '@strapi/icons/ContentIcon';
import { auth, usePersistentState } from '@strapi/helper-plugin'; import { auth, usePersistentState, useAppInfos } from '@strapi/helper-plugin';
import useConfigurations from '../../hooks/useConfigurations'; import useConfigurations from '../../hooks/useConfigurations';
const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => { const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => {
const { menuLogo } = useConfigurations(); const { menuLogo } = useConfigurations();
const { push } = useHistory(); const { push } = useHistory();
const [condensed, setCondensed] = usePersistentState('navbar-condensed', false); const [condensed, setCondensed] = usePersistentState('navbar-condensed', false);
const { userDisplayName } = useAppInfos();
const userInfo = auth.getUserInfo();
let displayName;
if (userInfo && userInfo.firstname && userInfo.lastname) {
displayName = `${userInfo.firstname} ${userInfo.lastname}`;
} else {
displayName = get(userInfo, 'username', '');
}
return ( return (
<MainNav condensed={condensed}> <MainNav condensed={condensed}>
@ -81,7 +72,7 @@ const LeftMenu = ({ generalSectionLinks, pluginsSectionLinks }) => {
</NavSections> </NavSections>
<NavUser src="https://avatars.githubusercontent.com/u/3874873?v=4" to="/me"> <NavUser src="https://avatars.githubusercontent.com/u/3874873?v=4" to="/me">
{displayName} {userDisplayName}
</NavUser> </NavUser>
<NavCondense onClick={() => setCondensed(s => !s)}> <NavCondense onClick={() => setCondensed(s => !s)}>

View File

@ -3,12 +3,14 @@ import { useRouteMatch, useHistory } from 'react-router-dom';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import pick from 'lodash/pick'; import pick from 'lodash/pick';
import get from 'lodash/get';
import { import {
CustomContentLayout, CustomContentLayout,
Form, Form,
GenericInput, GenericInput,
SettingsPageTitle, SettingsPageTitle,
// auth, auth,
useAppInfos,
useFocusWhenNavigate, useFocusWhenNavigate,
useNotification, useNotification,
useOverlayBlocker, useOverlayBlocker,
@ -24,6 +26,7 @@ import { Main } from '@strapi/parts/Main';
import { Stack } from '@strapi/parts/Stack'; import { Stack } from '@strapi/parts/Stack';
import { CheckIcon } from '@strapi/icons'; import { CheckIcon } from '@strapi/icons';
import MagicLink from 'ee_else_ce/pages/Users/components/MagicLink'; import MagicLink from 'ee_else_ce/pages/Users/components/MagicLink';
import { formatAPIErrors } from '../../../utils';
import { fetchUser, putUser } from './utils/api'; import { fetchUser, putUser } from './utils/api';
import layout from './utils/layout'; import layout from './utils/layout';
import { editValidation } from '../utils/validations/users'; import { editValidation } from '../utils/validations/users';
@ -37,6 +40,7 @@ const EditPage = ({ canUpdate }) => {
params: { id }, params: { id },
} = useRouteMatch('/settings/users/:id'); } = useRouteMatch('/settings/users/:id');
const { push } = useHistory(); const { push } = useHistory();
const { setUserDisplayName } = useAppInfos();
const toggleNotification = useNotification(); const toggleNotification = useNotification();
const { lockApp, unlockApp } = useOverlayBlocker(); const { lockApp, unlockApp } = useOverlayBlocker();
@ -65,15 +69,35 @@ const EditPage = ({ canUpdate }) => {
}, },
}); });
const handleSubmit = async body => { const handleSubmit = async (body, actions) => {
lockApp(); lockApp();
try { try {
await putUser(id, body); const data = await putUser(id, body);
const userInfos = auth.getUserInfo();
// The user is updating himself
if (id.toString() === userInfos.id.toString()) {
auth.setUserInfo(data);
const userDisplayName = get(body, 'username', `${body.firstname} ${body.lastname}`);
setUserDisplayName(userDisplayName);
}
} catch (err) { } catch (err) {
// FIXME when API errors are ready
const errors = formatAPIErrors(err.response.data);
const fieldsErrors = Object.keys(errors).reduce((acc, current) => {
acc[current] = errors[current].id;
return acc;
}, {});
actions.setErrors(fieldsErrors);
toggleNotification({ toggleNotification({
type: 'warning', type: 'warning',
message: data.message, message: get(err, 'response.data.message', 'notification.error'),
}); });
} }