More detailed error boundary for Document
This commit is contained in:
@ -8,7 +8,7 @@ type Props = {
|
|||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 60px;
|
padding: 60px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Content = styled.div`
|
const Content = styled.div`
|
||||||
|
@ -9,6 +9,14 @@ import PageTitle from 'components/PageTitle';
|
|||||||
class ErrorBoundary extends Component {
|
class ErrorBoundary extends Component {
|
||||||
@observable error: boolean = false;
|
@observable error: boolean = false;
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps: Object) {
|
||||||
|
if (
|
||||||
|
(this.props.location || nextProps.location) &&
|
||||||
|
this.props.location.pathname !== nextProps.location.pathname
|
||||||
|
)
|
||||||
|
this.error = false;
|
||||||
|
}
|
||||||
|
|
||||||
componentDidCatch(error: Error, info: Object) {
|
componentDidCatch(error: Error, info: Object) {
|
||||||
this.error = true;
|
this.error = true;
|
||||||
|
|
||||||
@ -27,9 +35,10 @@ class ErrorBoundary extends Component {
|
|||||||
return (
|
return (
|
||||||
<CenteredContent>
|
<CenteredContent>
|
||||||
<PageTitle title="Something went wrong" />
|
<PageTitle title="Something went wrong" />
|
||||||
<h1>Something went wrong</h1>
|
<h1>🛸 Something unexpected happened</h1>
|
||||||
<p>
|
<p>
|
||||||
An unrecoverable error occurred. Please try{' '}
|
An unrecoverable error occurred{window.Bugsnag ||
|
||||||
|
(true && ' and our engineers have been notified')}. Please try{' '}
|
||||||
<a onClick={this.handleReload}>reloading</a>.
|
<a onClick={this.handleReload}>reloading</a>.
|
||||||
</p>
|
</p>
|
||||||
</CenteredContent>
|
</CenteredContent>
|
||||||
|
@ -33,6 +33,7 @@ import CenteredContent from 'components/CenteredContent';
|
|||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
import NewDocumentIcon from 'components/Icon/NewDocumentIcon';
|
import NewDocumentIcon from 'components/Icon/NewDocumentIcon';
|
||||||
import Actions, { Action, Separator } from 'components/Actions';
|
import Actions, { Action, Separator } from 'components/Actions';
|
||||||
|
import ErrorBoundary from 'components/ErrorBoundary';
|
||||||
import Search from 'scenes/Search';
|
import Search from 'scenes/Search';
|
||||||
|
|
||||||
const DISCARD_CHANGES = `
|
const DISCARD_CHANGES = `
|
||||||
@ -216,75 +217,77 @@ class DocumentScene extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container column auto>
|
<Container column auto>
|
||||||
{isMoving && document && <DocumentMove document={document} />}
|
<ErrorBoundary location={this.props.location}>
|
||||||
{titleText && <PageTitle title={titleText} />}
|
{isMoving && document && <DocumentMove document={document} />}
|
||||||
{(this.isLoading || this.isSaving) && <LoadingIndicator />}
|
{titleText && <PageTitle title={titleText} />}
|
||||||
{isFetching && (
|
{(this.isLoading || this.isSaving) && <LoadingIndicator />}
|
||||||
<CenteredContent>
|
{isFetching && (
|
||||||
<LoadingState />
|
<CenteredContent>
|
||||||
</CenteredContent>
|
<LoadingState />
|
||||||
)}
|
</CenteredContent>
|
||||||
{!isFetching &&
|
|
||||||
document && (
|
|
||||||
<Flex justify="center" auto>
|
|
||||||
<Prompt
|
|
||||||
when={document.hasPendingChanges}
|
|
||||||
message={DISCARD_CHANGES}
|
|
||||||
/>
|
|
||||||
<Editor
|
|
||||||
key={`${document.id}-${document.revision}`}
|
|
||||||
text={document.text}
|
|
||||||
emoji={document.emoji}
|
|
||||||
onImageUploadStart={this.onImageUploadStart}
|
|
||||||
onImageUploadStop={this.onImageUploadStop}
|
|
||||||
onChange={this.onChange}
|
|
||||||
onSave={this.onSave}
|
|
||||||
onCancel={this.onDiscard}
|
|
||||||
readOnly={!this.isEditing}
|
|
||||||
/>
|
|
||||||
<Actions
|
|
||||||
align="center"
|
|
||||||
justify="flex-end"
|
|
||||||
readOnly={!this.isEditing}
|
|
||||||
>
|
|
||||||
{!isNew &&
|
|
||||||
!this.isEditing && <Collaborators document={document} />}
|
|
||||||
<Action>
|
|
||||||
{this.isEditing ? (
|
|
||||||
<SaveAction
|
|
||||||
isSaving={this.isSaving}
|
|
||||||
onClick={this.onSave.bind(this, true)}
|
|
||||||
disabled={
|
|
||||||
!(this.document && this.document.allowSave) ||
|
|
||||||
this.isSaving
|
|
||||||
}
|
|
||||||
isNew={!!isNew}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<a onClick={this.onClickEdit}>Edit</a>
|
|
||||||
)}
|
|
||||||
</Action>
|
|
||||||
{this.isEditing && (
|
|
||||||
<Action>
|
|
||||||
<a onClick={this.onDiscard}>Discard</a>
|
|
||||||
</Action>
|
|
||||||
)}
|
|
||||||
{!this.isEditing && (
|
|
||||||
<Action>
|
|
||||||
<DocumentMenu document={document} />
|
|
||||||
</Action>
|
|
||||||
)}
|
|
||||||
{!this.isEditing && <Separator />}
|
|
||||||
<Action>
|
|
||||||
{!this.isEditing && (
|
|
||||||
<a onClick={this.onClickNew}>
|
|
||||||
<NewDocumentIcon />
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</Action>
|
|
||||||
</Actions>
|
|
||||||
</Flex>
|
|
||||||
)}
|
)}
|
||||||
|
{!isFetching &&
|
||||||
|
document && (
|
||||||
|
<Flex justify="center" auto>
|
||||||
|
<Prompt
|
||||||
|
when={document.hasPendingChanges}
|
||||||
|
message={DISCARD_CHANGES}
|
||||||
|
/>
|
||||||
|
<Editor
|
||||||
|
key={`${document.id}-${document.revision}`}
|
||||||
|
text={document.text}
|
||||||
|
emoji={document.emoji}
|
||||||
|
onImageUploadStart={this.onImageUploadStart}
|
||||||
|
onImageUploadStop={this.onImageUploadStop}
|
||||||
|
onChange={this.onChange}
|
||||||
|
onSave={this.onSave}
|
||||||
|
onCancel={this.onDiscard}
|
||||||
|
readOnly={!this.isEditing}
|
||||||
|
/>
|
||||||
|
<Actions
|
||||||
|
align="center"
|
||||||
|
justify="flex-end"
|
||||||
|
readOnly={!this.isEditing}
|
||||||
|
>
|
||||||
|
{!isNew &&
|
||||||
|
!this.isEditing && <Collaborators document={document} />}
|
||||||
|
<Action>
|
||||||
|
{this.isEditing ? (
|
||||||
|
<SaveAction
|
||||||
|
isSaving={this.isSaving}
|
||||||
|
onClick={this.onSave.bind(this, true)}
|
||||||
|
disabled={
|
||||||
|
!(this.document && this.document.allowSave) ||
|
||||||
|
this.isSaving
|
||||||
|
}
|
||||||
|
isNew={!!isNew}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<a onClick={this.onClickEdit}>Edit</a>
|
||||||
|
)}
|
||||||
|
</Action>
|
||||||
|
{this.isEditing && (
|
||||||
|
<Action>
|
||||||
|
<a onClick={this.onDiscard}>Discard</a>
|
||||||
|
</Action>
|
||||||
|
)}
|
||||||
|
{!this.isEditing && (
|
||||||
|
<Action>
|
||||||
|
<DocumentMenu document={document} />
|
||||||
|
</Action>
|
||||||
|
)}
|
||||||
|
{!this.isEditing && <Separator />}
|
||||||
|
<Action>
|
||||||
|
{!this.isEditing && (
|
||||||
|
<a onClick={this.onClickNew}>
|
||||||
|
<NewDocumentIcon />
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</Action>
|
||||||
|
</Actions>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
|
</ErrorBoundary>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user