(core) Add tip for "Add New" button

Summary:
Adds a new tip for the doc menu's Add New button. The tip is
shown only when the current user is an editor or owner, and
the site is non-empty. The presence of welcome videos or
popups will also cause the tip to not be shown; it will instead
be shown the next time the doc menu is visited.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3757
This commit is contained in:
George Gevoian
2023-01-13 02:39:33 -05:00
parent b7f65ff408
commit db64dfeef0
18 changed files with 134 additions and 46 deletions

View File

@@ -1,3 +1,4 @@
import {BehavioralPromptsManager} from 'app/client/components/BehavioralPromptsManager';
import {get as getBrowserGlobals} from 'app/client/lib/browserGlobals';
import {makeT} from 'app/client/lib/localization';
import {error} from 'app/client/lib/log';
@@ -12,9 +13,8 @@ import {Features, isLegacyPlan, Product} from 'app/common/Features';
import {GristLoadConfig} from 'app/common/gristUrls';
import {FullUser} from 'app/common/LoginSessionAPI';
import {LocalPlugin} from 'app/common/plugin';
import {BehavioralPromptPrefs, DeprecationWarning, DismissedPopup, DismissedReminder,
UserPrefs} from 'app/common/Prefs';
import {isOwner} from 'app/common/roles';
import {DeprecationWarning, DismissedPopup, DismissedReminder, UserPrefs} from 'app/common/Prefs';
import {isOwner, isOwnerOrEditor} from 'app/common/roles';
import {getTagManagerScript} from 'app/common/tagManager';
import {getDefaultThemePrefs, Theme, ThemeAppearance, ThemeColors, ThemePrefs,
ThemePrefsChecker} from 'app/common/ThemePrefs';
@@ -99,19 +99,21 @@ export interface AppModel {
*/
deprecatedWarnings: Observable<DeprecationWarning[]>;
dismissedWelcomePopups: Observable<DismissedReminder[]>;
behavioralPrompts: Observable<BehavioralPromptPrefs>;
pageType: Observable<PageType>;
notifier: Notifier;
planName: string|null;
behavioralPromptsManager: BehavioralPromptsManager;
refreshOrgUsage(): Promise<void>;
showUpgradeModal(): void;
showNewSiteModal(): void;
isBillingManager(): boolean; // If user is a billing manager for this org
isSupport(): boolean; // If user is a Support user
isOwner(): boolean; // If user is an owner of this org
isOwnerOrEditor(): boolean; // If user is an owner or editor of this org
}
export class TopAppModelImpl extends Disposable implements TopAppModel {
@@ -246,8 +248,6 @@ export class AppModelImpl extends Disposable implements AppModel {
{ defaultValue: [] }) as Observable<DeprecationWarning[]>;
public readonly dismissedWelcomePopups = getUserPrefObs(this.userPrefsObs, 'dismissedWelcomePopups',
{ defaultValue: [] }) as Observable<DismissedReminder[]>;
public readonly behavioralPrompts = getUserPrefObs(this.userPrefsObs, 'behavioralPrompts',
{ defaultValue: { dontShowTips: false, dismissedTips: [] } }) as Observable<BehavioralPromptPrefs>;
// Get the current PageType from the URL.
public readonly pageType: Observable<PageType> = Computed.create(this, urlState().state,
@@ -255,6 +255,9 @@ export class AppModelImpl extends Disposable implements AppModel {
public readonly notifier = this.topAppModel.notifier;
public readonly behavioralPromptsManager: BehavioralPromptsManager =
BehavioralPromptsManager.create(this, this);
constructor(
public readonly topAppModel: TopAppModel,
public readonly currentUser: FullUser|null,
@@ -314,6 +317,10 @@ export class AppModelImpl extends Disposable implements AppModel {
return Boolean(this.currentOrg && isOwner(this.currentOrg));
}
public isOwnerOrEditor() {
return Boolean(this.currentOrg && isOwnerOrEditor(this.currentOrg));
}
/**
* Fetch and update the current org's usage.
*/

View File

@@ -75,6 +75,8 @@ export interface HomeModel {
// user isn't allowed to create a doc.
newDocWorkspace: Observable<Workspace|null|"unsaved">;
shouldShowAddNewTip: Observable<boolean>;
createWorkspace(name: string): Promise<void>;
renameWorkspace(id: number, name: string): Promise<void>;
deleteWorkspace(id: number, forever: boolean): Promise<void>;
@@ -154,6 +156,9 @@ export class HomeModelImpl extends Disposable implements HomeModel, ViewSettings
public readonly showIntro = Computed.create(this, this.workspaces, (use, wss) => (
wss.every((ws) => ws.isSupportWorkspace || ws.docs.length === 0)));
public readonly shouldShowAddNewTip = Observable.create(this,
!this._app.behavioralPromptsManager.hasSeenTip('addNew'));
private _userOrgPrefs = Observable.create<UserOrgPrefs|undefined>(this, this._app.currentOrg?.userOrgPrefs);
constructor(private _app: AppModel, clientScope: ClientScope) {