From ffe3b2237865bed1d0833915750794a31953c3f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jordi=20Guti=C3=A9rrez=20Hermoso?= Date: Wed, 24 Jul 2024 18:55:19 -0400 Subject: [PATCH] ToggleEnterpriseWidget: new frontend toggle for the admin Strongly patterned after SupportGristPage. In fact, it has almost the same structure. Perhaps one day it would be possible to synchronise the logic between the two toggles even further, but I couldn't see a simple way to do so now. For now, some code structure duplication seemed easiest in lieau of more abstractions. --- app/client/ui/ToggleEnterpriseWidget.ts | 78 +++++++++++++++++++++++++ app/common/gristUrls.ts | 1 + 2 files changed, 79 insertions(+) create mode 100644 app/client/ui/ToggleEnterpriseWidget.ts diff --git a/app/client/ui/ToggleEnterpriseWidget.ts b/app/client/ui/ToggleEnterpriseWidget.ts new file mode 100644 index 00000000..01019900 --- /dev/null +++ b/app/client/ui/ToggleEnterpriseWidget.ts @@ -0,0 +1,78 @@ +import {makeT} from 'app/client/lib/localization'; +import {markdown} from 'app/client/lib/markdown'; +import {Computed, Disposable, dom, makeTestId} from "grainjs"; +import {commonUrls} from "app/common/gristUrls"; +import {ToggleEnterpriseModel} from 'app/client/models/ToggleEnterpriseModel'; +import { + cssOptInButton, + cssOptOutButton, + cssParagraph, + cssSection, +} from 'app/client/ui/AdminTogglesCss'; + + +const t = makeT('ToggleEnterprsiePage'); +const testId = makeTestId('test-toggle-enterprise-page-'); + +export class ToggleEnterpriseWidget extends Disposable { + private readonly _model: ToggleEnterpriseModel = new ToggleEnterpriseModel(); + private readonly _isEnterprise = Computed.create(this, this._model.edition, (_use, edition) => { + return edition === 'enterprise'; + }).onWrite(async (enabled) => { + await this._model.updateEnterpriseToggle(enabled ? 'enterprise' : 'core'); + }); + + constructor() { + super(); + this._model.fetchEnterpriseToggle().catch(reportError); + } + + public getEnterpriseToggleObservable() { + return this._isEnterprise; + } + + public buildEnterpriseSection() { + return cssSection( + dom.domComputed(this._isEnterprise, (enterpriseEnabled) => { + return [ + enterpriseEnabled ? + cssParagraph( + markdown(t('Grist Enterprise is **enabled**.')), + testId('enterprise-opt-out-message'), + ) : null, + cssParagraph( + markdown(t(`An activation key is used to run Grist Enterprise after a trial period +of 30 days has expired. Get an activation key by [signing up for Grist +Enterprise]({{signupLink}}). You do not need an activation key to run +Grist Core. + +Learn more in our [Help Center]({{helpCenter}}).`, { + signupLink: commonUrls.plans, + helpCenter: commonUrls.helpEnterpriseOptIn + })) + ), + this._buildEnterpriseSectionButtons(), + ]; + }), + testId('enterprise-opt-in-section'), + ); + } + + public _buildEnterpriseSectionButtons() { + return dom.domComputed(this._isEnterprise, (enterpriseEnabled) => { + if (enterpriseEnabled) { + return [ + cssOptOutButton(t('Disable Grist Enterprise'), + dom.on('click', () => this._isEnterprise.set(false)), + ), + ]; + } else { + return [ + cssOptInButton(t('Enable Grist Enterprise'), + dom.on('click', () => this._isEnterprise.set(true)), + ), + ]; + } + }); + } +} diff --git a/app/common/gristUrls.ts b/app/common/gristUrls.ts index 2f81d215..6edc6fa8 100644 --- a/app/common/gristUrls.ts +++ b/app/common/gristUrls.ts @@ -84,6 +84,7 @@ export const commonUrls = { helpTryingOutChanges: "https://support.getgrist.com/copying-docs/#trying-out-changes", helpCustomWidgets: "https://support.getgrist.com/widget-custom", helpTelemetryLimited: "https://support.getgrist.com/telemetry-limited", + helpEnterpriseOptIn: "https://support.getgrist.com/self-managed/#how-do-i-activate-grist-enterprise", helpCalendarWidget: "https://support.getgrist.com/widget-calendar", helpLinkKeys: "https://support.getgrist.com/examples/2021-04-link-keys", helpFilteringReferenceChoices: "https://support.getgrist.com/col-refs/#filtering-reference-choices-in-dropdown",