Merge pull request #5633 from paulkaplan/remove-debug-errors

Improve errors around following studios
This commit is contained in:
Paul Kaplan 2021-06-18 15:01:23 -04:00 committed by GitHub
commit 6e43607a1d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 100 additions and 50 deletions

6
package-lock.json generated
View file

@ -7613,6 +7613,12 @@
}
}
},
"eslint-plugin-react-hooks": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz",
"integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==",
"dev": true
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",

View file

@ -86,6 +86,7 @@
"eslint-config-scratch": "7.0.0",
"eslint-plugin-json": "2.0.1",
"eslint-plugin-react": "7.14.2",
"eslint-plugin-react-hooks": "^4.2.0",
"fastly": "1.2.1",
"formik": "1.5.4",
"formsy-react": "1.1.4",

View file

@ -7,7 +7,7 @@ module.exports = {
globals: {
process: true
},
plugins: ['json'],
plugins: ['json', 'react-hooks'],
settings: {
react: {
version: 'detect'
@ -17,6 +17,7 @@ module.exports = {
'camelcase': [2, {
properties: 'never', // This is from the base `scratch` config
allow: ['^UNSAFE_'] // Allow until migrated to new lifecycle methods
}]
}],
'react-hooks/rules-of-hooks': 'error'
}
};

View file

@ -1,18 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
const Debug = ({label, data}) => (<div style={{padding: '2rem', border: '1px solid red', margin: '2rem'}}>
<small>{label}</small>
<code>
<pre style={{fontSize: '0.75rem'}}>
{JSON.stringify(data, null, ' ')}
</pre>
</code>
</div>);
Debug.propTypes = {
label: PropTypes.string,
data: PropTypes.any // eslint-disable-line react/forbid-prop-types
};
export default Debug;

View file

@ -18,6 +18,15 @@
"studio.updateErrors.thumbnailTooLarge": "Maximum file size is 512 KB and less than 500x500 pixels.",
"studio.updateErrors.thumbnailInvalid": "Upload a valid image. The file you uploaded was either not an image or a corrupted image.",
"studio.followErrors.confirmEmail": "Please confirm your email address first",
"studio.followErrors.generic": "Something went wrong following the studio",
"studio.sectionLoadError.projectsHeadline": "Something went wrong loading projects",
"studio.sectionLoadError.curatorsHeadline": "Something went wrong loading curators",
"studio.sectionLoadError.managersHeadline": "Something went wrong loading managers",
"studio.sectionLoadError.activityHeadline": "Something went wrong loading activity",
"studio.sectionLoadError.tryAgain": "Try again",
"studio.projectsHeader": "Projects",
"studio.addProjectsHeader": "Add Projects",
"studio.addProject": "Add",

View file

