chore: optimize the white screen problem (#1639)

* chore: add react-error-boundary

* fix: optimize the white screen problem

* fix: fix translation
This commit is contained in:
被雨水过滤的空气-Rairn 2023-04-24 16:40:02 +08:00 committed by GitHub
parent 5fa490e9a1
commit cd596925ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 140 additions and 50 deletions

View File

@ -25,7 +25,10 @@ export default defineConfig({
resolveNocobasePackagesAlias(memo);
// 在引入 mermaid 之后,运行 yarn dev 的时候会报错,添加下面的代码可以解决。
memo.module.rule('js-in-node_modules').test(/(htmlparser2|(.*mermaid.*\.js$))/).include.clear();
memo.module
.rule('js-in-node_modules')
.test(/(react-error-boundary.*\.js|htmlparser2|(.*mermaid.*\.js$))/)
.include.clear();
return memo;
},
});

View File

@ -33,6 +33,7 @@
"react-beautiful-dnd": "^13.1.0",
"react-big-calendar": "^0.38.7",
"react-drag-listview": "^0.1.9",
"react-error-boundary": "^4.0.3",
"react-helmet": "^6.1.0",
"react-hotkeys-hook": "^3.4.7",
"react-i18next": "^11.15.1",

View File

@ -1,6 +1,7 @@
import { Spin } from 'antd';
import { i18n as i18next } from 'i18next';
import React, { useEffect, useState } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { I18nextProvider } from 'react-i18next';
import { Link, NavLink } from 'react-router-dom';
import { ACLProvider } from '../acl';
@ -17,14 +18,15 @@ import {
RemoteRouteSwitchProvider,
RouteSchemaComponent,
RouteSwitch,
useRoutes
useRoutes,
} from '../route-switch';
import {
AntdSchemaComponentProvider,
DesignableSwitch,
MenuItemInitializers,
SchemaComponentProvider
SchemaComponentProvider,
} from '../schema-component';
import { ErrorFallback } from '../schema-component/antd/error-fallback';
import { SchemaInitializerProvider } from '../schema-initializer';
import { BlockTemplateDetails, BlockTemplatePage } from '../schema-templates';
import { SystemSettingsProvider } from '../system-settings';
@ -131,6 +133,10 @@ export class Application {
this.plugins.push(plugin);
}
handleErrors(error: any) {
console.error(error);
}
render() {
return (props: any) => {
const { plugins = [], dynamicImport } = this.options;
@ -152,7 +158,11 @@ export class Application {
if (loading) {
return <Spin />;
}
return <App providers={this.providers} />;
return (
<ErrorBoundary FallbackComponent={ErrorFallback} onError={this.handleErrors}>
<App providers={this.providers} />
</ErrorBoundary>
);
};
}
}

View File

@ -685,5 +685,9 @@ export default {
"UpdatedAt": "Recording a row's last updated user",
"Column width": "Column width",
"Sortable": "Sortable",
"Enable link": "Enable link"
"Enable link": "Enable link",
"This is likely a NocoBase internals bug. Please open an issue at <1>here</1>": "This is likely a NocoBase internals bug. Please open an issue at <1>here</1>",
"Render Failed": "Render Failed",
"Feedback": "Feedback",
"Try again": "Try again",
};

View File

