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:
parent
5fa490e9a1
commit
cd596925ee
@ -25,7 +25,10 @@ export default defineConfig({
|
|||||||
resolveNocobasePackagesAlias(memo);
|
resolveNocobasePackagesAlias(memo);
|
||||||
|
|
||||||
// 在引入 mermaid 之后,运行 yarn dev 的时候会报错,添加下面的代码可以解决。
|
// 在引入 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;
|
return memo;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"react-beautiful-dnd": "^13.1.0",
|
"react-beautiful-dnd": "^13.1.0",
|
||||||
"react-big-calendar": "^0.38.7",
|
"react-big-calendar": "^0.38.7",
|
||||||
"react-drag-listview": "^0.1.9",
|
"react-drag-listview": "^0.1.9",
|
||||||
|
"react-error-boundary": "^4.0.3",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-hotkeys-hook": "^3.4.7",
|
"react-hotkeys-hook": "^3.4.7",
|
||||||
"react-i18next": "^11.15.1",
|
"react-i18next": "^11.15.1",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import { i18n as i18next } from 'i18next';
|
import { i18n as i18next } from 'i18next';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import { I18nextProvider } from 'react-i18next';
|
import { I18nextProvider } from 'react-i18next';
|
||||||
import { Link, NavLink } from 'react-router-dom';
|
import { Link, NavLink } from 'react-router-dom';
|
||||||
import { ACLProvider } from '../acl';
|
import { ACLProvider } from '../acl';
|
||||||
@ -17,14 +18,15 @@ import {
|
|||||||
RemoteRouteSwitchProvider,
|
RemoteRouteSwitchProvider,
|
||||||
RouteSchemaComponent,
|
RouteSchemaComponent,
|
||||||
RouteSwitch,
|
RouteSwitch,
|
||||||
useRoutes
|
useRoutes,
|
||||||
} from '../route-switch';
|
} from '../route-switch';
|
||||||
import {
|
import {
|
||||||
AntdSchemaComponentProvider,
|
AntdSchemaComponentProvider,
|
||||||
DesignableSwitch,
|
DesignableSwitch,
|
||||||
MenuItemInitializers,
|
MenuItemInitializers,
|
||||||
SchemaComponentProvider
|
SchemaComponentProvider,
|
||||||
} from '../schema-component';
|
} from '../schema-component';
|
||||||
|
import { ErrorFallback } from '../schema-component/antd/error-fallback';
|
||||||
import { SchemaInitializerProvider } from '../schema-initializer';
|
import { SchemaInitializerProvider } from '../schema-initializer';
|
||||||
import { BlockTemplateDetails, BlockTemplatePage } from '../schema-templates';
|
import { BlockTemplateDetails, BlockTemplatePage } from '../schema-templates';
|
||||||
import { SystemSettingsProvider } from '../system-settings';
|
import { SystemSettingsProvider } from '../system-settings';
|
||||||
@ -131,6 +133,10 @@ export class Application {
|
|||||||
this.plugins.push(plugin);
|
this.plugins.push(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleErrors(error: any) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (props: any) => {
|
return (props: any) => {
|
||||||
const { plugins = [], dynamicImport } = this.options;
|
const { plugins = [], dynamicImport } = this.options;
|
||||||
@ -152,7 +158,11 @@ export class Application {
|
|||||||
if (loading) {
|
if (loading) {
|
||||||
return <Spin />;
|
return <Spin />;
|
||||||
}
|
}
|
||||||
return <App providers={this.providers} />;
|
return (
|
||||||
|
<ErrorBoundary FallbackComponent={ErrorFallback} onError={this.handleErrors}>
|
||||||
|
<App providers={this.providers} />
|
||||||
|
</ErrorBoundary>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,5 +685,9 @@ export default {
|
|||||||
"UpdatedAt": "Recording a row's last updated user",
|
"UpdatedAt": "Recording a row's last updated user",
|
||||||
"Column width": "Column width",
|
"Column width": "Column width",
|
||||||
"Sortable": "Sortable",
|
"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",
|
||||||
};
|
};
|
||||||
|
@ -592,7 +592,11 @@ export default {
|
|||||||
"Format": "フォーマット",
|
"Format": "フォーマット",
|
||||||
"Error message": "エラーメッセージ",
|
"Error message": "エラーメッセージ",
|
||||||
"Record picker": "レコードピッカー",
|
"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': 'クリックまたはドラッグしてファイルをアップロード',
|
'Click or drag file to this area to upload': 'クリックまたはドラッグしてファイルをアップロード',
|
||||||
'Support for a single or bulk upload, file size should not exceed': '単一または複数のファイルをアップロードできます。ファイルサイズは',
|
'Support for a single or bulk upload, file size should not exceed': '単一または複数のファイルをアップロードできます。ファイルサイズは',
|
||||||
|
@ -646,6 +646,10 @@ export default {
|
|||||||
"Column width": "Largura da coluna",
|
"Column width": "Largura da coluna",
|
||||||
"Sortable": "Classificável",
|
"Sortable": "Classificável",
|
||||||
"Enable link": "Habilitar link",
|
"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',
|
'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',
|
'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',
|
||||||
|
@ -499,7 +499,11 @@ export default {
|
|||||||
"Print": "Печать",
|
"Print": "Печать",
|
||||||
'Single select and radio fields can be used as the grouping field': 'Одиночное поле выбора и радиополя могут использоваться в качестве поля группировки',
|
'Single select and radio fields can be used as the grouping field': 'Одиночное поле выбора и радиополя могут использоваться в качестве поля группировки',
|
||||||
'Sign up successfully, and automatically jump to the sign in page': 'Зарегистрируйтесь успешно и автоматически перейдете на страницу входа',
|
'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': "Нажмите или перетащите файл в эту область, чтобы загрузить",
|
'Click or drag file to this area to upload': "Нажмите или перетащите файл в эту область, чтобы загрузить",
|
||||||
'Support for a single or bulk upload, file size should not exceed': "Поддержка одиночной или массовой загрузки, размер файла не должен превышать",
|
'Support for a single or bulk upload, file size should not exceed': "Поддержка одиночной или массовой загрузки, размер файла не должен превышать",
|
||||||
|
@ -498,7 +498,11 @@ export default {
|
|||||||
"Print": "Yazdır",
|
"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',
|
'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',
|
'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",
|
'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",
|
'Support for a single or bulk upload, file size should not exceed': "Tek veya toplu yükleme destekler, dosya boyutu aşmamalıdır",
|
||||||
|
@ -742,6 +742,10 @@ export default {
|
|||||||
'Theme': '主题',
|
'Theme': '主题',
|
||||||
'Default theme': '默认主题',
|
'Default theme': '默认主题',
|
||||||
'Compact 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': '点击或拖拽文件到此区域上传',
|
'Click or drag file to this area to upload': '点击或拖拽文件到此区域上传',
|
||||||
'Support for a single or bulk upload, file size should not exceed': '支持单个或批量上传,文件大小不能超过',
|
'Support for a single or bulk upload, file size should not exceed': '支持单个或批量上传,文件大小不能超过',
|
||||||
|
@ -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>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1 @@
|
|||||||
|
export * from './ErrorFallback';
|
@ -1,12 +1,13 @@
|
|||||||
import { PlusOutlined } from '@ant-design/icons';
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { FormDialog, FormLayout } from '@formily/antd';
|
import { FormDialog, FormLayout } from '@formily/antd';
|
||||||
import { Schema, SchemaOptionsContext, useField, useFieldSchema } from '@formily/react';
|
import { Schema, SchemaOptionsContext, useFieldSchema } from '@formily/react';
|
||||||
import { Button, PageHeader as AntdPageHeader, Spin, Tabs } from 'antd';
|
import { PageHeader as AntdPageHeader, Button, Spin, Tabs } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useHistory, useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useDocumentTitle } from '../../../document-title';
|
import { useDocumentTitle } from '../../../document-title';
|
||||||
import { FilterBlockProvider } from '../../../filter-provider/FilterProvider';
|
import { FilterBlockProvider } from '../../../filter-provider/FilterProvider';
|
||||||
import { Icon } from '../../../icon';
|
import { Icon } from '../../../icon';
|
||||||
@ -14,6 +15,7 @@ import { DndContext } from '../../common';
|
|||||||
import { SortableItem } from '../../common/sortable-item';
|
import { SortableItem } from '../../common/sortable-item';
|
||||||
import { SchemaComponent, SchemaComponentOptions } from '../../core';
|
import { SchemaComponent, SchemaComponentOptions } from '../../core';
|
||||||
import { useCompile, useDesignable } from '../../hooks';
|
import { useCompile, useDesignable } from '../../hooks';
|
||||||
|
import { ErrorFallback } from '../error-fallback';
|
||||||
import FixedBlock from './FixedBlock';
|
import FixedBlock from './FixedBlock';
|
||||||
import { PageDesigner, PageTabDesigner } from './PageTabDesigner';
|
import { PageDesigner, PageTabDesigner } from './PageTabDesigner';
|
||||||
|
|
||||||
@ -142,6 +144,10 @@ export const Page = (props) => {
|
|||||||
|
|
||||||
const [height, setHeight] = useState(0);
|
const [height, setHeight] = useState(0);
|
||||||
|
|
||||||
|
const handleErrors = (error) => {
|
||||||
|
console.error(error);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FilterBlockProvider>
|
<FilterBlockProvider>
|
||||||
<div className={pageDesignerCss}>
|
<div className={pageDesignerCss}>
|
||||||
@ -259,42 +265,44 @@ export const Page = (props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="nb-page-wrapper" style={{ margin: 'var(--nb-spacing)', flex: 1 }}>
|
<div className="nb-page-wrapper" style={{ margin: 'var(--nb-spacing)', flex: 1, }}>
|
||||||
{loading ? (
|
<ErrorBoundary FallbackComponent={ErrorFallback} onError={handleErrors}>
|
||||||
<Spin />
|
{loading ? (
|
||||||
) : !disablePageHeader && enablePageTabs ? (
|
<Spin />
|
||||||
fieldSchema.mapProperties((schema) => {
|
) : !disablePageHeader && enablePageTabs ? (
|
||||||
if (schema.name !== activeKey) return null;
|
fieldSchema.mapProperties((schema) => {
|
||||||
return (
|
if (schema.name !== activeKey) return null;
|
||||||
<FixedBlock
|
return (
|
||||||
key={schema.name}
|
<FixedBlock
|
||||||
height={
|
key={schema.name}
|
||||||
// header 46 margin --nb-spacing * 2
|
height={
|
||||||
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
|
// header 46 margin --nb-spacing * 2
|
||||||
}
|
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
|
||||||
>
|
|
||||||
<SchemaComponent
|
|
||||||
schema={
|
|
||||||
new Schema({
|
|
||||||
properties: {
|
|
||||||
[schema.name]: schema,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
/>
|
>
|
||||||
</FixedBlock>
|
<SchemaComponent
|
||||||
);
|
schema={
|
||||||
})
|
new Schema({
|
||||||
) : (
|
properties: {
|
||||||
<FixedBlock
|
[schema.name]: schema,
|
||||||
height={
|
},
|
||||||
// header 46 margin --nb-spacing * 2
|
})
|
||||||
`calc(${height}px + 46px + var(--nb-spacing) * 2)`
|
}
|
||||||
}
|
/>
|
||||||
>
|
</FixedBlock>
|
||||||
<div className={pageWithFixedBlockCss}>{props.children}</div>
|
);
|
||||||
</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>
|
||||||
</div>
|
</div>
|
||||||
</FilterBlockProvider>
|
</FilterBlockProvider>
|
||||||
|
@ -20905,10 +20905,10 @@ react-drag-listview@^0.1.9:
|
|||||||
babel-runtime "^6.26.0"
|
babel-runtime "^6.26.0"
|
||||||
prop-types "^15.5.8"
|
prop-types "^15.5.8"
|
||||||
|
|
||||||
react-error-boundary@^3.1.4:
|
react-error-boundary@^4.0.3:
|
||||||
version "3.1.4"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
|
resolved "https://registry.npmmirror.com/react-error-boundary/-/react-error-boundary-4.0.3.tgz#f811497c06d53ea1206817ee82c6e5c6a27becd9"
|
||||||
integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
|
integrity sha512-IzNKP/ViHWp2QRDgsDMirEcf0XLsLueN6Wgzm1TVwgbAH+paX8Z42VyKvZcFFRHgd+rPK2P4TLrOrHC/dommew==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.12.5"
|
"@babel/runtime" "^7.12.5"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user