mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add Support Grist page and nudge
Summary: Adds a new Support Grist page (accessible only in grist-core), containing options to opt in to telemetry and sponsor Grist Labs on GitHub. A nudge is also shown in the doc menu, which can be collapsed or permanently dismissed. Test Plan: Browser and server tests. Reviewers: paulfitz, dsagal Reviewed By: paulfitz Subscribers: jarek, dsagal Differential Revision: https://phab.getgrist.com/D3926
This commit is contained in:
@@ -9,6 +9,7 @@ import {urlState} from 'app/client/models/gristUrlState';
|
||||
import {Notifier} from 'app/client/models/NotifyModel';
|
||||
import {getFlavor, ProductFlavor} from 'app/client/ui/CustomThemes';
|
||||
import {buildNewSiteModal, buildUpgradeModal} from 'app/client/ui/ProductUpgrades';
|
||||
import {SupportGristNudge} from 'app/client/ui/SupportGristNudge';
|
||||
import {attachCssThemeVars, prefersDarkModeObs} from 'app/client/ui2018/cssVars';
|
||||
import {OrgUsageSummary} from 'app/common/DocUsage';
|
||||
import {Features, isLegacyPlan, Product} from 'app/common/Features';
|
||||
@@ -31,7 +32,15 @@ const t = makeT('AppModel');
|
||||
// Reexported for convenience.
|
||||
export {reportError} from 'app/client/models/errors';
|
||||
|
||||
export type PageType = "doc" | "home" | "billing" | "welcome";
|
||||
export type PageType =
|
||||
| "doc"
|
||||
| "home"
|
||||
| "billing"
|
||||
| "welcome"
|
||||
| "account"
|
||||
| "support-grist"
|
||||
| "activation";
|
||||
|
||||
const G = getBrowserGlobals('document', 'window');
|
||||
|
||||
// TopAppModel is the part of the app model that persists across org and user switches.
|
||||
@@ -107,6 +116,8 @@ export interface AppModel {
|
||||
|
||||
behavioralPromptsManager: BehavioralPromptsManager;
|
||||
|
||||
supportGristNudge: SupportGristNudge;
|
||||
|
||||
refreshOrgUsage(): Promise<void>;
|
||||
showUpgradeModal(): void;
|
||||
showNewSiteModal(): void;
|
||||
@@ -253,7 +264,23 @@ export class AppModelImpl extends Disposable implements AppModel {
|
||||
|
||||
// Get the current PageType from the URL.
|
||||
public readonly pageType: Observable<PageType> = Computed.create(this, urlState().state,
|
||||
(use, state) => (state.doc ? "doc" : (state.billing ? "billing" : (state.welcome ? "welcome" : "home"))));
|
||||
(_use, state) => {
|
||||
if (state.doc) {
|
||||
return 'doc';
|
||||
} else if (state.billing) {
|
||||
return 'billing';
|
||||
} else if (state.welcome) {
|
||||
return 'welcome';
|
||||
} else if (state.account) {
|
||||
return 'account';
|
||||
} else if (state.supportGrist) {
|
||||
return 'support-grist';
|
||||
} else if (state.activation) {
|
||||
return 'activation';
|
||||
} else {
|
||||
return 'home';
|
||||
}
|
||||
});
|
||||
|
||||
public readonly needsOrg: Observable<boolean> = Computed.create(
|
||||
this, urlState().state, (use, state) => {
|
||||
@@ -265,6 +292,8 @@ export class AppModelImpl extends Disposable implements AppModel {
|
||||
public readonly behavioralPromptsManager: BehavioralPromptsManager =
|
||||
BehavioralPromptsManager.create(this, this);
|
||||
|
||||
public readonly supportGristNudge: SupportGristNudge = SupportGristNudge.create(this, this);
|
||||
|
||||
constructor(
|
||||
public readonly topAppModel: TopAppModel,
|
||||
public readonly currentUser: FullUser|null,
|
||||
|
||||
32
app/client/models/TelemetryModel.ts
Normal file
32
app/client/models/TelemetryModel.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import {AppModel, getHomeUrl} from 'app/client/models/AppModel';
|
||||
import {TelemetryPrefs} from 'app/common/Install';
|
||||
import {InstallAPI, InstallAPIImpl, TelemetryPrefsWithSources} from 'app/common/InstallAPI';
|
||||
import {bundleChanges, Disposable, Observable} from 'grainjs';
|
||||
|
||||
export interface TelemetryModel {
|
||||
/** Telemetry preferences (e.g. the current telemetry level). */
|
||||
readonly prefs: Observable<TelemetryPrefsWithSources | null>;
|
||||
fetchTelemetryPrefs(): Promise<void>;
|
||||
updateTelemetryPrefs(prefs: Partial<TelemetryPrefs>): Promise<void>;
|
||||
}
|
||||
|
||||
export class TelemetryModelImpl extends Disposable implements TelemetryModel {
|
||||
public readonly prefs: Observable<TelemetryPrefsWithSources | null> = Observable.create(this, null);
|
||||
private readonly _installAPI: InstallAPI = new InstallAPIImpl(getHomeUrl());
|
||||
|
||||
constructor(_appModel: AppModel) {
|
||||
super();
|
||||
}
|
||||
|
||||
public async fetchTelemetryPrefs(): Promise<void> {
|
||||
const prefs = await this._installAPI.getInstallPrefs();
|
||||
bundleChanges(() => {
|
||||
this.prefs.set(prefs.telemetry);
|
||||
});
|
||||
}
|
||||
|
||||
public async updateTelemetryPrefs(prefs: Partial<TelemetryPrefs>): Promise<void> {
|
||||
await this._installAPI.updateInstallPrefs({telemetry: prefs});
|
||||
await this.fetchTelemetryPrefs();
|
||||
}
|
||||
}
|
||||
@@ -156,7 +156,8 @@ export class UrlStateImpl {
|
||||
*/
|
||||
public updateState(prevState: IGristUrlState, newState: IGristUrlState): IGristUrlState {
|
||||
const keepState = (newState.org || newState.ws || newState.homePage || newState.doc || isEmpty(newState) ||
|
||||
newState.account || newState.billing || newState.activation || newState.welcome) ?
|
||||
newState.account || newState.billing || newState.activation || newState.welcome ||
|
||||
newState.supportGrist) ?
|
||||
(prevState.org ? {org: prevState.org} : {}) :
|
||||
prevState;
|
||||
return {...keepState, ...newState};
|
||||
@@ -186,8 +187,11 @@ export class UrlStateImpl {
|
||||
// Reload when moving to/from the Grist sign-up page.
|
||||
const signupReload = [prevState.login, newState.login].includes('signup')
|
||||
&& prevState.login !== newState.login;
|
||||
return Boolean(orgReload || accountReload || billingReload || activationReload
|
||||
|| gristConfig.errPage || docReload || welcomeReload || linkKeysReload || signupReload);
|
||||
// Reload when moving to/from the support Grist page.
|
||||
const supportGristReload = Boolean(prevState.supportGrist) !== Boolean(newState.supportGrist);
|
||||
return Boolean(orgReload || accountReload || billingReload || activationReload ||
|
||||
gristConfig.errPage || docReload || welcomeReload || linkKeysReload || signupReload ||
|
||||
supportGristReload);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user