@ -6,7 +6,6 @@ import {connect} from 'react-redux';
import {activity} from './lib/redux-modules';
import {loadActivity} from './lib/studio-activity-actions';
import Debug from './debug.jsx';
import classNames from 'classnames';
import SocialMessage from '../../components/social-message/social-message.jsx';
@ -181,10 +180,15 @@ const StudioActivity = ({items, loading, error, moreToLoad, onLoadMore}) => {
<h2><FormattedMessage id="studio.activityHeader" /></h2>
</div>
{loading && <div>Loading...</div>}
{error && <Debug
label="Error"
data={error}
/>}
{error && <div className="studio-section-load-error studio-info-box studio-info-box-error">
<h3><FormattedMessage id="studio.sectionLoadError.activityHeadline" /></h3>
<button
className="button"
onClick={onLoadMore}
>
<FormattedMessage id="studio.sectionLoadError.tryAgain" />
</button>
</div>}
<ul
className="studio-messages-list"
>

View file

@ -5,7 +5,6 @@ import {FormattedMessage} from 'react-intl';
import classNames from 'classnames';
import {curators} from './lib/redux-modules';
import Debug from './debug.jsx';
import {CuratorTile} from './studio-member-tile.jsx';
import CuratorInviter from './studio-curator-inviter.jsx';
import {loadCurators} from './lib/studio-member-actions';
@ -28,10 +27,15 @@ const StudioCurators = ({
<h2><FormattedMessage id="studio.curatorsHeader" /></h2>
</div>
{canInviteCurators && <CuratorInviter />}
{error && <Debug
label="Error"
data={error}
/>}
{error && <div className="studio-section-load-error studio-info-box studio-info-box-error">
<h3><FormattedMessage id="studio.sectionLoadError.curatorsHeadline" /></h3>
<button
className="button"
onClick={onLoadMore}
>
<FormattedMessage id="studio.sectionLoadError.tryAgain" />
</button>
</div>}
<div className="studio-members-grid">
{items.length === 0 && !loading ? (
<div className="studio-empty">

View file

@ -1,15 +1,24 @@
/* eslint-disable react/jsx-no-bind */
import React from 'react';
import React, {useState} from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {FormattedMessage} from 'react-intl';
import onClickOutside from 'react-onclickoutside';
import {selectIsFollowing} from '../../redux/studio';
import {selectCanFollowStudio} from '../../redux/studio-permissions';
import {
mutateFollowingStudio, selectIsMutatingFollowing, selectFollowingMutationError
mutateFollowingStudio, selectIsMutatingFollowing, selectFollowingMutationError, Errors
} from '../../redux/studio-mutations';
import classNames from 'classnames';
import ValidationMessage from '../../components/forms/validation-message.jsx';
const errorToMessageId = error => {
switch (error) {
case Errors.PERMISSION: return 'studio.followErrors.confirmEmail';
default: return 'studio.followErrors.generic';
}
};
const StudioFollow = ({
canFollow,
@ -18,16 +27,24 @@ const StudioFollow = ({
followingError,
handleFollow
}) => {
if (!canFollow) return null;
const fieldClassName = classNames('button', 'studio-follow-button', {
'mod-mutating': isMutating
});
const [hideValidationMessage, setHideValidationMessage] = useState(false);
StudioFollow.handleClickOutside = () => {
setHideValidationMessage(true);
};
if (!canFollow) return null;
return (
<React.Fragment>
<div className="studio-info-section">
<button
className={fieldClassName}
disabled={isMutating}
onClick={() => handleFollow(!isFollowing)}
onClick={() => {
setHideValidationMessage(false);
handleFollow(!isFollowing);
}}
>
{isMutating ? '...' : (
isFollowing ?
@ -35,8 +52,11 @@ const StudioFollow = ({
<FormattedMessage id="studio.followStudio" />
)}
</button>
{followingError && <div>Error mutating following: {followingError}</div>}
</React.Fragment >
{followingError && !hideValidationMessage && <ValidationMessage
mode="error"
message={<FormattedMessage id={errorToMessageId(followingError)} />}
/>}
</div>
);
};
@ -48,6 +68,10 @@ StudioFollow.propTypes = {
handleFollow: PropTypes.func
};
const clickOutsideConfig = {
handleClickOutside: () => StudioFollow.handleClickOutside
};
export default connect(
state => ({
canFollow: selectCanFollowStudio(state),
@ -58,4 +82,4 @@ export default connect(
{
handleFollow: mutateFollowingStudio
}
)(StudioFollow);
)(onClickOutside(StudioFollow, clickOutsideConfig));

View file

@ -12,7 +12,6 @@ import {
selectStudioHasReachedManagerThreshold
} from '../../redux/studio.js';
import {loadManagers} from './lib/studio-member-actions';
import Debug from './debug.jsx';
import {ManagerTile} from './studio-member-tile.jsx';
import StudioInfoBox from './studio-info-box.jsx';
import AlertProvider from '../../components/alert/alert-provider.jsx';
@ -85,10 +84,15 @@ const StudioManagers = ({
</div>
}
</div>
{error && <Debug
label="Error"
data={error}
/>}
{error && <div className="studio-section-load-error studio-info-box studio-info-box-error">
<h3><FormattedMessage id="studio.sectionLoadError.managersHeadline" /></h3>
<button
className="button"
onClick={onLoadMore}
>
<FormattedMessage id="studio.sectionLoadError.tryAgain" />
</button>
</div>}
<div className="studio-members-grid">
{items.map(item =>
(<ManagerTile

View file

@ -7,7 +7,6 @@ import classNames from 'classnames';
import {projects} from './lib/redux-modules';
import {selectCanAddProjects, selectCanEditOpenToAll, selectShowProjectMuteError} from '../../redux/studio-permissions';
import Debug from './debug.jsx';
import StudioProjectAdder from './studio-project-adder.jsx';
import StudioProjectTile from './studio-project-tile.jsx';
import {loadProjects} from './lib/studio-project-actions.js';
@ -49,12 +48,19 @@ const StudioProjects = ({
</CommentingStatus>
}
{canAddProjects && <StudioProjectAdder />}
{error && <Debug
label="Error"
data={error}
/>}
{error && <div className="studio-section-load-error studio-info-box studio-info-box-error">
<h3><FormattedMessage id="studio.sectionLoadError.projectsHeadline" /></h3>
<button
className="button"
onClick={onLoadMore}
>
<FormattedMessage id="studio.sectionLoadError.tryAgain" />
</button>
</div>}
<div className="studio-projects-grid">
{items.length === 0 && !loading ? (
{items.length === 0 && !loading && !error ? (
<div className="studio-empty">
{canAddProjects ? (
<React.Fragment>

View file

@ -174,9 +174,18 @@ $radius: 8px;
padding-bottom: 14px;
font-size: 14px;
margin: 0;
width: 100%;
box-sizing: border-box;
}
}
.studio-section-load-error {
margin-top: 2rem;
padding: 1rem;
flex-direction: column;
text-align: center;
}
.studio-tab-nav {
border-bottom: 1px solid $active-dark-gray;
padding-bottom: 8px;