frontend: fix rendering when backend not available yet (#2448)
- don't wait for languages to be ready to render UI, as this can result in empty page if backend can not be reached. - catch if /api/settings returns an invalid response to show 'backend initializing' message - will support initContainers where backend may return 5xx error while backend is initializing, via #2449 Note: this results in locale picker showing all available locales if backend is not available, not just filtered ones, but I think that's a reasonable trade-off.
This commit is contained in:
		
							parent
							
								
									53b531ce3e
								
							
						
					
					
						commit
						64621ba6c0
					
				| @ -63,7 +63,7 @@ describe("browsertrix-app", () => { | |||||||
|     expect(el).instanceOf(App); |     expect(el).instanceOf(App); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it("blocks render if settings aren't defined", async () => { |   it("don't block render if settings aren't defined", async () => { | ||||||
|     stub(AuthService, "initSessionStorage").returns( |     stub(AuthService, "initSessionStorage").returns( | ||||||
|       Promise.resolve({ |       Promise.resolve({ | ||||||
|         headers: { Authorization: "_fake_headers_" }, |         headers: { Authorization: "_fake_headers_" }, | ||||||
| @ -76,7 +76,7 @@ describe("browsertrix-app", () => { | |||||||
|     const el = await fixture<App>(html` <browsertrix-app></browsertrix-app>`); |     const el = await fixture<App>(html` <browsertrix-app></browsertrix-app>`); | ||||||
|     await el.updateComplete; |     await el.updateComplete; | ||||||
| 
 | 
 | ||||||
|     expect(el.shadowRoot?.childElementCount).to.equal(0); |     expect(el.shadowRoot?.childElementCount).to.not.equal(0); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   it("renders org when authenticated", async () => { |   it("renders org when authenticated", async () => { | ||||||
|  | |||||||
| @ -101,9 +101,6 @@ export class App extends BtrixElement { | |||||||
| 
 | 
 | ||||||
|   authService = new AuthService(); |   authService = new AuthService(); | ||||||
| 
 | 
 | ||||||
|   @state() |  | ||||||
|   private translationReady = false; |  | ||||||
| 
 |  | ||||||
|   @provide({ context: viewStateContext }) |   @provide({ context: viewStateContext }) | ||||||
|   @state() |   @state() | ||||||
|   private viewState!: ViewState; |   private viewState!: ViewState; | ||||||
| @ -187,6 +184,7 @@ export class App extends BtrixElement { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   firstUpdated() { |   firstUpdated() { | ||||||
|  |     void this.initTranslation(); | ||||||
|     this.trackPageView(); |     this.trackPageView(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -194,9 +192,6 @@ export class App extends BtrixElement { | |||||||
|     if (changedProperties.has("settings")) { |     if (changedProperties.has("settings")) { | ||||||
|       AppStateService.updateSettings(this.settings || null); |       AppStateService.updateSettings(this.settings || null); | ||||||
| 
 | 
 | ||||||
|       if (this.settings && !changedProperties.get("settings")) { |  | ||||||
|         void this.initTranslation(); |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|     if (changedProperties.has("viewState")) { |     if (changedProperties.has("viewState")) { | ||||||
|       this.handleViewStateChange( |       this.handleViewStateChange( | ||||||
| @ -234,7 +229,6 @@ export class App extends BtrixElement { | |||||||
|     await localize.initLanguage(); |     await localize.initLanguage(); | ||||||
|     // TODO We might want to set this in a lit-localize-status event listener
 |     // TODO We might want to set this in a lit-localize-status event listener
 | ||||||
|     // see https://lit.dev/docs/localization/runtime-mode/#example-of-using-the-status-event
 |     // see https://lit.dev/docs/localization/runtime-mode/#example-of-using-the-status-event
 | ||||||
|     this.translationReady = true; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getLocationPathname() { |   getLocationPathname() { | ||||||
| @ -351,8 +345,6 @@ export class App extends BtrixElement { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   render() { |   render() { | ||||||
|     if (!this.translationReady) return; |  | ||||||
| 
 |  | ||||||
|     return html` |     return html` | ||||||
|       <div class="min-w-screen flex min-h-screen flex-col"> |       <div class="min-w-screen flex min-h-screen flex-col"> | ||||||
|         ${this.renderSuperadminBanner()} ${this.renderNavBar()} |         ${this.renderSuperadminBanner()} ${this.renderNavBar()} | ||||||
|  | |||||||
| @ -365,15 +365,21 @@ export class LogInPage extends BtrixElement { | |||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const resp = await fetch("/api/settings"); |     try { | ||||||
|     if (resp.status === 200) { |       const resp = await fetch("/api/settings"); | ||||||
|       this.formStateService.send("BACKEND_INITIALIZED"); |       if (resp.status === 200) { | ||||||
|     } else { |         this.formStateService.send("BACKEND_INITIALIZED"); | ||||||
|       this.formStateService.send("BACKEND_NOT_INITIALIZED"); |         return; | ||||||
|       this.timerId = window.setTimeout(() => { |       } | ||||||
|         void this.checkBackendInitialized(); |     } catch (e) { | ||||||
|       }, 5000); |       // assume backend not available if exception thrown
 | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // mark as not initialized
 | ||||||
|  |     this.formStateService.send("BACKEND_NOT_INITIALIZED"); | ||||||
|  |     this.timerId = window.setTimeout(() => { | ||||||
|  |       void this.checkBackendInitialized(); | ||||||
|  |     }, 5000); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async onSubmitLogIn(event: SubmitEvent) { |   async onSubmitLogIn(event: SubmitEvent) { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user