mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Add button for removing doc tours
Summary: Document owners can now remove doc tours by pressing the button located to the right of 'Tour of this Document' in the left panel. Test Plan: Browser test. Reviewers: jarek Reviewed By: jarek Subscribers: jarek Differential Revision: https://phab.getgrist.com/D3202
This commit is contained in:
parent
89dc9334c3
commit
62a6190970
@ -33,7 +33,7 @@ import {DocPageModel} from 'app/client/models/DocPageModel';
|
|||||||
import {UserError} from 'app/client/models/errors';
|
import {UserError} from 'app/client/models/errors';
|
||||||
import {urlState} from 'app/client/models/gristUrlState';
|
import {urlState} from 'app/client/models/gristUrlState';
|
||||||
import {getFilterFunc, QuerySetManager} from 'app/client/models/QuerySet';
|
import {getFilterFunc, QuerySetManager} from 'app/client/models/QuerySet';
|
||||||
import {getUserOrgPrefObs} from "app/client/models/UserPrefs";
|
import {getUserOrgPrefObs, getUserOrgPrefsObs} from 'app/client/models/UserPrefs';
|
||||||
import {App} from 'app/client/ui/App';
|
import {App} from 'app/client/ui/App';
|
||||||
import {DocHistory} from 'app/client/ui/DocHistory';
|
import {DocHistory} from 'app/client/ui/DocHistory';
|
||||||
import {startDocTour} from "app/client/ui/DocTour";
|
import {startDocTour} from "app/client/ui/DocTour";
|
||||||
@ -128,6 +128,8 @@ export class GristDoc extends DisposableWithEvents {
|
|||||||
// Holds current cursor position with a view id
|
// Holds current cursor position with a view id
|
||||||
public cursorPosition: Computed<ViewCursorPos | undefined>;
|
public cursorPosition: Computed<ViewCursorPos | undefined>;
|
||||||
|
|
||||||
|
public readonly userOrgPrefs = getUserOrgPrefsObs(this.docPageModel.appModel);
|
||||||
|
|
||||||
private _actionLog: ActionLog;
|
private _actionLog: ActionLog;
|
||||||
private _undoStack: UndoStack;
|
private _undoStack: UndoStack;
|
||||||
private _lastOwnActionGroup: ActionGroupWithCursorPos|null = null;
|
private _lastOwnActionGroup: ActionGroupWithCursorPos|null = null;
|
||||||
@ -135,7 +137,7 @@ export class GristDoc extends DisposableWithEvents {
|
|||||||
private _docHistory: DocHistory;
|
private _docHistory: DocHistory;
|
||||||
private _rightPanelTool = createSessionObs(this, "rightPanelTool", "none", RightPanelTool.guard);
|
private _rightPanelTool = createSessionObs(this, "rightPanelTool", "none", RightPanelTool.guard);
|
||||||
private _viewLayout: ViewLayout|null = null;
|
private _viewLayout: ViewLayout|null = null;
|
||||||
private _showGristTour = getUserOrgPrefObs(this.docPageModel.appModel, 'showGristTour');
|
private _showGristTour = getUserOrgPrefObs(this.userOrgPrefs, 'showGristTour');
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public readonly app: App,
|
public readonly app: App,
|
||||||
|
@ -29,13 +29,12 @@ export function getUserOrgPrefsObs(appModel: AppModel): Observable<UserOrgPrefs>
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an observable that returns a particular preference value from UserOrgPrefs, and which
|
* Creates an observable that returns a particular preference value from `prefsObs`, and which
|
||||||
* stores it when set.
|
* stores it when set.
|
||||||
*/
|
*/
|
||||||
export function getUserOrgPrefObs<Name extends keyof UserOrgPrefs>(
|
export function getUserOrgPrefObs<Name extends keyof UserOrgPrefs>(
|
||||||
appModel: AppModel, prefName: Name
|
prefsObs: Observable<UserOrgPrefs>, prefName: Name
|
||||||
): Observable<UserOrgPrefs[Name]> {
|
): Observable<UserOrgPrefs[Name]> {
|
||||||
const prefsObs = getUserOrgPrefsObs(appModel);
|
|
||||||
return Computed.create(null, (use) => use(prefsObs)[prefName])
|
return Computed.create(null, (use) => use(prefsObs)[prefName])
|
||||||
.onWrite(value => prefsObs.set({...prefsObs.get(), [prefName]: value}));
|
.onWrite(value => prefsObs.set({...prefsObs.get(), [prefName]: value}));
|
||||||
}
|
}
|
||||||
|
@ -156,17 +156,18 @@ export const cssSpacer = styled('div', `
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const cssSplitPageEntry = styled('div', `
|
export const cssSplitPageEntry = styled('div', `
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const cssPageEntryMain = styled(cssPageEntry, `
|
export const cssPageEntryMain = styled(cssPageEntry, `
|
||||||
flex: auto;
|
flex: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
min-width: 0px;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const cssPageEntrySmall = styled(cssPageEntry, `
|
export const cssPageEntrySmall = styled(cssPageEntry, `
|
||||||
flex: none;
|
flex: none;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
--icon-color: ${colors.lightGreen};
|
--icon-color: ${colors.lightGreen};
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
import { GristDoc } from "app/client/components/GristDoc";
|
import {GristDoc} from 'app/client/components/GristDoc';
|
||||||
import { urlState } from "app/client/models/gristUrlState";
|
import {loadGristDoc} from 'app/client/lib/imports';
|
||||||
import { showExampleCard } from 'app/client/ui/ExampleCard';
|
import {urlState} from 'app/client/models/gristUrlState';
|
||||||
import { examples } from 'app/client/ui/ExampleInfo';
|
import {getUserOrgPrefObs} from 'app/client/models/UserPrefs';
|
||||||
import { createHelpTools, cssSectionHeader, cssSpacer, cssTools } from 'app/client/ui/LeftPanelCommon';
|
import {showExampleCard} from 'app/client/ui/ExampleCard';
|
||||||
import { cssLinkText, cssPageEntry, cssPageIcon, cssPageLink } from 'app/client/ui/LeftPanelCommon';
|
import {examples} from 'app/client/ui/ExampleInfo';
|
||||||
import { hoverTooltip, tooltipCloseButton } from 'app/client/ui/tooltips';
|
import {createHelpTools, cssLinkText, cssPageEntry, cssPageEntryMain, cssPageEntrySmall,
|
||||||
import { colors } from 'app/client/ui2018/cssVars';
|
cssPageIcon, cssPageLink, cssSectionHeader, cssSpacer, cssSplitPageEntry,
|
||||||
import { icon } from 'app/client/ui2018/icons';
|
cssTools} from 'app/client/ui/LeftPanelCommon';
|
||||||
import { cssLink } from 'app/client/ui2018/links';
|
import {hoverTooltip, tooltipCloseButton} from 'app/client/ui/tooltips';
|
||||||
import { menuAnnotate } from 'app/client/ui2018/menus';
|
import {colors} from 'app/client/ui2018/cssVars';
|
||||||
import { userOverrideParams } from 'app/common/gristUrls';
|
import {icon} from 'app/client/ui2018/icons';
|
||||||
import { Disposable, dom, makeTestId, Observable, observable, styled } from "grainjs";
|
import {cssLink} from 'app/client/ui2018/links';
|
||||||
import {getUserOrgPrefObs} from "app/client/models/UserPrefs";
|
import {menuAnnotate} from 'app/client/ui2018/menus';
|
||||||
import {loadGristDoc} from "app/client/lib/imports";
|
import {confirmModal} from 'app/client/ui2018/modals';
|
||||||
|
import {userOverrideParams} from 'app/common/gristUrls';
|
||||||
|
import {Computed, Disposable, dom, makeTestId, Observable, observable, styled} from 'grainjs';
|
||||||
|
|
||||||
const testId = makeTestId('test-tools-');
|
const testId = makeTestId('test-tools-');
|
||||||
|
|
||||||
export function tools(owner: Disposable, gristDoc: GristDoc, leftPanelOpen: Observable<boolean>): Element {
|
export function tools(owner: Disposable, gristDoc: GristDoc, leftPanelOpen: Observable<boolean>): Element {
|
||||||
const isOwner = gristDoc.docPageModel.currentDoc.get()?.access === 'owners';
|
const isOwner = gristDoc.docPageModel.currentDoc.get()?.access === 'owners';
|
||||||
const isOverridden = Boolean(gristDoc.docPageModel.userOverride.get());
|
const isOverridden = Boolean(gristDoc.docPageModel.userOverride.get());
|
||||||
|
const hasDocTour = Computed.create(owner, use =>
|
||||||
|
use(gristDoc.docModel.allTableIds.getObservable()).includes('GristDocTour'));
|
||||||
const canViewAccessRules = observable(false);
|
const canViewAccessRules = observable(false);
|
||||||
function updateCanViewAccessRules() {
|
function updateCanViewAccessRules() {
|
||||||
canViewAccessRules.set((isOwner && !isOverridden) ||
|
canViewAccessRules.set((isOwner && !isOverridden) ||
|
||||||
@ -84,23 +88,32 @@ export function tools(owner: Disposable, gristDoc: GristDoc, leftPanelOpen: Obse
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
// Shows the 'Tour of this Document' button if a GristDocTour table exists
|
// Show the 'Tour of this Document' button if a GristDocTour table exists.
|
||||||
// at the time of running. Currently doesn't observe the set of existing tables
|
dom.maybe(hasDocTour, () =>
|
||||||
gristDoc.docData.getTable('GristDocTour') &&
|
cssSplitPageEntry(
|
||||||
cssPageEntry(
|
cssPageEntryMain(
|
||||||
cssPageLink(
|
cssPageLink(cssPageIcon('Page'),
|
||||||
cssPageIcon('Page'),
|
cssLinkText('Tour of this Document'),
|
||||||
cssLinkText('Tour of this Document'),
|
automaticHelpTool(
|
||||||
testId('doctour'),
|
async ({markAsSeen}) => {
|
||||||
automaticHelpTool(
|
const gristDocModule = await loadGristDoc();
|
||||||
async ({markAsSeen}) => {
|
await gristDocModule.startDocTour(gristDoc.docData, gristDoc.docComm, markAsSeen);
|
||||||
const gristDocModule = await loadGristDoc();
|
},
|
||||||
await gristDocModule.startDocTour(gristDoc.docData, gristDoc.docComm, markAsSeen);
|
gristDoc,
|
||||||
},
|
"seenDocTours",
|
||||||
gristDoc,
|
gristDoc.docId()
|
||||||
"seenDocTours",
|
),
|
||||||
gristDoc.docId()
|
testId('doctour'),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
!isOwner ? null : cssPageEntrySmall(
|
||||||
|
cssPageLink(cssPageIcon('Remove'),
|
||||||
|
dom.on('click', () => confirmModal('Delete document tour?', 'Delete', () =>
|
||||||
|
gristDoc.docData.sendAction(['RemoveTable', 'GristDocTour']))
|
||||||
|
),
|
||||||
|
testId('remove-doctour')
|
||||||
|
),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
createHelpTools(gristDoc.docPageModel.appModel, false)
|
createHelpTools(gristDoc.docPageModel.appModel, false)
|
||||||
@ -127,8 +140,7 @@ function automaticHelpTool(
|
|||||||
itemId: number | string
|
itemId: number | string
|
||||||
) {
|
) {
|
||||||
function show(elem: HTMLElement, reopen: boolean) {
|
function show(elem: HTMLElement, reopen: boolean) {
|
||||||
const appModel = gristDoc.docPageModel.appModel;
|
const prefObs: Observable<typeof itemId[] | undefined> = getUserOrgPrefObs(gristDoc.userOrgPrefs, prefKey);
|
||||||
const prefObs: Observable<typeof itemId[] | undefined> = getUserOrgPrefObs(appModel, prefKey);
|
|
||||||
const seenIds = prefObs.get() || [];
|
const seenIds = prefObs.get() || [];
|
||||||
|
|
||||||
// If this help was previously dismissed, don't show it again, unless the user is reopening it.
|
// If this help was previously dismissed, don't show it again, unless the user is reopening it.
|
||||||
|
Loading…
Reference in New Issue
Block a user