2 changed files with 118 additions and 0 deletions
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
import React from 'react'; |
||||
import { ComponentStory, ComponentMeta } from '@storybook/react'; |
||||
import { ComponentError } from './ComponentError'; |
||||
|
||||
export default { |
||||
title: 'owncast/Components/Component Error', |
||||
component: ComponentError, |
||||
parameters: { |
||||
docs: { |
||||
description: { |
||||
component: `This component is used to display a user-facing fatal error within a component's error boundary. It enables a link to file a bug report. It should have enough detail to help the developers fix the issue, but not be so unapproachable it makes the user scared away.`, |
||||
}, |
||||
}, |
||||
}, |
||||
} as ComponentMeta<typeof ComponentError>; |
||||
|
||||
const Template: ComponentStory<typeof ComponentError> = args => <ComponentError {...args} />; |
||||
|
||||
export const DefaultMessage = Template.bind({}); |
||||
DefaultMessage.args = { |
||||
componentName: 'Test Component', |
||||
}; |
||||
|
||||
export const Error1 = Template.bind({}); |
||||
Error1.args = { message: 'This is a test error message.', componentName: 'Test Component' }; |
||||
|
||||
export const WithDetails = Template.bind({}); |
||||
WithDetails.args = { |
||||
message: 'This is a test error message.', |
||||
componentName: 'Test Component', |
||||
details: 'Here are some additional details about the error.', |
||||
}; |
||||
|
||||
export const CanRetry = Template.bind({}); |
||||
CanRetry.args = { |
||||
message: 'This is a test error message.', |
||||
componentName: 'Test Component', |
||||
details: 'Here are some additional details about the error.', |
||||
retryFunction: () => { |
||||
console.log('retrying'); |
||||
}, |
||||
}; |
@ -0,0 +1,76 @@
@@ -0,0 +1,76 @@
|
||||
import { Alert, Button } from 'antd'; |
||||
import { FC } from 'react'; |
||||
|
||||
export type ComponentErrorProps = { |
||||
message?: string; |
||||
componentName: string; |
||||
details?: string; |
||||
retryFunction?: () => void; |
||||
}; |
||||
|
||||
const openBugReport = () => { |
||||
window.open( |
||||
'https://github.com/owncast/owncast/issues/new?assignees=&labels=&template=bug-report-feature-request.yml', |
||||
'_blank', |
||||
); |
||||
}; |
||||
|
||||
const ErrorContent = ({ |
||||
message, |
||||
componentName, |
||||
details, |
||||
canRetry, |
||||
}: { |
||||
message: string; |
||||
componentName: string; |
||||
details: string; |
||||
canRetry: boolean; |
||||
}) => ( |
||||
<div> |
||||
<p> |
||||
There was an unexpected error. It would be appreciated if you would report this so it can be |
||||
fixed in the future. |
||||
</p> |
||||
{!!canRetry && ( |
||||
<p> |
||||
You may optionally retry, however functionality, if there are errors, may be unexpected. |
||||
</p> |
||||
)} |
||||
<code> |
||||
<div>{message && `Error: ${message}`}</div> |
||||
<div>Component: {componentName}</div> |
||||
<div>{details && details}</div> |
||||
</code> |
||||
</div> |
||||
); |
||||
|
||||
export const ComponentError: FC<ComponentErrorProps> = ({ |
||||
message, |
||||
componentName, |
||||
details, |
||||
retryFunction, |
||||
}: ComponentErrorProps) => ( |
||||
<Alert |
||||
message="Error" |
||||
showIcon |
||||
description=<ErrorContent |
||||
message={message} |
||||
details={details} |
||||
componentName={componentName} |
||||
canRetry={!!retryFunction} |
||||
/> |
||||
type="error" |
||||
action={ |
||||
<> |
||||
{retryFunction && ( |
||||
<Button ghost size="small" onClick={retryFunction}> |
||||
Retry |
||||
</Button> |
||||
)} |
||||
<Button ghost size="small" danger onClick={openBugReport}> |
||||
Report Error |
||||
</Button> |
||||
</> |
||||
} |
||||
/> |
||||
); |
Loading…
Reference in new issue