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);
|
||||
|
||||
// 在引入 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;
|
||||
},
|
||||
});
|
||||
|
@ -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",
|
||||
|
@ -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>
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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",
|
||||
};
|
||||
|
@ -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': '単一または複数のファイルをアップロードできます。ファイルサイズは',
|
||||
|
@ -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',
|
||||
|
@ -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': "Поддержка одиночной или массовой загрузки, размер файла не должен превышать",
|
||||
|
@ -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",
|
||||
|
@ -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': '支持单个或批量上传,文件大小不能超过',
|
||||
|
@ -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 { 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>
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user