diff --git a/app/client/components/BehavioralPromptsManager.ts b/app/client/components/BehavioralPromptsManager.ts index a48fa88e..c086f7ac 100644 --- a/app/client/components/BehavioralPromptsManager.ts +++ b/app/client/components/BehavioralPromptsManager.ts @@ -77,6 +77,11 @@ export class BehavioralPromptsManager extends Disposable { this._isDisabled = true; } + public reset() { + this._prefs.set({...this._prefs.get(), dismissedTips: [], dontShowTips: false}); + this.enable(); + } + private _queueTip(refElement: Element, prompt: BehavioralPrompt, options: AttachOptions) { if ( this._isDisabled || diff --git a/app/client/components/GristDoc.ts b/app/client/components/GristDoc.ts index f6976f6d..fc9e6415 100644 --- a/app/client/components/GristDoc.ts +++ b/app/client/components/GristDoc.ts @@ -513,6 +513,24 @@ export class GristDoc extends DisposableWithEvents { this.draftMonitor = Drafts.create(this, this); this.cursorMonitor = CursorMonitor.create(this, this); this.editorMonitor = EditorMonitor.create(this, this); + + // When active section is changed to a chart or custom widget, change the tab in the creator + // panel to the table. + this.autoDispose(this.viewModel.activeSection.subscribe((section) => { + if (section.isDisposed() || section._isDeleted.peek()) { return; } + if ('chart' === section.parentKey.peek()) { + commands.allCommands.viewTabFocus.run(); + } else if ('custom' === section.parentKey.peek()) { + // Check if user has seen custom URL tooltip. + const seenTooltip = this.behavioralPromptsManager.hasSeenTip('customURL'); + // If yes, just focus on the table if it is opened + if (seenTooltip) { + commands.allCommands.viewTabFocus.run(); + } else { + commands.allCommands.viewTabOpen.run(); + } + } + })); } /** diff --git a/app/client/components/commandList.js b/app/client/components/commandList.js index e9039594..b0159fa9 100644 --- a/app/client/components/commandList.js +++ b/app/client/components/commandList.js @@ -73,6 +73,11 @@ exports.groups = [{ keys: [], desc: 'Shortcut to open view tab' }, + { + name: 'viewTabFocus', + keys: [], + desc: 'Shortcut to focus view tab if creator panel is open' + }, { name: 'fieldTabOpen', keys: [], diff --git a/app/client/models/AppModel.ts b/app/client/models/AppModel.ts index 0841dc93..0182f833 100644 --- a/app/client/models/AppModel.ts +++ b/app/client/models/AppModel.ts @@ -282,6 +282,7 @@ export class AppModelImpl extends Disposable implements AppModel { G.window.resetSeenPopups = (seen = false) => { this.dismissedPopups.set(seen ? DismissedPopup.values : []); + this.behavioralPromptsManager.reset(); }; } diff --git a/app/client/ui/CustomSectionConfig.ts b/app/client/ui/CustomSectionConfig.ts index 59d66e3e..efa48232 100644 --- a/app/client/ui/CustomSectionConfig.ts +++ b/app/client/ui/CustomSectionConfig.ts @@ -238,7 +238,7 @@ export class CustomSectionConfig extends Disposable { // Does widget has custom configuration. private _hasConfiguration: Computed; - constructor(private _section: ViewSectionRec, _gristDoc: GristDoc) { + constructor(private _section: ViewSectionRec, private _gristDoc: GristDoc) { super(); const api = _gristDoc.app.topAppModel.api; @@ -411,7 +411,12 @@ export class CustomSectionConfig extends Disposable { async value => this._url.set(value), dom.attr('placeholder', t("Enter Custom URL")), testId('url') - ) + ), + this._gristDoc.behavioralPromptsManager.attachTip('customURL', { + popupOptions: { + placement: 'left-start', + } + }) ), ]), dom.maybe(prompt, () => diff --git a/app/client/ui/GristTooltips.ts b/app/client/ui/GristTooltips.ts index 8645cbd7..62d172c0 100644 --- a/app/client/ui/GristTooltips.ts +++ b/app/client/ui/GristTooltips.ts @@ -217,5 +217,18 @@ export const GristBehavioralPrompts: Record t('Custom Widgets'), + content: (...args: DomElementArg[]) => cssTooltipContent( + dom('div', + t( + 'You can choose one of our pre-made widgets or embed your own ' + + 'by providing its full URL.' + ), + ), + dom('div', cssLink({href: commonUrls.helpCustomWidgets, target: '_blank'}, t('Learn more.'))), + ...args, + ), + }, }; diff --git a/app/client/ui/RightPanel.ts b/app/client/ui/RightPanel.ts index 676d27f1..230894e1 100644 --- a/app/client/ui/RightPanel.ts +++ b/app/client/ui/RightPanel.ts @@ -104,6 +104,7 @@ export class RightPanel extends Disposable { this.autoDispose(commands.createGroup({ fieldTabOpen: () => this._openFieldTab(), viewTabOpen: () => this._openViewTab(), + viewTabFocus: () => this._viewTabFocus(), sortFilterTabOpen: () => this._openSortFilter(), dataSelectionTabOpen: () => this._openDataSelection() }, this, true)); @@ -117,6 +118,11 @@ export class RightPanel extends Disposable { this._open('pageWidget', 'widget'); } + private _viewTabFocus() { + // If the view tab is already open, focus on the first input. + this._focus('pageWidget'); + } + private _openSortFilter() { this._open('pageWidget', 'sortAndFilter'); } @@ -135,6 +141,14 @@ export class RightPanel extends Disposable { }); } + private _focus(topTab: typeof TopTab.type) { + bundleChanges(() => { + if (!this._isOpen.get()) { return; } + this._isOpen.set(true); + this._topTab.set(topTab); + }); + } + private _buildHeaderDom() { return dom.domComputed((use) => { if (!use(this._isOpen)) { return null; } diff --git a/app/common/Prefs.ts b/app/common/Prefs.ts index 41abddff..d19e1ec5 100644 --- a/app/common/Prefs.ts +++ b/app/common/Prefs.ts @@ -86,6 +86,7 @@ export const BehavioralPrompt = StringUnion( 'editCardLayout', 'addNew', 'rickRow', + 'customURL', ); export type BehavioralPrompt = typeof BehavioralPrompt.type; diff --git a/app/common/gristUrls.ts b/app/common/gristUrls.ts index a954dbf5..5e4bf197 100644 --- a/app/common/gristUrls.ts +++ b/app/common/gristUrls.ts @@ -70,6 +70,7 @@ export const commonUrls = { helpUnderstandingReferenceColumns: "https://support.getgrist.com/col-refs/#understanding-reference-columns", helpTriggerFormulas: "https://support.getgrist.com/formulas/#trigger-formulas", helpTryingOutChanges: "https://support.getgrist.com/copying-docs/#trying-out-changes", + helpCustomWidgets: "https://support.getgrist.com/widget-custom", plans: "https://www.getgrist.com/pricing", createTeamSite: "https://www.getgrist.com/create-team-site", sproutsProgram: "https://www.getgrist.com/sprouts-program", diff --git a/static/custom-widget.html b/static/custom-widget.html index 9af2dfca..3e1fef15 100644 --- a/static/custom-widget.html +++ b/static/custom-widget.html @@ -3,8 +3,6 @@ - - Custom widget