-
-
Notifications
You must be signed in to change notification settings - Fork 337
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
254 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import {AppModel, getHomeUrl} from 'app/client/models/AppModel'; | ||
import {bundleChanges, Disposable, Observable} from "grainjs"; | ||
import {ConfigAPI, ConfigAPIImpl} from 'app/common/ConfigAPI'; | ||
|
||
export class ToggleEnterpriseModel extends Disposable { | ||
public readonly edition: Observable<string | null> = Observable.create(this, null); | ||
private readonly _configAPI: ConfigAPI = new ConfigAPIImpl(getHomeUrl()); | ||
constructor (_appModel: AppModel) { | ||
super(); | ||
} | ||
|
||
public async fetchEnterpriseToggle(): Promise<void> { | ||
const edition = await this._configAPI.getValue('edition'); | ||
bundleChanges(() => { | ||
this.edition.set(edition); | ||
}); | ||
} | ||
|
||
public async updateEnterpriseToggle(edition: string): Promise<void> { | ||
await this._configAPI.setValue({edition}); | ||
await this.fetchEnterpriseToggle(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import {bigBasicButton, bigBasicButtonLink, bigPrimaryButton} from 'app/client/ui2018/buttons'; | ||
import {theme} from 'app/client/ui2018/cssVars'; | ||
import {styled} from 'grainjs'; | ||
|
||
export const cssSection = styled('div', ``); | ||
|
||
export const cssParagraph = styled('div', ` | ||
color: ${theme.text}; | ||
font-size: 14px; | ||
line-height: 20px; | ||
margin-bottom: 12px; | ||
`); | ||
|
||
export const cssOptInOutMessage = styled(cssParagraph, ` | ||
line-height: 40px; | ||
font-weight: 600; | ||
margin-top: 24px; | ||
margin-bottom: 0px; | ||
`); | ||
|
||
export const cssOptInButton = styled(bigPrimaryButton, ` | ||
margin-top: 24px; | ||
`); | ||
|
||
export const cssOptOutButton = styled(bigBasicButton, ` | ||
margin-top: 24px; | ||
`); | ||
|
||
export const cssSponsorButton = styled(bigBasicButtonLink, ` | ||
margin-top: 24px; | ||
`); | ||
|
||
export const cssButtonIconAndText = styled('div', ` | ||
display: flex; | ||
align-items: center; | ||
`); | ||
|
||
export const cssButtonText = styled('span', ` | ||
margin-left: 8px; | ||
`); | ||
|
||
export const cssSpinnerBox = styled('div', ` | ||
margin-top: 24px; | ||
text-align: center; | ||
`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import {makeT} from 'app/client/lib/localization'; | ||
import {Computed, Disposable, dom, makeTestId} from "grainjs"; | ||
import {AppModel} from "app/client/models/AppModel"; | ||
import {loadingSpinner} from 'app/client/ui2018/loaders'; | ||
import {commonUrls} from "app/common/gristUrls"; | ||
import {cssLink} from 'app/client/ui2018/links'; | ||
import {ToggleEnterpriseModel} from 'app/client/models/ToggleEnterpriseModel'; | ||
import { | ||
cssOptInButton, | ||
cssOptInOutMessage, | ||
cssOptOutButton, | ||
cssParagraph, | ||
cssSection, | ||
cssSpinnerBox | ||
} from 'app/client/ui/AdminTogglesCss'; | ||
|
||
|
||
const t = makeT('ToggleEnterprsiePage'); | ||
const testId = makeTestId('test-toggle-enterprise-page-'); | ||
|
||
export class ToggleEnterprisePage extends Disposable { | ||
private readonly _model: ToggleEnterpriseModel = new ToggleEnterpriseModel(this._appModel); | ||
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(private _appModel: AppModel) { | ||
super(); | ||
this._model.fetchEnterpriseToggle().catch(reportError); | ||
} | ||
|
||
public getEnterpriseToggleObservable() { | ||
return this._isEnterprise; | ||
} | ||
|
||
public buildEnterpriseSection() { | ||
return cssSection( | ||
dom.domComputed(this._isEnterprise, isEnterprise => { | ||
if (isEnterprise === null) { | ||
return cssSpinnerBox(loadingSpinner()); | ||
} | ||
return [ | ||
cssParagraph( | ||
t('Activation keys are used to run Grist Enterprise after a trial period ' + | ||
'of 30 days has expired. Get an activation key by signing up for Grist ' + | ||
'Enterprise. You do not need an activation key to run Grist Core.') | ||
), | ||
cssParagraph(t('Learn more in our {{link}}.', { | ||
link: enterpriseHelpCenterLink(), | ||
})), | ||
this._buildEnterpriseSectionButtons(), | ||
]; | ||
}), | ||
testId('enterprise-opt-in-section'), | ||
); | ||
} | ||
|
||
public _buildEnterpriseSectionButtons() { | ||
return dom.domComputed(this._isEnterprise, (enterpriseEnabled) => { | ||
if (enterpriseEnabled) { | ||
return [ | ||
cssOptInOutMessage( | ||
t('Grist Enterprise Edition is enabled.'), | ||
testId('enterprise-opt-out-message'), | ||
), | ||
cssOptOutButton(t('Disable Grist Enterprise Edition'), | ||
dom.on('click', () => this._isEnterprise.set(false)), | ||
), | ||
]; | ||
} else { | ||
return [ | ||
cssOptInButton(t('Enable Grist Enterprise Edition'), | ||
dom.on('click', () => this._isEnterprise.set(true)), | ||
), | ||
]; | ||
} | ||
}); | ||
} | ||
} | ||
|
||
function enterpriseHelpCenterLink() { | ||
return cssLink( | ||
t('Help Center'), | ||
{href: commonUrls.helpEnterpriseOptIn, target: '_blank'}, | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { BaseAPI, IOptions } from "app/common/BaseAPI"; | ||
import {addCurrentOrgToPath} from 'app/common/urlUtils'; | ||
|
||
export interface ConfigAPI { | ||
getValue(key: string): Promise<any>; | ||
setValue(value: any): Promise<void>; | ||
} | ||
|
||
export class ConfigAPIImpl extends BaseAPI implements ConfigAPI { | ||
constructor(private _homeUrl: string, options: IOptions = {}) { | ||
super(options); | ||
} | ||
|
||
public async getValue(key: string): Promise<any> { | ||
return (await this.requestJson(`${this._url}/api/config/${key}`, {method: 'GET'})).value; | ||
} | ||
|
||
public async setValue(value: any): Promise<void> { | ||
await this.request(`${this._url}/api/config`, { | ||
method: 'PATCH', | ||
body: JSON.stringify(value), | ||
}); | ||
} | ||
|
||
private get _url(): string { | ||
return addCurrentOrgToPath(this._homeUrl); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import * as express from 'express'; | ||
import {expressWrap} from 'app/server/lib/expressWrap'; | ||
|
||
import {IGristCoreConfig, loadGristCoreConfigFile} from 'app/server/lib/configCore'; | ||
import log from "app/server/lib/log"; | ||
|
||
export class ConfigBackendAPI { | ||
private _config: IGristCoreConfig; | ||
public async init () { | ||
this._config = await loadGristCoreConfigFile(); | ||
} | ||
|
||
public addEndpoints(app: express.Express, requireMiddleware: express.RequestHandler) { | ||
app.get('/api/config/:key', requireMiddleware, expressWrap(async (req, resp) => { | ||
log.debug('config: requesting configuration', req.params); | ||
|
||
// Only one key is valid for now | ||
if (req.params.key === 'edition') { | ||
resp.send({value: this._config.edition.get()}); | ||
} else { | ||
resp.status(404).send('Configuration key not found.'); | ||
} | ||
})); | ||
|
||
app.patch('/api/config', requireMiddleware, expressWrap(async (req, resp) => { | ||
log.debug('config: received new configuration item', req.body); | ||
if(req.body.edition !== undefined) { | ||
await this._config.edition.set(req.body.edition); | ||
resp.sendStatus(200); | ||
} else { | ||
resp.status(400).send('Invalid configuration key'); | ||
} | ||
})); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters