From c32090618e535eb48fb4dc377659ff97dae1a9ee Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Mon, 10 Dec 2018 16:34:53 +0100 Subject: merge default and fetched feature configs --- src/stores/FeaturesStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/stores/FeaturesStore.js') diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index 0adee6adf..eb2b21af3 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js @@ -37,7 +37,7 @@ export default class FeaturesStore extends Store { @computed get features() { if (this.stores.user.isLoggedIn) { - return this.featuresRequest.execute().result || DEFAULT_FEATURES_CONFIG; + return Object.assign({}, DEFAULT_FEATURES_CONFIG, this.featuresRequest.execute().result); } return DEFAULT_FEATURES_CONFIG; -- cgit v1.2.3-70-g09d2 From 4a537e890d95e8666985ce77df4c6327582332be Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Mon, 10 Dec 2018 17:15:37 +0100 Subject: basic setup for workspaces feature --- src/config.js | 1 + src/features/workspaces/api.js | 9 +++++++++ src/features/workspaces/index.js | 34 ++++++++++++++++++++++++++++++++++ src/features/workspaces/store.js | 29 +++++++++++++++++++++++++++++ src/stores/FeaturesStore.js | 2 ++ 5 files changed, 75 insertions(+) create mode 100644 src/features/workspaces/api.js create mode 100644 src/features/workspaces/index.js create mode 100644 src/features/workspaces/store.js (limited to 'src/stores/FeaturesStore.js') diff --git a/src/config.js b/src/config.js index 789ddd1a0..d7a485b8a 100644 --- a/src/config.js +++ b/src/config.js @@ -37,6 +37,7 @@ export const DEFAULT_FEATURES_CONFIG = { }, isServiceProxyEnabled: false, isServiceProxyPremiumFeature: true, + isWorkspaceEnabled: true, }; export const DEFAULT_WINDOW_OPTIONS = { diff --git a/src/features/workspaces/api.js b/src/features/workspaces/api.js new file mode 100644 index 000000000..1ee2440fe --- /dev/null +++ b/src/features/workspaces/api.js @@ -0,0 +1,9 @@ +// TODO: use real server instead +const workspaces = [ + { id: 'workspace-1', name: 'Private' }, + { id: 'workspace-2', name: 'Office' }, +]; + +export default { + getUserWorkspaces: () => Promise.resolve(workspaces), +}; diff --git a/src/features/workspaces/index.js b/src/features/workspaces/index.js new file mode 100644 index 000000000..b7e1090e8 --- /dev/null +++ b/src/features/workspaces/index.js @@ -0,0 +1,34 @@ +import { observable, reaction } from 'mobx'; +import { merge } from 'lodash'; +import WorkspacesStore from './store'; +import api from './api'; + +const debug = require('debug')('Franz:feature:workspaces'); + +let store = null; +const defaultState = { workspaces: [] }; + +export const state = observable(defaultState); + +export default function initWorkspaces(stores, actions) { + const { features, user } = stores; + reaction( + () => features.features.isWorkspaceEnabled && user.isLoggedIn, + (isEnabled) => { + if (isEnabled) { + debug('Initializing `workspaces` feature'); + store = new WorkspacesStore(stores, api, actions, state); + store.initialize(); + } else if (store) { + debug('Disabling `workspaces` feature'); + store.teardown(); + store = null; + // Reset state to default + merge(state, defaultState); + } + }, + { + fireImmediately: true, + }, + ); +} diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js new file mode 100644 index 000000000..4b4e729ed --- /dev/null +++ b/src/features/workspaces/store.js @@ -0,0 +1,29 @@ +import { observable, reaction } from 'mobx'; +import Store from '../../stores/lib/Store'; +import CachedRequest from '../../stores/lib/CachedRequest'; + +const debug = require('debug')('Franz:feature:workspaces'); + +export default class WorkspacesStore extends Store { + @observable allWorkspacesRequest = new CachedRequest(this.api, 'getUserWorkspaces'); + + constructor(stores, api, actions, state) { + super(stores, api, actions); + this.state = state; + } + + setup() { + debug('fetching user workspaces'); + this.allWorkspacesRequest.execute(); + + reaction( + () => this.allWorkspacesRequest.result, + workspaces => this.setWorkspaces(workspaces), + ); + } + + setWorkspaces = (workspaces) => { + debug('setting user workspaces', workspaces.slice()); + this.state.workspaces = workspaces; + }; +} diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index eb2b21af3..05a620f0b 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js @@ -7,6 +7,7 @@ import delayApp from '../features/delayApp'; import spellchecker from '../features/spellchecker'; import serviceProxy from '../features/serviceProxy'; import basicAuth from '../features/basicAuth'; +import workspaces from '../features/workspaces'; import { DEFAULT_FEATURES_CONFIG } from '../config'; @@ -56,5 +57,6 @@ export default class FeaturesStore extends Store { spellchecker(this.stores, this.actions); serviceProxy(this.stores, this.actions); basicAuth(this.stores, this.actions); + workspaces(this.stores, this.actions); } } -- cgit v1.2.3-70-g09d2 From d05a8efffadd926165d516d6efd8c8b893648ebe Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Tue, 26 Mar 2019 13:47:54 +0100 Subject: hide workspace feature if it is disabled --- src/components/layout/Sidebar.js | 25 ++++++----- .../settings/navigation/SettingsNavigation.js | 21 +++++---- src/config.js | 2 +- src/features/workspaces/store.js | 5 +++ src/i18n/locales/defaultMessages.json | 52 +++++++++++----------- .../messages/src/components/layout/Sidebar.json | 24 +++++----- .../settings/navigation/SettingsNavigation.json | 28 ++++++------ src/lib/Menu.js | 6 ++- src/stores/FeaturesStore.js | 4 +- 9 files changed, 90 insertions(+), 77 deletions(-) (limited to 'src/stores/FeaturesStore.js') diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js index de379875e..f7bacfe0f 100644 --- a/src/components/layout/Sidebar.js +++ b/src/components/layout/Sidebar.js @@ -6,6 +6,7 @@ import { observer } from 'mobx-react'; import Tabbar from '../services/tabs/Tabbar'; import { ctrlKey } from '../../environment'; +import { workspaceStore } from '../../features/workspaces'; const messages = defineMessages({ settings: { @@ -88,17 +89,19 @@ export default @observer class Sidebar extends Component { enableToolTip={() => this.enableToolTip()} disableToolTip={() => this.disableToolTip()} /> - + {workspaceStore.isFeatureActive ? ( + + ) : null} @@ -73,3 +88,5 @@ PremiumFeatureContainer.wrappedComponent.propTypes = { }).isRequired, }).isRequired, }; + +export default PremiumFeatureContainer; diff --git a/src/components/ui/PremiumFeatureContainer/styles.js b/src/components/ui/PremiumFeatureContainer/styles.js index 81d6666c6..615ed0a79 100644 --- a/src/components/ui/PremiumFeatureContainer/styles.js +++ b/src/components/ui/PremiumFeatureContainer/styles.js @@ -6,6 +6,7 @@ export default theme => ({ padding: 20, 'border-radius': theme.borderRadius, pointerEvents: 'none', + height: 'auto', }, titleContainer: { display: 'flex', @@ -26,7 +27,7 @@ export default theme => ({ content: { opacity: 0.5, 'margin-top': 20, - '& :last-child': { + '& > :last-child': { 'margin-bottom': 0, }, }, diff --git a/src/features/delayApp/index.js b/src/features/delayApp/index.js index abc8274cf..67f0fc5e6 100644 --- a/src/features/delayApp/index.js +++ b/src/features/delayApp/index.js @@ -55,7 +55,7 @@ export default function init(stores) { setVisibility(true); gaPage('/delayApp'); - gaEvent('delayApp', 'show', 'Delay App Feature'); + gaEvent('DelayApp', 'show', 'Delay App Feature'); timeLastDelay = moment(); shownAfterLaunch = true; diff --git a/src/features/utils/FeatureStore.js b/src/features/utils/FeatureStore.js new file mode 100644 index 000000000..66b66a104 --- /dev/null +++ b/src/features/utils/FeatureStore.js @@ -0,0 +1,21 @@ +import Reaction from '../../stores/lib/Reaction'; + +export class FeatureStore { + _actions = null; + + _reactions = null; + + _listenToActions(actions) { + if (this._actions) this._actions.forEach(a => a[0].off(a[1])); + this._actions = []; + actions.forEach(a => this._actions.push(a)); + this._actions.forEach(a => a[0].listen(a[1])); + } + + _startReactions(reactions) { + if (this._reactions) this._reactions.forEach(r => r.stop()); + this._reactions = []; + reactions.forEach(r => this._reactions.push(new Reaction(r))); + this._reactions.forEach(r => r.start()); + } +} diff --git a/src/features/workspaces/components/CreateWorkspaceForm.js b/src/features/workspaces/components/CreateWorkspaceForm.js index a8f07d0d5..0be2d528f 100644 --- a/src/features/workspaces/components/CreateWorkspaceForm.js +++ b/src/features/workspaces/components/CreateWorkspaceForm.js @@ -30,7 +30,6 @@ const styles = () => ({ }, submitButton: { height: 'inherit', - marginTop: '3px', }, }); diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js index 52c3afdcf..1fad1f71d 100644 --- a/src/features/workspaces/components/WorkspacesDashboard.js +++ b/src/features/workspaces/components/WorkspacesDashboard.js @@ -10,6 +10,8 @@ import WorkspaceItem from './WorkspaceItem'; import CreateWorkspaceForm from './CreateWorkspaceForm'; import Request from '../../../stores/lib/Request'; import Appear from '../../../components/ui/effects/Appear'; +import { workspaceStore } from '../index'; +import PremiumFeatureContainer from '../../../components/ui/PremiumFeatureContainer'; const messages = defineMessages({ headline: { @@ -36,6 +38,14 @@ const messages = defineMessages({ id: 'settings.workspaces.deletedInfo', defaultMessage: '!!!Workspace has been deleted', }, + workspaceFeatureInfo: { + id: 'settings.workspaces.workspaceFeatureInfo', + defaultMessage: '!!!Info about workspace feature', + }, + workspaceFeatureHeadline: { + id: 'settings.workspaces.workspaceFeatureHeadline', + defaultMessage: '!!!Less is More: Introducing Franz Workspaces', + }, }); const styles = () => ({ @@ -46,6 +56,12 @@ const styles = () => ({ appear: { height: 'auto', }, + premiumAnnouncement: { + padding: '20px', + backgroundColor: '#3498db', + marginLeft: '-20px', + height: 'auto', + }, }); @injectSheet(styles) @observer @@ -112,14 +128,24 @@ class WorkspacesDashboard extends Component { )} - {/* ===== Create workspace form ===== */} -
- -
- + + {/* ===== Create workspace form ===== */} +
+ +
+
+ {workspaceStore.isUpgradeToPremiumRequired && ( +
+

{intl.formatMessage(messages.workspaceFeatureHeadline)}

+

{intl.formatMessage(messages.workspaceFeatureInfo)}

+
+ )} {getUserWorkspacesRequest.isExecuting ? ( ) : ( diff --git a/src/features/workspaces/index.js b/src/features/workspaces/index.js index 89999ab0f..524a83e3c 100644 --- a/src/features/workspaces/index.js +++ b/src/features/workspaces/index.js @@ -4,11 +4,12 @@ import { resetApiRequests } from './api'; const debug = require('debug')('Franz:feature:workspaces'); -export const GA_CATEGORY_WORKSPACES = 'workspaces'; +export const GA_CATEGORY_WORKSPACES = 'Workspaces'; export const workspaceStore = new WorkspacesStore(); export default function initWorkspaces(stores, actions) { + stores.workspaces = workspaceStore; const { features, user } = stores; // Toggle workspace feature diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js index f7df7b29c..62bf3efb4 100644 --- a/src/features/workspaces/store.js +++ b/src/features/workspaces/store.js @@ -3,9 +3,9 @@ import { observable, action, } from 'mobx'; -import Reaction from '../../stores/lib/Reaction'; import { matchRoute } from '../../helpers/routing-helpers'; import { workspaceActions } from './actions'; +import { FeatureStore } from '../utils/FeatureStore'; import { createWorkspaceRequest, deleteWorkspaceRequest, @@ -15,7 +15,11 @@ import { const debug = require('debug')('Franz:feature:workspaces:store'); -export default class WorkspacesStore { +export default class WorkspacesStore extends FeatureStore { + @observable isFeatureEnabled = false; + + @observable isPremiumFeature = true; + @observable isFeatureActive = false; @observable activeWorkspace = null; @@ -33,36 +37,39 @@ export default class WorkspacesStore { return getUserWorkspacesRequest.result || []; } - constructor() { - // Wire-up action handlers - workspaceActions.edit.listen(this._edit); - workspaceActions.create.listen(this._create); - workspaceActions.delete.listen(this._delete); - workspaceActions.update.listen(this._update); - workspaceActions.activate.listen(this._setActiveWorkspace); - workspaceActions.deactivate.listen(this._deactivateActiveWorkspace); - workspaceActions.toggleWorkspaceDrawer.listen(this._toggleWorkspaceDrawer); - workspaceActions.openWorkspaceSettings.listen(this._openWorkspaceSettings); - - // Register and start reactions - this._registerReactions([ - this._updateWorkspaceBeingEdited, - this._updateActiveServiceOnWorkspaceSwitch, - ]); + @computed get isUpgradeToPremiumRequired() { + return this.isFeatureEnabled && !this.isFeatureActive; } start(stores, actions) { debug('WorkspacesStore::start'); this.stores = stores; this.actions = actions; - this._reactions.forEach(r => r.start()); - this.isFeatureActive = true; + + this._listenToActions([ + [workspaceActions.edit, this._edit], + [workspaceActions.create, this._create], + [workspaceActions.delete, this._delete], + [workspaceActions.update, this._update], + [workspaceActions.activate, this._setActiveWorkspace], + [workspaceActions.deactivate, this._deactivateActiveWorkspace], + [workspaceActions.toggleWorkspaceDrawer, this._toggleWorkspaceDrawer], + [workspaceActions.openWorkspaceSettings, this._openWorkspaceSettings], + ]); + + this._startReactions([ + this._setWorkspaceBeingEditedReaction, + this._setActiveServiceOnWorkspaceSwitchReaction, + this._setFeatureEnabledReaction, + this._setIsPremiumFeatureReaction, + ]); + getUserWorkspacesRequest.execute(); + this.isFeatureActive = true; } stop() { debug('WorkspacesStore::stop'); - this._reactions.forEach(r => r.stop()); this.isFeatureActive = false; this.activeWorkspace = null; this.nextWorkspace = null; @@ -85,12 +92,6 @@ export default class WorkspacesStore { // ========== PRIVATE ========= // - _reactions = []; - - _registerReactions(reactions) { - reactions.forEach(r => this._reactions.push(new Reaction(r))); - } - _getWorkspaceById = id => this.workspaces.find(w => w.id === id); // Actions @@ -164,7 +165,17 @@ export default class WorkspacesStore { // Reactions - _updateWorkspaceBeingEdited = () => { + _setFeatureEnabledReaction = () => { + const { isWorkspaceEnabled } = this.stores.features.features; + this.isFeatureEnabled = isWorkspaceEnabled; + }; + + _setIsPremiumFeatureReaction = () => { + const { isWorkspacePremiumFeature } = this.stores.features.features; + this.isPremiumFeature = isWorkspacePremiumFeature; + }; + + _setWorkspaceBeingEditedReaction = () => { const { pathname } = this.stores.router.location; const match = matchRoute('/settings/workspaces/edit/:id', pathname); if (match) { @@ -172,7 +183,7 @@ export default class WorkspacesStore { } }; - _updateActiveServiceOnWorkspaceSwitch = () => { + _setActiveServiceOnWorkspaceSwitchReaction = () => { if (!this.isFeatureActive) return; if (this.activeWorkspace) { const services = this.stores.services.allDisplayed; diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index 659b1b361..1747e1976 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json @@ -2535,13 +2535,13 @@ "defaultMessage": "!!!Upgrade account", "end": { "column": 3, - "line": 17 + "line": 18 }, "file": "src/components/ui/PremiumFeatureContainer/index.js", "id": "premiumFeature.button.upgradeAccount", "start": { "column": 10, - "line": 14 + "line": 15 } } ], @@ -3388,78 +3388,104 @@ "defaultMessage": "!!!Your workspaces", "end": { "column": 3, - "line": 18 + "line": 20 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.headline", "start": { "column": 12, - "line": 15 + "line": 17 } }, { "defaultMessage": "!!!You haven't added any workspaces yet.", "end": { "column": 3, - "line": 22 + "line": 24 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.noWorkspacesAdded", "start": { "column": 19, - "line": 19 + "line": 21 } }, { "defaultMessage": "!!!Could not load your workspaces", "end": { "column": 3, - "line": 26 + "line": 28 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.workspacesRequestFailed", "start": { "column": 27, - "line": 23 + "line": 25 } }, { "defaultMessage": "!!!Try again", "end": { "column": 3, - "line": 30 + "line": 32 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.tryReloadWorkspaces", "start": { "column": 23, - "line": 27 + "line": 29 } }, { "defaultMessage": "!!!Your changes have been saved", "end": { "column": 3, - "line": 34 + "line": 36 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.updatedInfo", "start": { "column": 15, - "line": 31 + "line": 33 } }, { "defaultMessage": "!!!Workspace has been deleted", "end": { "column": 3, - "line": 38 + "line": 40 }, "file": "src/features/workspaces/components/WorkspacesDashboard.js", "id": "settings.workspaces.deletedInfo", "start": { "column": 15, - "line": 35 + "line": 37 + } + }, + { + "defaultMessage": "!!!Info about workspace feature", + "end": { + "column": 3, + "line": 44 + }, + "file": "src/features/workspaces/components/WorkspacesDashboard.js", + "id": "settings.workspaces.workspaceFeatureInfo", + "start": { + "column": 24, + "line": 41 + } + }, + { + "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", + "end": { + "column": 3, + "line": 48 + }, + "file": "src/features/workspaces/components/WorkspacesDashboard.js", + "id": "settings.workspaces.workspaceFeatureHeadline", + "start": { + "column": 28, + "line": 45 } } ], diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 5f7254317..987262c35 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -254,6 +254,8 @@ "settings.workspaces.noWorkspacesAdded": "You haven't added any workspaces yet.", "settings.workspaces.tryReloadWorkspaces": "Try again", "settings.workspaces.updatedInfo": "Your changes have been saved", + "settings.workspaces.workspaceFeatureHeadline": "Less is More: Introducing Franz Workspaces", + "settings.workspaces.workspaceFeatureInfo": "Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time. You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.", "settings.workspaces.workspacesRequestFailed": "Could not load your workspaces", "sidebar.addNewService": "Add new service", "sidebar.closeWorkspaceDrawer": "Close workspace drawer", diff --git a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json index 582d546fa..320d3ca3e 100644 --- a/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json +++ b/src/i18n/messages/src/components/ui/PremiumFeatureContainer/index.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Upgrade account", "file": "src/components/ui/PremiumFeatureContainer/index.js", "start": { - "line": 14, + "line": 15, "column": 10 }, "end": { - "line": 17, + "line": 18, "column": 3 } } diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json index a957358c8..ef8f1bebc 100644 --- a/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json +++ b/src/i18n/messages/src/features/workspaces/components/WorkspacesDashboard.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Your workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 15, + "line": 17, "column": 12 }, "end": { - "line": 18, + "line": 20, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!You haven't added any workspaces yet.", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 19, + "line": 21, "column": 19 }, "end": { - "line": 22, + "line": 24, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Could not load your workspaces", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 23, + "line": 25, "column": 27 }, "end": { - "line": 26, + "line": 28, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Try again", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 27, + "line": 29, "column": 23 }, "end": { - "line": 30, + "line": 32, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Your changes have been saved", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 31, + "line": 33, "column": 15 }, "end": { - "line": 34, + "line": 36, "column": 3 } }, @@ -69,11 +69,37 @@ "defaultMessage": "!!!Workspace has been deleted", "file": "src/features/workspaces/components/WorkspacesDashboard.js", "start": { - "line": 35, + "line": 37, "column": 15 }, "end": { - "line": 38, + "line": 40, + "column": 3 + } + }, + { + "id": "settings.workspaces.workspaceFeatureInfo", + "defaultMessage": "!!!Info about workspace feature", + "file": "src/features/workspaces/components/WorkspacesDashboard.js", + "start": { + "line": 41, + "column": 24 + }, + "end": { + "line": 44, + "column": 3 + } + }, + { + "id": "settings.workspaces.workspaceFeatureHeadline", + "defaultMessage": "!!!Less is More: Introducing Franz Workspaces", + "file": "src/features/workspaces/components/WorkspacesDashboard.js", + "start": { + "line": 45, + "column": 28 + }, + "end": { + "line": 48, "column": 3 } } diff --git a/src/lib/Menu.js b/src/lib/Menu.js index d19aa9d6e..a4e41c17c 100644 --- a/src/lib/Menu.js +++ b/src/lib/Menu.js @@ -323,7 +323,7 @@ const _templateFactory = intl => [ { label: intl.formatMessage(menuItems.workspaces), submenu: [], - visible: workspaceStore.isFeatureActive, + visible: workspaceStore.isFeatureEnabled, }, { label: intl.formatMessage(menuItems.window), @@ -732,7 +732,7 @@ export default class FranzMenu { tpl[3].submenu = serviceTpl; } - if (workspaceStore.isFeatureActive) { + if (workspaceStore.isFeatureEnabled) { tpl[4].submenu = this.workspacesMenu(); } diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index 2bda82e17..52e38ad96 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js @@ -1,4 +1,4 @@ -import { computed, observable, reaction } from 'mobx'; +import { computed, observable, reaction, runInAction } from 'mobx'; import Store from './lib/Store'; import CachedRequest from './lib/CachedRequest'; @@ -17,8 +17,11 @@ export default class FeaturesStore extends Store { @observable featuresRequest = new CachedRequest(this.api.features, 'features'); + @observable features = Object.assign({}, DEFAULT_FEATURES_CONFIG); + async setup() { this.registerReactions([ + this._updateFeatures, this._monitorLoginStatus.bind(this), ]); @@ -37,13 +40,16 @@ export default class FeaturesStore extends Store { return this.defaultFeaturesRequest.execute().result || DEFAULT_FEATURES_CONFIG; } - @computed get features() { + _updateFeatures = () => { + const features = Object.assign({}, DEFAULT_FEATURES_CONFIG); if (this.stores.user.isLoggedIn) { - return Object.assign({}, DEFAULT_FEATURES_CONFIG, this.featuresRequest.execute().result); + const requestResult = this.featuresRequest.execute().result; + Object.assign(features, requestResult); } - - return DEFAULT_FEATURES_CONFIG; - } + runInAction('FeaturesStore::_updateFeatures', () => { + this.features = features; + }); + }; _monitorLoginStatus() { if (this.stores.user.isLoggedIn) { -- cgit v1.2.3-70-g09d2 From 6b38abc9011648a1f54b1ef3e3fb29d13750750c Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Wed, 3 Apr 2019 16:59:24 +0200 Subject: add workspace premium badge in settings nav --- .../settings/navigation/SettingsNavigation.js | 9 +++++- src/i18n/locales/defaultMessages.json | 32 +++++++++++----------- src/i18n/locales/en-US.json | 2 +- .../settings/navigation/SettingsNavigation.json | 28 +++++++++---------- src/stores/FeaturesStore.js | 7 ++++- src/styles/settings.scss | 10 +++++++ 6 files changed, 55 insertions(+), 33 deletions(-) (limited to 'src/stores/FeaturesStore.js') diff --git a/src/components/settings/navigation/SettingsNavigation.js b/src/components/settings/navigation/SettingsNavigation.js index dc3c1d6f1..945285f5a 100644 --- a/src/components/settings/navigation/SettingsNavigation.js +++ b/src/components/settings/navigation/SettingsNavigation.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { defineMessages, intlShape } from 'react-intl'; import { inject, observer } from 'mobx-react'; +import { Icon } from '@meetfranz/ui'; import Link from '../../ui/Link'; import { workspaceStore } from '../../../features/workspaces'; @@ -77,7 +78,13 @@ export default @inject('stores') @observer class SettingsNavigation extends Comp > {intl.formatMessage(messages.yourWorkspaces)} {' '} - {workspaceCount} + {workspaceStore.isPremiumUpgradeRequired ? ( + + + + ) : ( + {workspaceCount} + )} ) : null} Franz Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time.

You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.

", "workspaces.switchingIndicator.switchingTo": "Switching to" -} +} \ No newline at end of file diff --git a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json index 96a42aa80..de78a71cf 100644 --- a/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json +++ b/src/i18n/messages/src/components/settings/navigation/SettingsNavigation.json @@ -4,11 +4,11 @@ "defaultMessage": "!!!Available services", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 10, + "line": 11, "column": 21 }, "end": { - "line": 13, + "line": 14, "column": 3 } }, @@ -17,11 +17,11 @@ "defaultMessage": "!!!Your services", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 14, + "line": 15, "column": 16 }, "end": { - "line": 17, + "line": 18, "column": 3 } }, @@ -30,11 +30,11 @@ "defaultMessage": "!!!Your workspaces", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 18, + "line": 19, "column": 18 }, "end": { - "line": 21, + "line": 22, "column": 3 } }, @@ -43,11 +43,11 @@ "defaultMessage": "!!!Account", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 22, + "line": 23, "column": 11 }, "end": { - "line": 25, + "line": 26, "column": 3 } }, @@ -56,11 +56,11 @@ "defaultMessage": "!!!Settings", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 26, + "line": 27, "column": 12 }, "end": { - "line": 29, + "line": 30, "column": 3 } }, @@ -69,11 +69,11 @@ "defaultMessage": "!!!Invite Friends", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 30, + "line": 31, "column": 17 }, "end": { - "line": 33, + "line": 34, "column": 3 } }, @@ -82,11 +82,11 @@ "defaultMessage": "!!!Logout", "file": "src/components/settings/navigation/SettingsNavigation.js", "start": { - "line": 34, + "line": 35, "column": 10 }, "end": { - "line": 37, + "line": 38, "column": 3 } } diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js index 52e38ad96..8fe576813 100644 --- a/src/stores/FeaturesStore.js +++ b/src/stores/FeaturesStore.js @@ -1,4 +1,9 @@ -import { computed, observable, reaction, runInAction } from 'mobx'; +import { + computed, + observable, + reaction, + runInAction, +} from 'mobx'; import Store from './lib/Store'; import CachedRequest from './lib/CachedRequest'; diff --git a/src/styles/settings.scss b/src/styles/settings.scss index 9fde9a7bf..d97d4ac2c 100644 --- a/src/styles/settings.scss +++ b/src/styles/settings.scss @@ -85,6 +85,11 @@ .badge { background: $dark-theme-gray-lighter; color: $dark-theme-gray-smoke; + + &.badge--pro { + background: $theme-brand-primary; + padding: 4px 6px 3px 7px; + } } &:hover { @@ -93,6 +98,11 @@ .badge { background: $dark-theme-gray-lighter; color: $dark-theme-gray-smoke; + + &.badge--pro { + background: $theme-brand-primary; + padding: 4px 6px 3px 7px; + } } } -- cgit v1.2.3-70-g09d2