@@ -53,6 +53,7 @@ import { SystemWarning } from "./components/SystemWarning";
5353import { getBrandingConfig } from "./redux/selectors/configSelectors" ;
5454import { buildMaterialPreviewURL } from "./util/materialUtils" ;
5555import GlobalInstances from 'components/GlobalInstances' ;
56+ import { ErrorBoundary , FallbackProps } from 'react-error-boundary' ;
5657
5758const LazyUserAuthComp = React . lazy ( ( ) => import ( "pages/userAuth" ) ) ;
5859const LazyInviteLanding = React . lazy ( ( ) => import ( "pages/common/inviteLanding" ) ) ;
@@ -89,18 +90,34 @@ type AppIndexProps = {
8990} ;
9091
9192class AppIndex extends React . Component < AppIndexProps , any > {
93+ constructor ( props : any ) {
94+ super ( props ) ;
95+ this . state = { error : null } ;
96+ }
9297 componentDidMount ( ) {
9398 this . props . getCurrentUser ( ) ;
9499 }
95100
96101 componentDidUpdate ( prevProps : AppIndexProps ) {
97- if ( prevProps . currentOrgId !== this . props . currentOrgId && this . props . currentOrgId !== '' ) {
102+ if (
103+ prevProps . currentOrgId !== this . props . currentOrgId &&
104+ this . props . currentOrgId !== ''
105+ ) {
98106 this . props . fetchConfig ( this . props . currentOrgId ) ;
99107 }
100108 }
101-
109+ updateError = ( ) => {
110+ this . state . error ( 'known' ) ;
111+ } ;
112+ fallbackRender = ( { error, resetErrorBoundary} : FallbackProps ) => {
113+ return < div role = "alert" >
114+ < h3 > Error Boundary</ h3 >
115+ < p > Something went wrong.</ p >
116+ < button onClick = { resetErrorBoundary } > Reset</ button >
117+ </ div > ;
118+ } ;
102119 render ( ) {
103- const isTemplate = hasQueryParam ( " template" ) ;
120+ const isTemplate = hasQueryParam ( ' template' ) ;
104121 const pathname = history . location . pathname ;
105122
106123 // we check if we are on the public cloud
@@ -122,56 +139,157 @@ class AppIndex extends React.Component<AppIndexProps, any> {
122139 < Helmet >
123140 { < title > { this . props . brandName } </ title > }
124141 { < link rel = "icon" href = { this . props . favicon } /> }
125- < meta name = "description" content = { trans ( "productDesc" ) } />
126- < meta name = "keywords" content = "Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development" />
142+ < meta name = "description" content = { trans ( 'productDesc' ) } />
143+ < meta
144+ name = "keywords"
145+ content = "Lowcoder, Applications, App Builder, Internal Applications, Websites, Dashboards, Data Visualization, Customer Applications, CRM, ERP, eCommerce, VideoMeeting, Rapid Development"
146+ />
127147 < meta name = "author" content = "Lowcoder Software LTD" />
128148 < meta name = "robots" content = "index, follow" />
129149
130-
131- < meta key = "og:title" property = "og:title" content = { this . props . brandName } />
132- < meta key = "og:description" property = "og:description" content = { trans ( "productDesc" ) } />
133- < 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" />
150+ < meta
151+ key = "og:title"
152+ property = "og:title"
153+ content = { this . props . brandName }
154+ />
155+ < meta
156+ key = "og:description"
157+ property = "og:description"
158+ content = { trans ( 'productDesc' ) }
159+ />
160+ < meta
161+ key = "og:image"
162+ property = "og:image"
163+ content = "https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png"
164+ />
134165 < meta key = "og:url" property = "og:url" content = { window . location . href } />
135166 < meta key = "og:type" property = "og:type" content = "website" />
136167
137- < meta key = "twitter:card" name = "twitter:card" content = "summary_large_image" />
138- < meta key = "twitter:title" name = "twitter:title" content = { this . props . brandName } />
139- < meta key = "twitter:description" name = "twitter:description" content = { trans ( "productDesc" ) } />
140- < 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" />
168+ < meta
169+ key = "twitter:card"
170+ name = "twitter:card"
171+ content = "summary_large_image"
172+ />
173+ < meta
174+ key = "twitter:title"
175+ name = "twitter:title"
176+ content = { this . props . brandName }
177+ />
178+ < meta
179+ key = "twitter:description"
180+ name = "twitter:description"
181+ content = { trans ( 'productDesc' ) }
182+ />
183+ < meta
184+ key = "twitter:image"
185+ name = "twitter:image"
186+ content = "https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/App%20Editor%20%7C%20Main%20Screeen%20clean%20v2.4.0.png"
187+ />
141188
142- < meta key = "viewport" name = "viewport" content = "width=device-width, initial-scale=1, shrink-to-fit=no" />
143- < meta key = "mobile-web-app-capable" name = "mobile-web-app-capable" content = "yes" />
189+ < meta
190+ key = "viewport"
191+ name = "viewport"
192+ content = "width=device-width, initial-scale=1, shrink-to-fit=no"
193+ />
194+ < meta
195+ key = "mobile-web-app-capable"
196+ name = "mobile-web-app-capable"
197+ content = "yes"
198+ />
144199 < meta key = "theme-color" name = "theme-color" content = "#b480de" />
145200
146- < meta key = "apple-mobile-web-app-capable" name = "apple-mobile-web-app-capable" content = "yes" />
147- < meta key = "apple-mobile-web-app-status-bar-style" name = "apple-mobile-web-app-status-bar-style" content = "black-translucent" />
148- < meta key = "apple-mobile-web-app-title" name = "apple-mobile-web-app-title" content = { this . props . brandName } />
149- < 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" />
150- < 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" />
201+ < meta
202+ key = "apple-mobile-web-app-capable"
203+ name = "apple-mobile-web-app-capable"
204+ content = "yes"
205+ />
206+ < meta
207+ key = "apple-mobile-web-app-status-bar-style"
208+ name = "apple-mobile-web-app-status-bar-style"
209+ content = "black-translucent"
210+ />
211+ < meta
212+ key = "apple-mobile-web-app-title"
213+ name = "apple-mobile-web-app-title"
214+ content = { this . props . brandName }
215+ />
216+ < link
217+ key = "apple-touch-icon"
218+ rel = "apple-touch-icon"
219+ href = "https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png"
220+ />
221+ < link
222+ key = "apple-touch-startup-image"
223+ rel = "apple-touch-startup-image"
224+ href = "https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20512.png"
225+ />
151226
152- < meta key = "application-name" name = "application-name" content = { this . props . brandName } />
153- < meta key = "msapplication-TileColor" name = "msapplication-TileColor" content = "#b480de" />
154- < meta key = "msapplication-TileImage" name = "msapplication-TileImage" content = "https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png" />
227+ < meta
228+ key = "application-name"
229+ name = "application-name"
230+ content = { this . props . brandName }
231+ />
232+ < meta
233+ key = "msapplication-TileColor"
234+ name = "msapplication-TileColor"
235+ content = "#b480de"
236+ />
237+ < meta
238+ key = "msapplication-TileImage"
239+ name = "msapplication-TileImage"
240+ content = "https://raw.githubusercontent.com/lowcoder-org/lowcoder-media-assets/main/images/Lowcoder%20Logo%20150.png"
241+ />
155242 { /* }<meta key="msapplication-config" name="msapplication-config" content="https://www.yourdomain.com/path/to/browserconfig.xml" />, */ }
156243
157244 < link rel = "canonical" href = { window . location . href } />
158245 { isLowCoderDomain && [
159246 // Adding Support for iframely to be able to embedd the component explorer in the docu
160- < meta key = "iframely:title" property = "iframely:title" content = { this . props . brandName } /> ,
161- < meta key = "iframely:description" property = "iframely:description" content = { trans ( "productDesc" ) } /> ,
247+ < meta
248+ key = "iframely:title"
249+ property = "iframely:title"
250+ content = { this . props . brandName }
251+ /> ,
252+ < meta
253+ key = "iframely:description"
254+ property = "iframely:description"
255+ content = { trans ( 'productDesc' ) }
256+ /> ,
162257
163- < link key = "preconnect-googleapis" rel = "preconnect" href = "https://fonts.googleapis.com" /> ,
164- < link key = "preconnect-gstatic" rel = "preconnect" href = "https://fonts.gstatic.com" crossOrigin = "anonymous" /> ,
165- < 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" /> ,
258+ < link
259+ key = "preconnect-googleapis"
260+ rel = "preconnect"
261+ href = "https://fonts.googleapis.com"
262+ /> ,
263+ < link
264+ key = "preconnect-gstatic"
265+ rel = "preconnect"
266+ href = "https://fonts.gstatic.com"
267+ crossOrigin = "anonymous"
268+ /> ,
269+ < link
270+ key = "font-ubuntu"
271+ href = "https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,700;1,400& display = swap "
272+ rel = "stylesheet"
273+ /> ,
166274 // adding Clearbit Support for Analytics
167- < script key = "clearbit-script" src = "https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js" referrerPolicy = "strict-origin-when-cross-origin" type = "text/javascript" > </ script >
275+ < script
276+ key = "clearbit-script"
277+ src = "https://tag.clearbitscripts.com/v1/pk_dfbc0aeefb28dc63475b67134facf127/tags.js"
278+ referrerPolicy = "strict-origin-when-cross-origin"
279+ type = "text/javascript"
280+ > </ script > ,
168281 ] }
169282 </ Helmet >
170283 < SystemWarning />
171- < Router history = { history } >
172- < Switch >
173-
174- { /*
284+ < ErrorBoundary
285+ fallbackRender = { this . fallbackRender }
286+ onReset = { ( details ) => {
287+ this . state . error ( null ) ;
288+ } }
289+ >
290+ < Router history = { history } >
291+ < Switch >
292+ { /*
175293 // we decided to show the org homepage in a own navigation page
176294 {!this.props.orgDev && !!this.props.defaultHomePage ? (
177295 <Redirect exact from={BASE_URL} to={APPLICATION_VIEW_URL(this.props.defaultHomePage, "view")}
@@ -184,55 +302,92 @@ class AppIndex extends React.Component<AppIndexProps, any> {
184302 />
185303 )} */ }
186304
187- { ! this . props . orgDev ? (
188- < Redirect exact from = { BASE_URL } to = { ORG_HOME_URL } />
189- ) : (
190- < Redirect exact from = { BASE_URL } to = { ALL_APPLICATIONS_URL } />
191- ) }
192-
193- < LazyRoute exact path = { IMPORT_APP_FROM_TEMPLATE_URL } component = { LazyAppFromTemplate } />
194- < LazyRoute fallback = "layout" path = { APP_EDITOR_URL } component = { LazyAppEditor } />
195- < LazyRoute
196- fallback = "layout"
197- path = { [
198- USER_PROFILE_URL ,
199- NEWS_URL ,
200- ORG_HOME_URL ,
201- ALL_APPLICATIONS_URL ,
202- DATASOURCE_CREATE_URL ,
203- DATASOURCE_EDIT_URL ,
204- DATASOURCE_URL ,
205- QUERY_LIBRARY_URL ,
206- FOLDERS_URL ,
207- FOLDER_URL ,
208- TRASH_URL ,
209- SETTING ,
210- MARKETPLACE_URL ,
211- ADMIN_APP_URL ,
212- API_DOCS_URL ,
213- ] }
214- // component={ApplicationListPage}
215- component = { LazyApplicationHome }
216- />
217- < LazyRoute path = { USER_AUTH_URL } component = { LazyUserAuthComp } />
218- < LazyRoute path = { ORG_AUTH_LOGIN_URL } component = { LazyUserAuthComp } />
219- < LazyRoute path = { ORG_AUTH_REGISTER_URL } component = { LazyUserAuthComp } />
220- < LazyRoute path = { ORG_AUTH_FORGOT_PASSWORD_URL } component = { LazyUserAuthComp } />
221- < LazyRoute path = { ORG_AUTH_RESET_PASSWORD_URL } component = { LazyUserAuthComp } />
222- < LazyRoute path = { INVITE_LANDING_URL } component = { LazyInviteLanding } />
223- < LazyRoute path = { `${ COMPONENT_DOC_URL } /:name` } component = { LazyComponentDoc } />
224- < LazyRoute path = { `/playground/:name/:dsl` } component = { LazyComponentPlayground } />
225- < Redirect to = { `${ COMPONENT_DOC_URL } /input` } path = "/components" />
226- { developEnv ( ) && (
227- < >
228- < LazyRoute path = "/debug_comp/:name" component = { LazyDebugComp } />
229- < LazyRoute exact path = "/debug_comp" component = { LazyDebugComp } />
230- < LazyRoute path = "/debug_editor" component = { LazyAppEditor } />
231- < LazyRoute path = "/debug_new" component = { LazyDebugNewComp } />
232- </ >
233- ) }
234- </ Switch >
235- </ Router >
305+ { ! this . props . orgDev ? (
306+ < Redirect exact from = { BASE_URL } to = { ORG_HOME_URL } />
307+ ) : (
308+ < Redirect exact from = { BASE_URL } to = { ALL_APPLICATIONS_URL } />
309+ ) }
310+
311+ < LazyRoute
312+ exact
313+ path = { IMPORT_APP_FROM_TEMPLATE_URL }
314+ component = { LazyAppFromTemplate }
315+ />
316+ < LazyRoute
317+ fallback = "layout"
318+ path = { APP_EDITOR_URL }
319+ component = { LazyAppEditor }
320+ />
321+ < LazyRoute
322+ fallback = "layout"
323+ path = { [
324+ USER_PROFILE_URL ,
325+ NEWS_URL ,
326+ ORG_HOME_URL ,
327+ ALL_APPLICATIONS_URL ,
328+ DATASOURCE_CREATE_URL ,
329+ DATASOURCE_EDIT_URL ,
330+ DATASOURCE_URL ,
331+ QUERY_LIBRARY_URL ,
332+ FOLDERS_URL ,
333+ FOLDER_URL ,
334+ TRASH_URL ,
335+ SETTING ,
336+ MARKETPLACE_URL ,
337+ ADMIN_APP_URL ,
338+ API_DOCS_URL ,
339+ ] }
340+ // component={ApplicationListPage}
341+ component = { LazyApplicationHome }
342+ />
343+ < LazyRoute path = { USER_AUTH_URL } component = { LazyUserAuthComp } />
344+ < LazyRoute
345+ path = { ORG_AUTH_LOGIN_URL }
346+ component = { LazyUserAuthComp }
347+ />
348+ < LazyRoute
349+ path = { ORG_AUTH_REGISTER_URL }
350+ component = { LazyUserAuthComp }
351+ />
352+ < LazyRoute
353+ path = { ORG_AUTH_FORGOT_PASSWORD_URL }
354+ component = { LazyUserAuthComp }
355+ />
356+ < LazyRoute
357+ path = { ORG_AUTH_RESET_PASSWORD_URL }
358+ component = { LazyUserAuthComp }
359+ />
360+ < LazyRoute
361+ path = { INVITE_LANDING_URL }
362+ component = { LazyInviteLanding }
363+ />
364+ < LazyRoute
365+ path = { `${ COMPONENT_DOC_URL } /:name` }
366+ component = { LazyComponentDoc }
367+ />
368+ < LazyRoute
369+ path = { `/playground/:name/:dsl` }
370+ component = { LazyComponentPlayground }
371+ />
372+ < Redirect to = { `${ COMPONENT_DOC_URL } /input` } path = "/components" />
373+ { developEnv ( ) && (
374+ < >
375+ < LazyRoute
376+ path = "/debug_comp/:name"
377+ component = { LazyDebugComp }
378+ />
379+ < LazyRoute
380+ exact
381+ path = "/debug_comp"
382+ component = { LazyDebugComp }
383+ />
384+ < LazyRoute path = "/debug_editor" component = { LazyAppEditor } />
385+ < LazyRoute path = "/debug_new" component = { LazyDebugNewComp } />
386+ </ >
387+ ) }
388+ </ Switch >
389+ </ Router >
390+ </ ErrorBoundary >
236391 </ Wrapper >
237392 ) ;
238393 }
@@ -267,7 +422,7 @@ export function bootstrap() {
267422 const root = createRoot ( container ! ) ;
268423 root . render (
269424 < Provider store = { reduxStore } >
270- < AppIndexWithProps />
425+ < AppIndexWithProps />
271426 </ Provider >
272427 ) ;
273428}
0 commit comments