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:
Ilya Kreymer 2025-03-01 14:02:37 -08:00 committed by GitHub
parent 53b531ce3e
commit 64621ba6c0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 17 additions and 19 deletions

View File

@ -63,7 +63,7 @@ describe("browsertrix-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(
Promise.resolve({
headers: { Authorization: "_fake_headers_" },
@ -76,7 +76,7 @@ describe("browsertrix-app", () => {
const el = await fixture<App>(html` <browsertrix-app></browsertrix-app>`);
await el.updateComplete;
expect(el.shadowRoot?.childElementCount).to.equal(0);
expect(el.shadowRoot?.childElementCount).to.not.equal(0);
});
it("renders org when authenticated", async () => {

View File

@ -101,9 +101,6 @@ export class App extends BtrixElement {
authService = new AuthService();
@state()
private translationReady = false;
@provide({ context: viewStateContext })
@state()
private viewState!: ViewState;
@ -187,6 +184,7 @@ export class App extends BtrixElement {
}
firstUpdated() {
void this.initTranslation();
this.trackPageView();
}
@ -194,9 +192,6 @@ export class App extends BtrixElement {
if (changedProperties.has("settings")) {
AppStateService.updateSettings(this.settings || null);
if (this.settings && !changedProperties.get("settings")) {
void this.initTranslation();
}
}
if (changedProperties.has("viewState")) {
this.handleViewStateChange(
@ -234,7 +229,6 @@ export class App extends BtrixElement {
await localize.initLanguage();
// 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
this.translationReady = true;
}
getLocationPathname() {
@ -351,8 +345,6 @@ export class App extends BtrixElement {
}
render() {
if (!this.translationReady) return;
return html`
<div class="min-w-screen flex min-h-screen flex-col">
${this.renderSuperadminBanner()} ${this.renderNavBar()}

View File

@ -365,15 +365,21 @@ export class LogInPage extends BtrixElement {
return;
}
const resp = await fetch("/api/settings");
if (resp.status === 200) {
this.formStateService.send("BACKEND_INITIALIZED");
} else {
this.formStateService.send("BACKEND_NOT_INITIALIZED");
this.timerId = window.setTimeout(() => {
void this.checkBackendInitialized();
}, 5000);
try {
const resp = await fetch("/api/settings");
if (resp.status === 200) {
this.formStateService.send("BACKEND_INITIALIZED");
return;
}
} catch (e) {
// 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) {