Skip to content

Commit 0b69057

Browse files
Merge pull request #1011 from MenamAfzal/feature/error-boundary
Feature/error boundary
2 parents 400b932 + 3997d33 commit 0b69057

File tree

4 files changed

+239
-86
lines changed

4 files changed

+239
-86
lines changed

client/packages/lowcoder/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"react-documents": "^1.2.1",
6969
"react-dom": "^18.2.0",
7070
"react-draggable": "^4.4.4",
71+
"react-error-boundary": "^4.0.13",
7172
"react-grid-layout": "^1.3.0",
7273
"react-helmet": "^6.1.0",
7374
"react-joyride": "^2.4.0",

client/packages/lowcoder/src/app.tsx

Lines changed: 216 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,15 @@ class AppIndex extends React.Component<AppIndexProps, any> {
9595
}
9696

9797
componentDidUpdate(prevProps: AppIndexProps) {
98-
if(prevProps.currentOrgId !== this.props.currentOrgId && this.props.currentOrgId !== '') {
98+
if (
99+
prevProps.currentOrgId !== this.props.currentOrgId &&
100+
this.props.currentOrgId !== ''
101+
) {
99102
this.props.fetchConfig(this.props.currentOrgId);
100103
}
101104
}
102-
103105
render() {
104-
const isTemplate = hasQueryParam("template");
106+
const isTemplate = hasQueryParam('template');
105107
const pathname = history.location.pathname;
106108

107109
// we check if we are on the public cloud
@@ -126,56 +128,151 @@ class AppIndex extends React.Component<AppIndexProps, any> {
126128
<Helmet>
127129
{<title>{this.props.brandName}</title>}
128130
{<link rel="icon" href={this.props.favicon} />}
129-
<meta name="description" content={trans("productDesc")} />
130-
<meta name="keywords" content="Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development" />
131+
<meta name="description" content={trans('productDesc')} />
132+
<meta
133+
name="keywords"
134+
content="Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development"
135+
/>
131136
<meta name="author" content="Lowcoder Software LTD" />
132137
<meta name="robots" content="index, follow" />
133138

134-
135-
<meta key="og:title" property="og:title" content={this.props.brandName} />
136-
<meta key="og:description" property="og:description" content={trans("productDesc")} />
137-
<meta key="og:image" property="og:image" content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png" />
139+
<meta
140+
key="og:title"
141+
property="og:title"
142+
content={this.props.brandName}
143+
/>
144+
<meta
145+
key="og:description"
146+
property="og:description"
147+
content={trans('productDesc')}
148+
/>
149+
<meta
150+
key="og:image"
151+
property="og:image"
152+
content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png"
153+
/>
138154
<meta key="og:url" property="og:url" content={window.location.href} />
139155
<meta key="og:type" property="og:type" content="website" />
140156

141-
<meta key="twitter:card" name="twitter:card" content="summary_large_image" />
142-
<meta key="twitter:title" name="twitter:title" content={this.props.brandName} />
143-
<meta key="twitter:description" name="twitter:description" content={trans("productDesc")} />
144-
<meta key="twitter:image" name="twitter:image" content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png" />
157+
<meta
158+
key="twitter:card"
159+
name="twitter:card"
160+
content="summary_large_image"
161+
/>
162+
<meta
163+
key="twitter:title"
164+
name="twitter:title"
165+
content={this.props.brandName}
166+
/>
167+
<meta
168+
key="twitter:description"
169+
name="twitter:description"
170+
content={trans('productDesc')}
171+
/>
172+
<meta
173+
key="twitter:image"
174+
name="twitter:image"
175+
content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png"
176+
/>
145177

146-
<meta key="viewport" name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
147-
<meta key="mobile-web-app-capable" name="mobile-web-app-capable" content="yes" />
178+
<meta
179+
key="viewport"
180+
name="viewport"
181+
content="width=device-width, initial-scale=1, shrink-to-fit=no"
182+
/>
183+
<meta
184+
key="mobile-web-app-capable"
185+
name="mobile-web-app-capable"
186+
content="yes"
187+
/>
148188
<meta key="theme-color" name="theme-color" content="#b480de" />
149189

150-
<meta key="apple-mobile-web-app-capable" name="apple-mobile-web-app-capable" content="yes" />
151-
<meta key="apple-mobile-web-app-status-bar-style" name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
152-
<meta key="apple-mobile-web-app-title" name="apple-mobile-web-app-title" content={this.props.brandName} />
153-
<link key="apple-touch-icon" rel="apple-touch-icon" href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png" />
154-
<link key="apple-touch-startup-image" rel="apple-touch-startup-image" href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png" />
190+
<meta
191+
key="apple-mobile-web-app-capable"
192+
name="apple-mobile-web-app-capable"
193+
content="yes"
194+
/>
195+
<meta
196+
key="apple-mobile-web-app-status-bar-style"
197+
name="apple-mobile-web-app-status-bar-style"
198+
content="black-translucent"
199+
/>
200+
<meta
201+
key="apple-mobile-web-app-title"
202+
name="apple-mobile-web-app-title"
203+
content={this.props.brandName}
204+
/>
205+
<link
206+
key="apple-touch-icon"
207+
rel="apple-touch-icon"
208+
href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png"
209+
/>
210+
<link
211+
key="apple-touch-startup-image"
212+
rel="apple-touch-startup-image"
213+
href="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png"
214+
/>
155215

156-
<meta key="application-name" name="application-name" content={this.props.brandName} />
157-
<meta key="msapplication-TileColor" name="msapplication-TileColor" content="#b480de" />
158-
<meta key="msapplication-TileImage" name="msapplication-TileImage" content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png" />
216+
<meta
217+
key="application-name"
218+
name="application-name"
219+
content={this.props.brandName}
220+
/>
221+
<meta
222+
key="msapplication-TileColor"
223+
name="msapplication-TileColor"
224+
content="#b480de"
225+
/>
226+
<meta
227+
key="msapplication-TileImage"
228+
name="msapplication-TileImage"
229+
content="https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png"
230+
/>
159231
{/* }<meta key="msapplication-config" name="msapplication-config" content="https://www.yourdomain.com/path/to/browserconfig.xml" />, */}
160232

161233
<link rel="canonical" href={window.location.href} />
162234
{isLowCoderDomain && [
163235
// Adding Support for iframely to be able to embedd the component explorer in the docu
164-
<meta key="iframely:title" property="iframely:title" content={this.props.brandName} />,
165-
<meta key="iframely:description" property="iframely:description" content={trans("productDesc")} />,
236+
<meta
237+
key="iframely:title"
238+
property="iframely:title"
239+
content={this.props.brandName}
240+
/>,
241+
<meta
242+
key="iframely:description"
243+
property="iframely:description"
244+
content={trans('productDesc')}
245+
/>,
166246

167-
<link key="preconnect-googleapis" rel="preconnect" href="https://fonts.googleapis.com" />,
168-
<link key="preconnect-gstatic" rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />,
169-
<link key="font-ubuntu" href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,700;1,400&display=swap" rel="stylesheet" />,
247+
<link
248+
key="preconnect-googleapis"
249+
rel="preconnect"
250+
href="https://fonts.googleapis.com"
251+
/>,
252+
<link
253+
key="preconnect-gstatic"
254+
rel="preconnect"
255+
href="https://fonts.gstatic.com"
256+
crossOrigin="anonymous"
257+
/>,
258+
<link
259+
key="font-ubuntu"
260+
href="https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,700;1,400&display=swap"
261+
rel="stylesheet"
262+
/>,
170263
// adding Clearbit Support for Analytics
171-
<script key="clearbit-script" src="https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js" referrerPolicy="strict-origin-when-cross-origin" type="text/javascript"></script>
264+
<script
265+
key="clearbit-script"
266+
src="https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js"
267+
referrerPolicy="strict-origin-when-cross-origin"
268+
type="text/javascript"
269+
></script>,
172270
]}
173271
</Helmet>
174272
<SystemWarning />
175-
<Router history={history}>
176-
<Switch>
177-
178-
{/*
273+
<Router history={history}>
274+
<Switch>
275+
{/*
179276
// we decided to show the org homepage in a own navigation page
180277
{!this.props.orgDev && !!this.props.defaultHomePage ? (
181278
<Redirect exact from={BASE_URL} to={APPLICATION_VIEW_URL(this.props.defaultHomePage, "view")}
@@ -188,55 +285,91 @@ class AppIndex extends React.Component<AppIndexProps, any> {
188285
/>
189286
)} */}
190287

191-
{!this.props.orgDev ? (
192-
<Redirect exact from={BASE_URL} to={ORG_HOME_URL} />
193-
) : (
194-
<Redirect exact from={BASE_URL} to={ALL_APPLICATIONS_URL} />
195-
)}
196-
197-
<LazyRoute exact path={IMPORT_APP_FROM_TEMPLATE_URL} component={LazyAppFromTemplate} />
198-
<LazyRoute fallback="layout" path={APP_EDITOR_URL} component={LazyAppEditor} />
199-
<LazyRoute
200-
fallback="layout"
201-
path={[
202-
USER_PROFILE_URL,
203-
NEWS_URL,
204-
ORG_HOME_URL,
205-
ALL_APPLICATIONS_URL,
206-
DATASOURCE_CREATE_URL,
207-
DATASOURCE_EDIT_URL,
208-
DATASOURCE_URL,
209-
QUERY_LIBRARY_URL,
210-
FOLDERS_URL,
211-
FOLDER_URL,
212-
TRASH_URL,
213-
SETTING,
214-
MARKETPLACE_URL,
215-
ADMIN_APP_URL,
216-
API_DOCS_URL,
217-
]}
218-
// component={ApplicationListPage}
219-
component={LazyApplicationHome}
220-
/>
221-
<LazyRoute path={USER_AUTH_URL} component={LazyUserAuthComp} />
222-
<LazyRoute path={ORG_AUTH_LOGIN_URL} component={LazyUserAuthComp} />
223-
<LazyRoute path={ORG_AUTH_REGISTER_URL} component={LazyUserAuthComp} />
224-
<LazyRoute path={ORG_AUTH_FORGOT_PASSWORD_URL} component={LazyUserAuthComp} />
225-
<LazyRoute path={ORG_AUTH_RESET_PASSWORD_URL} component={LazyUserAuthComp} />
226-
<LazyRoute path={INVITE_LANDING_URL} component={LazyInviteLanding} />
227-
<LazyRoute path={`${COMPONENT_DOC_URL}/:name`} component={LazyComponentDoc} />
228-
<LazyRoute path={`/playground/:name/:dsl`} component={LazyComponentPlayground} />
229-
<Redirect to={`${COMPONENT_DOC_URL}/input`} path="/components" />
230-
{developEnv() && (
231-
<>
232-
<LazyRoute path="/debug_comp/:name" component={LazyDebugComp} />
233-
<LazyRoute exact path="/debug_comp" component={LazyDebugComp} />
234-
<LazyRoute path="/debug_editor" component={LazyAppEditor} />
235-
<LazyRoute path="/debug_new" component={LazyDebugNewComp} />
236-
</>
237-
)}
238-
</Switch>
239-
</Router>
288+
{!this.props.orgDev ? (
289+
<Redirect exact from={BASE_URL} to={ORG_HOME_URL} />
290+
) : (
291+
<Redirect exact from={BASE_URL} to={ALL_APPLICATIONS_URL} />
292+
)}
293+
294+
<LazyRoute
295+
exact
296+
path={IMPORT_APP_FROM_TEMPLATE_URL}
297+
component={LazyAppFromTemplate}
298+
/>
299+
<LazyRoute
300+
fallback="layout"
301+
path={APP_EDITOR_URL}
302+
component={LazyAppEditor}
303+
/>
304+
<LazyRoute
305+
fallback="layout"
306+
path={[
307+
USER_PROFILE_URL,
308+
NEWS_URL,
309+
ORG_HOME_URL,
310+
ALL_APPLICATIONS_URL,
311+
DATASOURCE_CREATE_URL,
312+
DATASOURCE_EDIT_URL,
313+
DATASOURCE_URL,
314+
QUERY_LIBRARY_URL,
315+
FOLDERS_URL,
316+
FOLDER_URL,
317+
TRASH_URL,
318+
SETTING,
319+
MARKETPLACE_URL,
320+
ADMIN_APP_URL,
321+
API_DOCS_URL,
322+
]}
323+
// component={ApplicationListPage}
324+
component={LazyApplicationHome}
325+
/>
326+
<LazyRoute path={USER_AUTH_URL} component={LazyUserAuthComp} />
327+
<LazyRoute
328+
path={ORG_AUTH_LOGIN_URL}
329+
component={LazyUserAuthComp}
330+
/>
331+
<LazyRoute
332+
path={ORG_AUTH_REGISTER_URL}
333+
component={LazyUserAuthComp}
334+
/>
335+
<LazyRoute
336+
path={ORG_AUTH_FORGOT_PASSWORD_URL}
337+
component={LazyUserAuthComp}
338+
/>
339+
<LazyRoute
340+
path={ORG_AUTH_RESET_PASSWORD_URL}
341+
component={LazyUserAuthComp}
342+
/>
343+
<LazyRoute
344+
path={INVITE_LANDING_URL}
345+
component={LazyInviteLanding}
346+
/>
347+
<LazyRoute
348+
path={`${COMPONENT_DOC_URL}/:name`}
349+
component={LazyComponentDoc}
350+
/>
351+
<LazyRoute
352+
path={`/playground/:name/:dsl`}
353+
component={LazyComponentPlayground}
354+
/>
355+
<Redirect to={`${COMPONENT_DOC_URL}/input`} path="/components" />
356+
{developEnv() && (
357+
<>
358+
<LazyRoute
359+
path="/debug_comp/:name"
360+
component={LazyDebugComp}
361+
/>
362+
<LazyRoute
363+
exact
364+
path="/debug_comp"
365+
component={LazyDebugComp}
366+
/>
367+
<LazyRoute path="/debug_editor" component={LazyAppEditor} />
368+
<LazyRoute path="/debug_new" component={LazyDebugNewComp} />
369+
</>
370+
)}
371+
</Switch>
372+
</Router>
240373
</Wrapper>
241374
);
242375
}
@@ -271,7 +404,7 @@ export function bootstrap() {
271404
const root = createRoot(container!);
272405
root.render(
273406
<Provider store={reduxStore}>
274-
<AppIndexWithProps />
407+
<AppIndexWithProps />
275408
</Provider>
276409
);
277410
}

client/packages/lowcoder/src/pages/editor/AppEditor.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ import { fetchFolderElements } from "redux/reduxActions/folderActions";
2626
import { registryDataSourcePlugin } from "constants/queryConstants";
2727
import { DatasourceApi } from "api/datasourceApi";
2828
import { useRootCompInstance } from "./useRootCompInstance";
29-
import ErrorBoundary from "antd/es/alert/ErrorBoundary";
3029
import EditorSkeletonView from "./editorSkeletonView";
30+
import {ErrorBoundary, FallbackProps} from 'react-error-boundary';
31+
import { ALL_APPLICATIONS_URL } from "@lowcoder-ee/constants/routesURL";
32+
import history from "util/history";
3133

3234
const AppSnapshot = lazy(() => {
3335
return import("pages/editor/appSnapshot")
@@ -133,9 +135,14 @@ export default function AppEditor() {
133135
})
134136
);
135137
}, [viewMode, applicationId, dispatch]);
136-
138+
const fallbackUI = (
139+
<div style={{display:'flex', height:'100%', width:'100%', alignItems:'center',justifyContent:'center', gap:'8px',marginTop:'10px'}}>
140+
<p style={{margin:0}}>Something went wrong while displaying this webpage</p>
141+
<button onClick={() => history.push(ALL_APPLICATIONS_URL)} style={{background: '#4965f2',border: '1px solid #4965f2', color: '#ffffff',borderRadius:'6px'}}>Go to Apps</button>
142+
</div>
143+
);
137144
return (
138-
<ErrorBoundary>
145+
<ErrorBoundary fallback={fallbackUI}>
139146
{showAppSnapshot ? (
140147
<Suspense fallback={<EditorSkeletonView />}>
141148
<AppSnapshot

0 commit comments

Comments
 (0)