(core) Add initial tutorials implementation

Summary:
Documents can now be flagged as tutorials, which causes them to display
Markdown-formatted slides from a special GristDocTutorial table. Tutorial
documents are forked on open, and remember the last slide a user was on.
They can be restarted too, which prepares a new fork of the tutorial.

Test Plan: Browser tests.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3813
This commit is contained in:
George Gevoian
2023-03-22 09:48:50 -04:00
parent 210aa92eed
commit be8e13df64
31 changed files with 1621 additions and 174 deletions

View File

@@ -345,6 +345,9 @@ export const ThemeColors = t.iface([], {
"date-picker-range-start-end-bg-hover": "string",
"date-picker-range-bg": "string",
"date-picker-range-bg-hover": "string",
"tutorials-popup-border": "string",
"tutorials-popup-header-fg": "string",
"tutorials-popup-box-bg": "string",
});
const exportedTypeSuite: t.ITypeSuite = {

View File

@@ -451,6 +451,11 @@ export interface ThemeColors {
'date-picker-range-start-end-bg-hover': string;
'date-picker-range-bg': string;
'date-picker-range-bg-hover': string;
/* Tutorials */
'tutorials-popup-border': string;
'tutorials-popup-header-fg': string;
'tutorials-popup-box-bg': string;
}
export const ThemePrefsChecker = createCheckers(ThemePrefsTI).ThemePrefs as CheckerT<ThemePrefs>;

View File

@@ -119,6 +119,11 @@ export interface DocumentOptions {
openMode?: OpenDocMode|null;
externalId?: string|null; // A slot for storing an externally maintained id.
// Not used in grist-core, but handy for Electron app.
tutorial?: TutorialMetadata|null;
}
export interface TutorialMetadata {
lastSlideIndex?: number;
}
export interface DocumentProperties extends CommonProperties {
@@ -129,7 +134,7 @@ export interface DocumentProperties extends CommonProperties {
options: DocumentOptions|null;
}
export const documentPropertyKeys = [...commonPropertyKeys, 'isPinned', 'urlId', 'options'];
export const documentPropertyKeys = [...commonPropertyKeys, 'isPinned', 'urlId', 'options', 'type'];
export interface Document extends DocumentProperties {
id: string;
@@ -143,6 +148,7 @@ export interface Fork {
id: string;
trunkId: string;
updatedAt: string; // ISO date string
options: DocumentOptions|null;
}
// Non-core options for a user.
@@ -241,8 +247,21 @@ export interface OrgError {
* (e.g. a fork) or from a snapshot.
*/
export interface DocReplacementOptions {
sourceDocId?: string; // docId to copy from
snapshotId?: string; // s3 VersionId
/**
* The docId to copy from.
*/
sourceDocId?: string;
/**
* The s3 version ID.
*/
snapshotId?: string;
/**
* True if tutorial metadata should be reset.
*
* Metadata that's reset includes the doc (i.e. tutorial) name, and the
* properties under options.tutorial (e.g. lastSlideIndex).
*/
resetTutorialMetadata?: boolean;
}
/**

View File

@@ -430,4 +430,9 @@ export const GristDark: ThemeColors = {
'date-picker-range-start-end-bg-hover': '#8F8F8F',
'date-picker-range-bg': '#57575F',
'date-picker-range-bg-hover': '#7F7F7F',
/* Tutorials */
'tutorials-popup-border': '#69697D',
'tutorials-popup-header-fg': '#FFFFFF',
'tutorials-popup-box-bg': '#57575F',
};

View File

@@ -430,4 +430,9 @@ export const GristLight: ThemeColors = {
'date-picker-range-start-end-bg-hover': '#CFCFCF',
'date-picker-range-bg': '#EEEEEE',
'date-picker-range-bg-hover': '#D9D9D9',
/* Tutorials */
'tutorials-popup-border': '#D9D9D9',
'tutorials-popup-header-fg': '#FFFFFF',
'tutorials-popup-box-bg': '#F5F5F5',
};