aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/AppStore.js2
-rw-r--r--src/stores/FeaturesStore.js4
-rw-r--r--src/stores/ServicesStore.js39
-rw-r--r--src/stores/UserStore.js40
-rw-r--r--src/stores/index.js4
5 files changed, 87 insertions, 2 deletions
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 2ac306a2a..6054e6721 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -357,6 +357,8 @@ export default class AppStore extends Store {
357 this.locale = this._getDefaultLocale(); 357 this.locale = this._getDefaultLocale();
358 } 358 }
359 359
360 moment.locale(this.locale);
361
360 debug(`Set locale to "${this.locale}"`); 362 debug(`Set locale to "${this.locale}"`);
361 } 363 }
362 364
diff --git a/src/stores/FeaturesStore.js b/src/stores/FeaturesStore.js
index e7832088b..27334c9a2 100644
--- a/src/stores/FeaturesStore.js
+++ b/src/stores/FeaturesStore.js
@@ -16,6 +16,8 @@ import workspaces from '../features/workspaces';
16import shareFranz from '../features/shareFranz'; 16import shareFranz from '../features/shareFranz';
17import announcements from '../features/announcements'; 17import announcements from '../features/announcements';
18import settingsWS from '../features/settingsWS'; 18import settingsWS from '../features/settingsWS';
19import serviceLimit from '../features/serviceLimit';
20import communityRecipes from '../features/communityRecipes';
19 21
20import { DEFAULT_FEATURES_CONFIG } from '../config'; 22import { DEFAULT_FEATURES_CONFIG } from '../config';
21 23
@@ -75,5 +77,7 @@ export default class FeaturesStore extends Store {
75 shareFranz(this.stores, this.actions); 77 shareFranz(this.stores, this.actions);
76 announcements(this.stores, this.actions); 78 announcements(this.stores, this.actions);
77 settingsWS(this.stores, this.actions); 79 settingsWS(this.stores, this.actions);
80 serviceLimit(this.stores, this.actions);
81 communityRecipes(this.stores, this.actions);
78 } 82 }
79} 83}
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 109ac5cd7..e3b3fcf21 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -13,6 +13,8 @@ import CachedRequest from './lib/CachedRequest';
13import { matchRoute } from '../helpers/routing-helpers'; 13import { matchRoute } from '../helpers/routing-helpers';
14import { gaEvent, statsEvent } from '../lib/analytics'; 14import { gaEvent, statsEvent } from '../lib/analytics';
15import { workspaceStore } from '../features/workspaces'; 15import { workspaceStore } from '../features/workspaces';
16import { serviceLimitStore } from '../features/serviceLimit';
17import { RESTRICTION_TYPES } from '../models/Service';
16 18
17const debug = require('debug')('Franz:ServiceStore'); 19const debug = require('debug')('Franz:ServiceStore');
18 20
@@ -75,6 +77,7 @@ export default class ServicesStore extends Store {
75 this._saveActiveService.bind(this), 77 this._saveActiveService.bind(this),
76 this._logoutReaction.bind(this), 78 this._logoutReaction.bind(this),
77 this._handleMuteSettings.bind(this), 79 this._handleMuteSettings.bind(this),
80 this._restrictServiceAccess.bind(this),
78 ]); 81 ]);
79 82
80 // Just bind this 83 // Just bind this
@@ -98,7 +101,10 @@ export default class ServicesStore extends Store {
98 if (this.stores.user.isLoggedIn) { 101 if (this.stores.user.isLoggedIn) {
99 const services = this.allServicesRequest.execute().result; 102 const services = this.allServicesRequest.execute().result;
100 if (services) { 103 if (services) {
101 return observable(services.slice().slice().sort((a, b) => a.order - b.order)); 104 return observable(services.slice().slice().sort((a, b) => a.order - b.order).map((s, index) => {
105 s.index = index;
106 return s;
107 }));
102 } 108 }
103 } 109 }
104 return []; 110 return [];
@@ -153,6 +159,8 @@ export default class ServicesStore extends Store {
153 159
154 // Actions 160 // Actions
155 @action async _createService({ recipeId, serviceData, redirect = true }) { 161 @action async _createService({ recipeId, serviceData, redirect = true }) {
162 if (serviceLimitStore.userHasReachedServiceLimit) return;
163
156 const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); 164 const data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData);
157 165
158 const response = await this.createServiceRequest.execute(recipeId, data)._promise; 166 const response = await this.createServiceRequest.execute(recipeId, data)._promise;
@@ -678,6 +686,35 @@ export default class ServicesStore extends Store {
678 return serviceData; 686 return serviceData;
679 } 687 }
680 688
689 _restrictServiceAccess() {
690 const { features } = this.stores.features;
691 const { userHasReachedServiceLimit, serviceLimit } = this.stores.serviceLimit;
692
693 this.all.map((service, index) => {
694 if (userHasReachedServiceLimit) {
695 service.isServiceAccessRestricted = index >= serviceLimit;
696
697 if (service.isServiceAccessRestricted) {
698 service.restrictionType = RESTRICTION_TYPES.SERVICE_LIMIT;
699
700 debug('Restricting access to server due to service limit');
701 }
702 }
703
704 if (service.isUsingCustomUrl) {
705 service.isServiceAccessRestricted = !features.isCustomUrlIncludedInCurrentPlan;
706
707 if (service.isServiceAccessRestricted) {
708 service.restrictionType = RESTRICTION_TYPES.CUSTOM_URL;
709
710 debug('Restricting access to server due to custom url');
711 }
712 }
713
714 return service;
715 });
716 }
717
681 // Helper 718 // Helper
682 _initializeServiceRecipeInWebview(serviceId) { 719 _initializeServiceRecipeInWebview(serviceId) {
683 const service = this.one(serviceId); 720 const service = this.one(serviceId);
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index b5423af3b..e7516e6e6 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -2,12 +2,14 @@ import { observable, computed, action } from 'mobx';
2import moment from 'moment'; 2import moment from 'moment';
3import jwt from 'jsonwebtoken'; 3import jwt from 'jsonwebtoken';
4import localStorage from 'mobx-localstorage'; 4import localStorage from 'mobx-localstorage';
5import ms from 'ms';
5 6
6import { isDevMode } from '../environment'; 7import { isDevMode } from '../environment';
7import Store from './lib/Store'; 8import Store from './lib/Store';
8import Request from './lib/Request'; 9import Request from './lib/Request';
9import CachedRequest from './lib/CachedRequest'; 10import CachedRequest from './lib/CachedRequest';
10import { gaEvent } from '../lib/analytics'; 11import { gaEvent } from '../lib/analytics';
12import { sleep } from '../helpers/async-helpers';
11 13
12const debug = require('debug')('Franz:UserStore'); 14const debug = require('debug')('Franz:UserStore');
13 15
@@ -37,6 +39,8 @@ export default class UserStore extends Store {
37 39
38 @observable passwordRequest = new Request(this.api.user, 'password'); 40 @observable passwordRequest = new Request(this.api.user, 'password');
39 41
42 @observable activateTrialRequest = new Request(this.api.user, 'activateTrial');
43
40 @observable inviteRequest = new Request(this.api.user, 'invite'); 44 @observable inviteRequest = new Request(this.api.user, 'invite');
41 45
42 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); 46 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo');
@@ -57,7 +61,9 @@ export default class UserStore extends Store {
57 61
58 @observable accountType; 62 @observable accountType;
59 63
60 @observable hasCompletedSignup = null; 64 @observable hasCompletedSignup = false;
65
66 @observable hasActivatedTrial = false;
61 67
62 @observable userData = {}; 68 @observable userData = {};
63 69
@@ -77,6 +83,7 @@ export default class UserStore extends Store {
77 this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this)); 83 this.actions.user.retrievePassword.listen(this._retrievePassword.bind(this));
78 this.actions.user.logout.listen(this._logout.bind(this)); 84 this.actions.user.logout.listen(this._logout.bind(this));
79 this.actions.user.signup.listen(this._signup.bind(this)); 85 this.actions.user.signup.listen(this._signup.bind(this));
86 this.actions.user.activateTrial.listen(this._activateTrial.bind(this));
80 this.actions.user.invite.listen(this._invite.bind(this)); 87 this.actions.user.invite.listen(this._invite.bind(this));
81 this.actions.user.update.listen(this._update.bind(this)); 88 this.actions.user.update.listen(this._update.bind(this));
82 this.actions.user.resetStatus.listen(this._resetStatus.bind(this)); 89 this.actions.user.resetStatus.listen(this._resetStatus.bind(this));
@@ -87,6 +94,7 @@ export default class UserStore extends Store {
87 this.registerReactions([ 94 this.registerReactions([
88 this._requireAuthenticatedUser, 95 this._requireAuthenticatedUser,
89 this._getUserData.bind(this), 96 this._getUserData.bind(this),
97 this._resetTrialActivationState.bind(this),
90 ]); 98 ]);
91 } 99 }
92 100
@@ -199,6 +207,26 @@ export default class UserStore extends Store {
199 gaEvent('User', 'retrievePassword'); 207 gaEvent('User', 'retrievePassword');
200 } 208 }
201 209
210 @action async _activateTrial({ planId }) {
211 debug('activate trial', planId);
212
213 this.activateTrialRequest.execute({
214 plan: planId,
215 });
216
217 await this.activateTrialRequest._promise;
218
219 this.hasActivatedTrial = true;
220
221 console.log('hasActivatedTrial', this.hasActivatedTrial);
222
223 this.stores.features.featuresRequest.invalidate({ immediately: true });
224 this.stores.user.getUserInfoRequest.invalidate({ immediately: true });
225
226
227 gaEvent('User', 'activateTrial');
228 }
229
202 @action async _invite({ invites }) { 230 @action async _invite({ invites }) {
203 const data = invites.filter(invite => invite.email !== ''); 231 const data = invites.filter(invite => invite.email !== '');
204 232
@@ -318,6 +346,16 @@ export default class UserStore extends Store {
318 } 346 }
319 } 347 }
320 348
349 async _resetTrialActivationState() {
350 if (this.hasActivatedTrial) {
351 await sleep(ms('12s'));
352
353 console.log('resetting this.hasActivatedTrial', this.hasActivatedTrial);
354
355 this.hasActivatedTrial = false;
356 }
357 }
358
321 // Helpers 359 // Helpers
322 _parseToken(authToken) { 360 _parseToken(authToken) {
323 try { 361 try {
diff --git a/src/stores/index.js b/src/stores/index.js
index 1912418a2..c9ec77612 100644
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -12,6 +12,8 @@ import RequestStore from './RequestStore';
12import GlobalErrorStore from './GlobalErrorStore'; 12import GlobalErrorStore from './GlobalErrorStore';
13import { workspaceStore } from '../features/workspaces'; 13import { workspaceStore } from '../features/workspaces';
14import { announcementsStore } from '../features/announcements'; 14import { announcementsStore } from '../features/announcements';
15import { serviceLimitStore } from '../features/serviceLimit';
16import { communityRecipesStore } from '../features/communityRecipes';
15 17
16export default (api, actions, router) => { 18export default (api, actions, router) => {
17 const stores = {}; 19 const stores = {};
@@ -31,6 +33,8 @@ export default (api, actions, router) => {
31 globalError: new GlobalErrorStore(stores, api, actions), 33 globalError: new GlobalErrorStore(stores, api, actions),
32 workspaces: workspaceStore, 34 workspaces: workspaceStore,
33 announcements: announcementsStore, 35 announcements: announcementsStore,
36 serviceLimit: serviceLimitStore,
37 communityRecipes: communityRecipesStore,
34 }); 38 });
35 // Initialize all stores 39 // Initialize all stores
36 Object.keys(stores).forEach((name) => { 40 Object.keys(stores).forEach((name) => {