@ -592,7 +592,11 @@ export default {
"Format": "フォーマット",
"Error message": "エラーメッセージ",
"Record picker": "レコードピッカー",
"Search and select collection": "Search and select collection",
"Search and select collection": "コレクションを検索して選択",
"This is likely a NocoBase internals bug. Please open an issue at <1>here</1>": "これはNocoBaseの内部バグの可能性があります。 <1>こちら</1>で問題を報告してください",
"Render Failed": "レンダリングに失敗しました",
"Feedback": "フィードバック",
"Try again": "再試行",
'Click or drag file to this area to upload': 'クリックまたはドラッグしてファイルをアップロード',
'Support for a single or bulk upload, file size should not exceed': '単一または複数のファイルをアップロードできます。ファイルサイズは',

View File

@ -646,6 +646,10 @@ export default {
"Column width": "Largura da coluna",
"Sortable": "Classificável",
"Enable link": "Habilitar link",
"This is likely a NocoBase internals bug. Please open an issue at <1>here</1>": "Isso provavelmente é um bug interno do NocoBase. Por favor, abra um problema em <1>aqui</1>",
"Render Failed": "Falha na renderização",
"Feedback": "Feedback",
"Try again": "Tente novamente",
'Click or drag file to this area to upload': 'Clique ou arraste o arquivo para esta área para fazer o upload',
'Support for a single or bulk upload, file size should not exceed': 'Suporte para upload único ou em massa, o tamanho do arquivo não deve exceder',

View File

@ -499,7 +499,11 @@ export default {
"Print": "Печать",
'Single select and radio fields can be used as the grouping field': 'Одиночное поле выбора и радиополя могут использоваться в качестве поля группировки',
'Sign up successfully, and automatically jump to the sign in page': 'Зарегистрируйтесь успешно и автоматически перейдете на страницу входа',
"Search and select collection": "Search and select collection",
"Search and select collection": "Поиск и выбор коллекции",
"This is likely a NocoBase internals bug. Please open an issue at <1>here</1>": "Это, вероятно, ошибка внутреннего устройства NocoBase. Пожалуйста, откройте проблему <1>здесь</1>",
"Render Failed": "Ошибка рендеринга",
"Feedback": "Обратная связь",
"Try again": "Попробуйте еще раз",
'Click or drag file to this area to upload': "Нажмите или перетащите файл в эту область, чтобы загрузить",
'Support for a single or bulk upload, file size should not exceed': "Поддержка одиночной или массовой загрузки, размер файла не должен превышать",

View File

@ -498,7 +498,11 @@ export default {
"Print": "Yazdır",
'Single select and radio fields can be used as the grouping field': 'Gruplama alanı olarak tek seçim ve radyo alanları kullanılabilir',
'Sign up successfully, and automatically jump to the sign in page': 'Başarılı bir şekilde kaydolun ve otomatik olarak oturum açma sayfasına geçin',
"Search and select collection": "Search and select collection",
"Search and select collection": "Koleksiyon ara ve seç",
"This is likely a NocoBase internals bug. Please open an issue at <1>here</1>": "Bu, NocoBase iç işlevleri hatası olabilir. Lütfen <1>burada</1> bir sorun açın",
"Render Failed": "Oluşturma başarısız",
"Feedback": "Geri bildirim",
"Try again": "Tekrar dene",
'Click or drag file to this area to upload': "Dosyayı yüklemek için buraya tıklayın veya sürükleyin",
'Support for a single or bulk upload, file size should not exceed': "Tek veya toplu yükleme destekler, dosya boyutu aşmamalıdır",

View File

@ -742,6 +742,10 @@ export default {
'Theme': '主题',
'Default theme': '默认主题',
'Compact theme': '紧凑主题',
"This is likely a NocoBase internals bug. Please open an issue at <1>here</1>": "这可能是 NocoBase 内部的问题,你可以在<1>这里</1>将该错误反馈给我们,我们会尽快修复",
"Render Failed": "渲染失败",
"Feedback": "反馈问题",
"Try again": "重试一下",
'Click or drag file to this area to upload': '点击或拖拽文件到此区域上传',
'Support for a single or bulk upload, file size should not exceed': '支持单个或批量上传,文件大小不能超过',

View File

@ -0,0 +1,43 @@
import { Button, Result, Typography } from 'antd';
import React from 'react';
import { useErrorBoundary } from 'react-error-boundary';
import { Trans, useTranslation } from 'react-i18next';
const { Paragraph, Text, Link } = Typography;
export const ErrorFallback = ({ error }) => {
const { resetBoundary } = useErrorBoundary();
const { t } = useTranslation();
const subTitle = (
<Trans>
{'This is likely a NocoBase internals bug. Please open an issue at '}
<Link href="https://github.com/nocobase/nocobase/issues">here</Link>
</Trans>
);
return (
<div style={{ backgroundColor: 'white' }}>
<Result
style={{ maxWidth: '60vw', margin: 'auto' }}
status="error"
title={t('Render Failed')}
subTitle={subTitle}
extra={[
<Button type="primary" key="feedback">
<a href="https://github.com/nocobase/nocobase/issues">{t('Feedback')}</a>
</Button>,
<Button key="try" onClick={resetBoundary}>
{t('Try again')}
</Button>,
]}
>
<Paragraph copyable>
<Text type="danger" style={{ whiteSpace: 'pre-line', textAlign: 'center' }}>
{error.stack}
</Text>
</Paragraph>
</Result>
</div>
);
};

View File

@ -0,0 +1 @@
export * from './ErrorFallback';

View File

@ -1,12 +1,13 @@
import { PlusOutlined } from '@ant-design/icons';
import { css } from '@emotion/css';
import { FormDialog, FormLayout } from '@formily/antd';
import { Schema, SchemaOptionsContext, useField, useFieldSchema } from '@formily/react';
import { Button, PageHeader as AntdPageHeader, Spin, Tabs } from 'antd';
import { Schema, SchemaOptionsContext, useFieldSchema } from '@formily/react';
import { PageHeader as AntdPageHeader, Button, Spin, Tabs } from 'antd';
import classNames from 'classnames';
import React, { useContext, useEffect, useState } from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { useTranslation } from 'react-i18next';
import { useHistory, useLocation } from 'react-router-dom';
import { useLocation } from 'react-router-dom';
import { useDocumentTitle } from '../../../document-title';
import { FilterBlockProvider } from '../../../filter-provider/FilterProvider';
import { Icon } from '../../../icon';
@ -14,6 +15,7 @@ import { DndContext } from '../../common';
import { SortableItem } from '../../common/sortable-item';
import { SchemaComponent, SchemaComponentOptions } from '../../core';
import { useCompile, useDesignable } from '../../hooks';
import { ErrorFallback } from '../error-fallback';
import FixedBlock from './FixedBlock';
import { PageDesigner, PageTabDesigner } from './PageTabDesigner';
@ -142,6 +144,10 @@ export const Page = (props) => {
const [height, setHeight] = useState(0);
const handleErrors = (error) => {
console.error(error);
};
return (
<FilterBlockProvider>
<div className={pageDesignerCss}>
@ -259,42 +265,44 @@ export const Page = (props) => {
/>
)}
</div>
<div className="nb-page-wrapper" style={{ margin: 'var(--nb-spacing)', flex: 1 }}>
{loading ? (
<Spin />
) : !disablePageHeader && enablePageTabs ? (
fieldSchema.mapProperties((schema) => {
if (schema.name !== activeKey) return null;
return (
<FixedBlock
key={schema.name}
height={
// header 46 margin --nb-spacing * 2
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
}
>
<SchemaComponent
schema={
new Schema({
properties: {
[schema.name]: schema,
},
})
<div className="nb-page-wrapper" style={{ margin: 'var(--nb-spacing)', flex: 1, }}>
<ErrorBoundary FallbackComponent={ErrorFallback} onError={handleErrors}>
{loading ? (
<Spin />
) : !disablePageHeader && enablePageTabs ? (
fieldSchema.mapProperties((schema) => {
if (schema.name !== activeKey) return null;
return (
<FixedBlock
key={schema.name}
height={
// header 46 margin --nb-spacing * 2
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
}
/>
</FixedBlock>
);
})
) : (
<FixedBlock
height={
// header 46 margin --nb-spacing * 2
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
}
>
<div className={pageWithFixedBlockCss}>{props.children}</div>
</FixedBlock>
)}
>
<SchemaComponent
schema={
new Schema({
properties: {
[schema.name]: schema,
},
})
}
/>
</FixedBlock>
);
})
) : (
<FixedBlock
height={
// header 46 margin --nb-spacing * 2
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
}
>
<div className={pageWithFixedBlockCss}>{props.children}</div>
</FixedBlock>
)}
</ErrorBoundary>
</div>
</div>
</FilterBlockProvider>

View File

@ -20905,10 +20905,10 @@ react-drag-listview@^0.1.9:
babel-runtime "^6.26.0"
prop-types "^15.5.8"
react-error-boundary@^3.1.4:
version "3.1.4"
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
react-error-boundary@^4.0.3:
version "4.0.3"
resolved "https://registry.npmmirror.com/react-error-boundary/-/react-error-boundary-4.0.3.tgz#f811497c06d53ea1206817ee82c6e5c6a27becd9"
integrity sha512-IzNKP/ViHWp2QRDgsDMirEcf0XLsLueN6Wgzm1TVwgbAH+paX8Z42VyKvZcFFRHgd+rPK2P4TLrOrHC/dommew==
dependencies:
"@babel/runtime" "^7.12.5"