make a /boot/GRIST_BOOT_KEY page for diagnosing configuration problems (#850)

This is a start at a page for diagnosing problems while setting up Grist. Starting to add some diagnostics based on feedback in github issues. We should make Grist installation easier! But when there is a problem it should be easier to diagnose than it is now, and this may help. The page is ugly and doesn't have many diagnostics yet, but we can iterate.

Visit `/boot` on a Grist server for tips on how to use this feature.
This commit is contained in:
Paul Fitzpatrick
2024-03-04 16:22:47 -05:00
committed by GitHub
parent 2693e01d08
commit 95b734149e
12 changed files with 618 additions and 8 deletions

View File

@@ -146,6 +146,11 @@ export interface AppModel {
switchUser(user: FullUser, org?: string): Promise<void>;
}
export interface TopAppModelOptions {
/** Defaults to true. */
useApi?: boolean;
}
export class TopAppModelImpl extends Disposable implements TopAppModel {
public readonly isSingleOrg: boolean;
public readonly productFlavor: ProductFlavor;
@@ -163,14 +168,16 @@ export class TopAppModelImpl extends Disposable implements TopAppModel {
// up new widgets - that seems ok.
private readonly _widgets: AsyncCreate<ICustomWidget[]>;
constructor(window: {gristConfig?: GristLoadConfig}, public readonly api: UserAPI = newUserAPIImpl()) {
constructor(window: {gristConfig?: GristLoadConfig},
public readonly api: UserAPI = newUserAPIImpl(),
public readonly options: TopAppModelOptions = {}) {
super();
setErrorNotifier(this.notifier);
this.isSingleOrg = Boolean(window.gristConfig && window.gristConfig.singleOrg);
this.productFlavor = getFlavor(window.gristConfig && window.gristConfig.org);
this._gristConfig = window.gristConfig;
this._widgets = new AsyncCreate<ICustomWidget[]>(async () => {
const widgets = await this.api.getWidgets();
const widgets = this.options.useApi === false ? [] : await this.api.getWidgets();
this.customWidgets.set(widgets);
return widgets;
});
@@ -180,7 +187,9 @@ export class TopAppModelImpl extends Disposable implements TopAppModel {
this.autoDispose(subscribe(this.currentSubdomain, (use) => this.initialize()));
this.plugins = this._gristConfig?.plugins || [];
this.fetchUsersAndOrgs().catch(reportError);
if (this.options.useApi !== false) {
this.fetchUsersAndOrgs().catch(reportError);
}
}
public initialize(): void {
@@ -237,6 +246,10 @@ export class TopAppModelImpl extends Disposable implements TopAppModel {
private async _doInitialize() {
this.appObs.set(null);
if (this.options.useApi === false) {
AppModelImpl.create(this.appObs, this, null, null, {error: 'no-api', status: 500});
return;
}
try {
const {user, org, orgError} = await this.api.getSessionActive();
if (this.isDisposed()) { return; }