mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Update onboarding flow
Summary: A new onboarding page is now shown to all new users visiting the doc menu for the first time. Tutorial cards on the doc menu have been replaced with a new version that tracks completion progress, alongside a new card that opens the orientation video. Test Plan: Browser tests. Reviewers: jarek Reviewed By: jarek Differential Revision: https://phab.getgrist.com/D4296
This commit is contained in:
@@ -1124,7 +1124,7 @@ export class DocWorkerApi {
|
||||
const scope = getDocScope(req);
|
||||
const tutorialTrunkId = options.sourceDocId;
|
||||
await this._dbManager.connection.transaction(async (manager) => {
|
||||
// Fetch the tutorial trunk doc so we can replace the tutorial doc's name.
|
||||
// Fetch the tutorial trunk so we can replace the tutorial fork's name.
|
||||
const tutorialTrunk = await this._dbManager.getDoc({...scope, urlId: tutorialTrunkId}, manager);
|
||||
await this._dbManager.updateDocument(
|
||||
scope,
|
||||
@@ -1132,9 +1132,8 @@ export class DocWorkerApi {
|
||||
name: tutorialTrunk.name,
|
||||
options: {
|
||||
tutorial: {
|
||||
...tutorialTrunk.options?.tutorial,
|
||||
// For now, the only state we need to reset is the slide position.
|
||||
lastSlideIndex: 0,
|
||||
percentComplete: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1055,7 +1055,7 @@ export class FlexServer implements GristServer {
|
||||
// Reset isFirstTimeUser flag.
|
||||
await this._dbManager.updateUser(user.id, {isFirstTimeUser: false});
|
||||
|
||||
// This is a good time to set some other flags, for showing a popup with welcome question(s)
|
||||
// This is a good time to set some other flags, for showing a page with welcome question(s)
|
||||
// to this new user and recording their sign-up with Google Tag Manager. These flags are also
|
||||
// scoped to the user, but isFirstTimeUser has a dedicated DB field because it predates userPrefs.
|
||||
// Note that the updateOrg() method handles all levels of prefs (for user, user+org, or org).
|
||||
@@ -1586,20 +1586,25 @@ export class FlexServer implements GristServer {
|
||||
this.app.post('/welcome/info', ...middleware, expressWrap(async (req, resp, next) => {
|
||||
const userId = getUserId(req);
|
||||
const user = getUser(req);
|
||||
const orgName = stringParam(req.body.org_name, 'org_name');
|
||||
const orgRole = stringParam(req.body.org_role, 'org_role');
|
||||
const useCases = stringArrayParam(req.body.use_cases, 'use_cases');
|
||||
const useOther = stringParam(req.body.use_other, 'use_other');
|
||||
const row = {
|
||||
UserID: userId,
|
||||
Name: user.name,
|
||||
Email: user.loginEmail,
|
||||
org_name: orgName,
|
||||
org_role: orgRole,
|
||||
use_cases: ['L', ...useCases],
|
||||
use_other: useOther,
|
||||
};
|
||||
this._recordNewUserInfo(row)
|
||||
.catch(e => {
|
||||
try {
|
||||
await this._recordNewUserInfo(row);
|
||||
} catch (e) {
|
||||
// If we failed to record, at least log the data, so we could potentially recover it.
|
||||
log.rawWarn(`Failed to record new user info: ${e.message}`, {newUserQuestions: row});
|
||||
});
|
||||
}
|
||||
const nonOtherUseCases = useCases.filter(useCase => useCase !== 'Other');
|
||||
for (const useCase of [...nonOtherUseCases, ...(useOther ? [`Other - ${useOther}`] : [])]) {
|
||||
this.getTelemetry().logEvent(req as RequestWithLogin, 'answeredUseCaseQuestion', {
|
||||
|
||||
@@ -11,3 +11,9 @@ export function getTemplateOrg() {
|
||||
}
|
||||
return org;
|
||||
}
|
||||
|
||||
export function getOnboardingTutorialDocId() {
|
||||
return appSettings.section('tutorials').flag('onboardingTutorialDocId').readString({
|
||||
envVar: 'GRIST_ONBOARDING_TUTORIAL_DOC_ID',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import {SUPPORT_EMAIL} from 'app/gen-server/lib/homedb/HomeDBManager';
|
||||
import {isAnonymousUser, isSingleUserMode, RequestWithLogin} from 'app/server/lib/Authorizer';
|
||||
import {RequestWithOrg} from 'app/server/lib/extractOrg';
|
||||
import {GristServer} from 'app/server/lib/GristServer';
|
||||
import {getTemplateOrg} from 'app/server/lib/gristSettings';
|
||||
import {getOnboardingTutorialDocId, getTemplateOrg} from 'app/server/lib/gristSettings';
|
||||
import {getSupportedEngineChoices} from 'app/server/lib/serverUtils';
|
||||
import {readLoadedLngs, readLoadedNamespaces} from 'app/server/localization';
|
||||
import * as express from 'express';
|
||||
@@ -97,6 +97,7 @@ export function makeGristConfig(options: MakeGristConfigOptions): GristLoadConfi
|
||||
telemetry: server?.getTelemetry().getTelemetryConfig(req as RequestWithLogin | undefined),
|
||||
deploymentType: server?.getDeploymentType(),
|
||||
templateOrg: getTemplateOrg(),
|
||||
onboardingTutorialDocId: getOnboardingTutorialDocId(),
|
||||
canCloseAccount: isAffirmative(process.env.GRIST_ACCOUNT_CLOSE),
|
||||
experimentalPlugins: isAffirmative(process.env.GRIST_EXPERIMENTAL_PLUGINS),
|
||||
notifierEnabled: server?.hasNotifier(),
|
||||
|
||||
Reference in New Issue
Block a user