default error page
This commit is contained in:
parent
9bcfa4f39b
commit
9abea28b6e
6 changed files with 97 additions and 72 deletions
|
@ -1,5 +1,22 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ResetButtons from './reset-buttons'
|
import ResetButtons from './reset-buttons'
|
||||||
|
import {EventGroup} from 'shared/components/workbench/events'
|
||||||
|
import DefaultErrorView from './view';
|
||||||
|
|
||||||
|
const ErrorView = (props) => {
|
||||||
|
if (props.children) return props.children
|
||||||
|
|
||||||
|
const inspectChildrenProps = {
|
||||||
|
type: 'error',
|
||||||
|
events: [props.error],
|
||||||
|
units: props.gist?.units
|
||||||
|
}
|
||||||
|
const inspectChildren = (<EventGroup {...inspectChildrenProps}></EventGroup>)
|
||||||
|
return (props.children || (<DefaultErrorView inspectChildren={inspectChildren}>
|
||||||
|
<h4>If you think your last action caused this error, you can: </h4>
|
||||||
|
<ResetButtons undoGist={props.undoGist} resetGist={props.resetGist} />
|
||||||
|
</DefaultErrorView>))
|
||||||
|
}
|
||||||
|
|
||||||
class ErrorBoundary extends React.Component {
|
class ErrorBoundary extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -26,17 +43,13 @@ class ErrorBoundary extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
if (this.state.hasError) {
|
if (this.state.hasError) {
|
||||||
// You can render any custom fallback UI
|
// You can render any custom fallback UI
|
||||||
return (<div>
|
return <ErrorView {...this.props} error={this.state.error}>{this.errorView}</ErrorView>
|
||||||
{this.props.errorView || (<h1>Something went wrong.</h1>)}
|
|
||||||
<ResetButtons undoGist={this.props.undoGist} resetGist={this.props.resetGist} />
|
|
||||||
</div>)
|
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return this.props.children;
|
return this.props.children;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return this.props.errorView || (<h1>Something went wrong.</h1>);
|
return <ErrorView {...this.props} error={e}>{this.errorView}</ErrorView>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,8 @@ import { useTranslation } from 'next-i18next'
|
||||||
export default function ({resetGist, undoGist}) {
|
export default function ({resetGist, undoGist}) {
|
||||||
const {t} = useTranslation(['app'])
|
const {t} = useTranslation(['app'])
|
||||||
|
|
||||||
return (<>
|
return (<div className="flex flex-row gap-4 my-4">
|
||||||
<button className="btn btn-primary" onClick={undoGist}>{t('undo')}</button>
|
<button className="btn btn-primary" onClick={undoGist}>{t('undo')}</button>
|
||||||
<button className="btn btn-primary" onClick={resetGist}>{t('reset_all')}</button>
|
<button className="btn btn-primary" onClick={resetGist}>{t('reset_all')}</button>
|
||||||
</>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
59
sites/shared/components/error/view.js
Normal file
59
sites/shared/components/error/view.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import Robot from 'shared/components/robot/index.js'
|
||||||
|
import Popout from 'shared/components/popout.js'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import { useState } from 'react'
|
||||||
|
|
||||||
|
const Error = ({ children, inspectChildren}) => {
|
||||||
|
|
||||||
|
const { t } = useTranslation(['errors'])
|
||||||
|
const [share, setShare] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-4xl m-auto">
|
||||||
|
<Popout warning>
|
||||||
|
<div className="flex flex-row justify-between">
|
||||||
|
<div>
|
||||||
|
<h3>{t('errors:something')}</h3>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
<Robot pose='fail' />
|
||||||
|
</div>
|
||||||
|
</Popout>
|
||||||
|
<Popout tip>
|
||||||
|
<h3>Would you like to report this problem?</h3>
|
||||||
|
<p>
|
||||||
|
You can help us <strong>make FreeSewing better by reporting this problem</strong>.
|
||||||
|
</p>
|
||||||
|
<p>If you choose to report this:</p>
|
||||||
|
<ul className="list-disc list-inside ml-4 text-xl">
|
||||||
|
<li>
|
||||||
|
We will compile a <strong>crash report</strong> that contains everything needed <strong>to recreate this problem</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
We will include <strong>personal data</strong> such as your <strong>username</strong>, <strong>
|
||||||
|
email address</strong> and <strong>measurements</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
We will share this report and the data in it with <a className="text-primary font-bold"
|
||||||
|
href="https://github.com/orgs/freesewing/teams/bughunters">FreeSewing's bughunters team</a> who will investigate the problem on your behalf
|
||||||
|
</li>
|
||||||
|
<li>Your personal data will <strong>not be shared publicly</strong></li>
|
||||||
|
</ul>
|
||||||
|
<div className="form-control">
|
||||||
|
<label className="cursor-pointer flex flex-row gap-4 my-4">
|
||||||
|
<input type="checkbox" checked={share} className="checkbox checkbox-primary" onChange={() => setShare(!share)}/>
|
||||||
|
<span className="label-text text-xl">I agree to the use of my personal data for the purposes outlined above</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<button disabled={!share} className="btn btn-primary">Report this</button>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you prefer not to share any info, or want to investigate the problem yourself, you can do so:
|
||||||
|
</p>
|
||||||
|
{inspectChildren}
|
||||||
|
</Popout>
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Error
|
|
@ -2,68 +2,21 @@ import { useState } from 'react'
|
||||||
import Robot from 'shared/components/robot/index.js'
|
import Robot from 'shared/components/robot/index.js'
|
||||||
import Popout from 'shared/components/popout.js'
|
import Popout from 'shared/components/popout.js'
|
||||||
import { useTranslation } from 'next-i18next'
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import DefaultErrorView from 'shared/components/error/view';
|
||||||
|
|
||||||
const Error = ({ draft, patternProps, error, updateGist }) => {
|
const Error = ({ draft, patternProps, error, updateGist }) => {
|
||||||
|
const inspectChildren = (<ul className="list-disc list-inside ml-4 text-xl">
|
||||||
|
<li>
|
||||||
|
Check the <button className="btn-link" onClick={() => updateGist(['_state', 'view'], 'events')}>
|
||||||
|
<strong>{patternProps?.events?.error?.length} errors</strong> and <strong>
|
||||||
|
{patternProps?.events?.warning?.length} warnings</strong></button>
|
||||||
|
</li>
|
||||||
|
<li>Check the partially rendered pattern below to see which areas are problematic</li>
|
||||||
|
</ul>)
|
||||||
|
|
||||||
const { t } = useTranslation(['errors'])
|
return (<DefaultErrorView inspectChildren={inspectChildren}>
|
||||||
const [share, setShare] = useState(false)
|
<p>Don't be alarmed, but we ran into some trouble while drafting this pattern.</p>
|
||||||
|
</DefaultErrorView>)
|
||||||
return (
|
|
||||||
<div className="max-w-4xl m-auto">
|
|
||||||
<Popout warning>
|
|
||||||
<div className="flex flex-row justify-between">
|
|
||||||
<div>
|
|
||||||
<h3>{t('errors:something')}</h3>
|
|
||||||
<p>Don't be alarmed, but we ran into some trouble while drafting this pattern.</p>
|
|
||||||
</div>
|
|
||||||
<Robot pose='fail' />
|
|
||||||
</div>
|
|
||||||
</Popout>
|
|
||||||
<Popout tip>
|
|
||||||
<h3>Would you like to report this problem?</h3>
|
|
||||||
<p>
|
|
||||||
You can help us <strong>make FreeSewing better by reporting this problem</strong>.
|
|
||||||
</p>
|
|
||||||
<p>If you choose to report this:</p>
|
|
||||||
<ul className="list-disc list-inside ml-4 text-xl">
|
|
||||||
<li>
|
|
||||||
We will compile a <strong>crash report</strong> that contains everything needed <strong>to recreate this problem</strong>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
We will include <strong>personal data</strong> such as your <strong>username</strong>, <strong>
|
|
||||||
email address</strong> and <strong>measurements</strong>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
We will share this report and the data in it with <a className="text-primary font-bold"
|
|
||||||
href="https://github.com/orgs/freesewing/teams/bughunters">FreeSewing's bughunters team</a> who will investigate the problem on your behalf
|
|
||||||
</li>
|
|
||||||
<li>Your personal data will <strong>not be shared publicly</strong></li>
|
|
||||||
</ul>
|
|
||||||
<div className="form-control">
|
|
||||||
<label className="cursor-pointer flex flex-row gap-4 my-4">
|
|
||||||
<input type="checkbox" checked={share} className="checkbox checkbox-primary" onChange={() => setShare(!share)}/>
|
|
||||||
<span className="label-text text-xl">I agree to the use of my personal data for the purposes outlined above</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
<button disabled={!share} className="btn btn-primary">Report this</button>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If you prefer not to share any info, or want to investigate the problem yourself, you can do so:
|
|
||||||
</p>
|
|
||||||
<ul className="list-disc list-inside ml-4 text-xl">
|
|
||||||
<li>
|
|
||||||
Check the <button className="btn-link" onClick={() => updateGist(['_state', 'view'], 'events')}>
|
|
||||||
<strong>{patternProps?.events?.error?.length} errors</strong> and <strong>
|
|
||||||
{patternProps?.events?.warning?.length} warnings</strong></button>
|
|
||||||
</li>
|
|
||||||
<li>Check the partially rendered pattern below to see which areas are problematic</li>
|
|
||||||
</ul>
|
|
||||||
</Popout>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default Error
|
export default Error
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Markdown from 'react-markdown'
|
import Markdown from 'react-markdown'
|
||||||
import { formatMm } from 'shared/utils'
|
import { formatMm } from 'shared/utils'
|
||||||
|
|
||||||
const Error = ({err}) => (
|
export const Error = ({err}) => (
|
||||||
<code className="block">
|
<pre>
|
||||||
{err.toString()}
|
{err.stack.split(/\n/g).slice(0, 5).map((l, i) => (<code key={`error-${i}`} className={'block whitespace-pre-wrap' + (i > 0 ? ' break-all' : '')}>{l}</code>))}
|
||||||
</code>
|
</pre>
|
||||||
)
|
)
|
||||||
|
|
||||||
// Markdown wrapper to suppress creation of P tags
|
// Markdown wrapper to suppress creation of P tags
|
||||||
|
|
|
@ -36,7 +36,7 @@ const Draft = props => {
|
||||||
for (const [pname, part] of Object.entries(patternProps.parts)) {
|
for (const [pname, part] of Object.entries(patternProps.parts)) {
|
||||||
let partLayout = newLayout.parts[pname];
|
let partLayout = newLayout.parts[pname];
|
||||||
// Pages part does not have its topLeft and bottomRight set by core since it's added post-draft
|
// Pages part does not have its topLeft and bottomRight set by core since it's added post-draft
|
||||||
if (partLayout.tl) {
|
if (partLayout?.tl) {
|
||||||
// set the pattern extremes
|
// set the pattern extremes
|
||||||
topLeft.x = Math.min(topLeft.x, partLayout.tl.x)
|
topLeft.x = Math.min(topLeft.x, partLayout.tl.x)
|
||||||
topLeft.y = Math.min(topLeft.y, partLayout.tl.y)
|
topLeft.y = Math.min(topLeft.y, partLayout.tl.y)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue