Files
owncast/web/components/ui/ComponentError/ComponentError.tsx
Copilot 29b5100114 Create custom Translation component for better i18n handling (#4431)
* Initial plan

* Implement Translation component with Storybook stories

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Add Jest test for Translation component and demonstrate ?lang=de functionality

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Javascript formatting autofixes

* Create centralized type-safe localization system

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Add @testing-library/react to Translation component tests

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Fix code formatting errors with prettier and eslint

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Revert "Fix code formatting errors with prettier and eslint"

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* fix(js): eslinter errors

* fix(js): unused code warnings

* fix(js): fix additional warnings

* Update Emoji admin page to use new Translation component

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Organize localization keys by logical sections (Frontend, Admin, Common, Testing)

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Organize localization keys by TypeScript namespaces

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* Javascript formatting autofixes

* feat(js): add support for default translated text

* chore: add default lang translations on commit

* fix(js): unused code warnings

* Update OfflineBanner component to use new Translation component

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* fix(js): fix localization extraction job

* chore(js): remove ts-node cli

* fix(css): fix css warning

* feat(js): add some additional translation strings via component

* chore: update extracted translations

* test: add tests for Translation component defaultText and fallback behavior

Co-authored-by: gabek <414923+gabek@users.noreply.github.com>

* chore: update extracted translations

* Javascript formatting autofixes

* chore: call out new Translation component

* fix: linter warning

* chore: updated instructions

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gabek <414923+gabek@users.noreply.github.com>
Co-authored-by: Owncast <owncast@owncast.online>
Co-authored-by: Gabe Kangas <gabek@real-ity.com>
2025-07-13 02:21:46 -07:00

85 lines
1.9 KiB
TypeScript

import { Alert, Button } from 'antd';
import { FC } from 'react';
import Translation from '../Translation/Translation';
import { Localization } from '../../../types/localization';
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 might not work as expected.</p>
)}
<code>
<div>
{message && (
<Translation
translationKey={Localization.Frontend.componentError}
defaultText="Error: {{message}}"
vars={{ 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>
</>
}
/>
);