aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/workspaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/features/workspaces')
-rw-r--r--src/features/workspaces/api.js12
-rw-r--r--src/features/workspaces/components/CreateWorkspaceForm.js4
-rw-r--r--src/features/workspaces/components/EditWorkspaceForm.js28
-rw-r--r--src/features/workspaces/components/WorkspaceDrawer.js9
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js2
-rw-r--r--src/features/workspaces/containers/EditWorkspaceScreen.js4
-rw-r--r--src/features/workspaces/index.js2
-rw-r--r--src/features/workspaces/models/Workspace.js14
-rw-r--r--src/features/workspaces/store.js23
9 files changed, 63 insertions, 35 deletions
diff --git a/src/features/workspaces/api.js b/src/features/workspaces/api.js
index 0ec20c9ea..30fbd84be 100644
--- a/src/features/workspaces/api.js
+++ b/src/features/workspaces/api.js
@@ -1,14 +1,14 @@
1import { pick } from 'lodash'; 1import { pick } from 'lodash';
2import { sendAuthRequest } from '../../api/utils/auth'; 2import { sendAuthRequest } from '../../api/utils/auth';
3import { API, API_VERSION } from '../../environment';
4import Request from '../../stores/lib/Request'; 3import Request from '../../stores/lib/Request';
5import Workspace from './models/Workspace'; 4import Workspace from './models/Workspace';
5import apiBase from '../../api/apiBase';
6 6
7const debug = require('debug')('Franz:feature:workspaces:api'); 7const debug = require('debug')('Ferdi:feature:workspaces:api');
8 8
9export const workspaceApi = { 9export const workspaceApi = {
10 getUserWorkspaces: async () => { 10 getUserWorkspaces: async () => {
11 const url = `${API}/${API_VERSION}/workspace`; 11 const url = `${apiBase()}/workspace`;
12 debug('getUserWorkspaces GET', url); 12 debug('getUserWorkspaces GET', url);
13 const result = await sendAuthRequest(url, { method: 'GET' }); 13 const result = await sendAuthRequest(url, { method: 'GET' });
14 debug('getUserWorkspaces RESULT', result); 14 debug('getUserWorkspaces RESULT', result);
@@ -18,7 +18,7 @@ export const workspaceApi = {
18 }, 18 },
19 19
20 createWorkspace: async (name) => { 20 createWorkspace: async (name) => {
21 const url = `${API}/${API_VERSION}/workspace`; 21 const url = `${apiBase()}/workspace`;
22 const options = { 22 const options = {
23 method: 'POST', 23 method: 'POST',
24 body: JSON.stringify({ name }), 24 body: JSON.stringify({ name }),
@@ -31,7 +31,7 @@ export const workspaceApi = {
31 }, 31 },
32 32
33 deleteWorkspace: async (workspace) => { 33 deleteWorkspace: async (workspace) => {
34 const url = `${API}/${API_VERSION}/workspace/${workspace.id}`; 34 const url = `${apiBase()}/workspace/${workspace.id}`;
35 debug('deleteWorkspace DELETE', url); 35 debug('deleteWorkspace DELETE', url);
36 const result = await sendAuthRequest(url, { method: 'DELETE' }); 36 const result = await sendAuthRequest(url, { method: 'DELETE' });
37 debug('deleteWorkspace RESULT', result); 37 debug('deleteWorkspace RESULT', result);
@@ -40,7 +40,7 @@ export const workspaceApi = {
40 }, 40 },
41 41
42 updateWorkspace: async (workspace) => { 42 updateWorkspace: async (workspace) => {
43 const url = `${API}/${API_VERSION}/workspace/${workspace.id}`; 43 const url = `${apiBase()}/workspace/${workspace.id}`;
44 const options = { 44 const options = {
45 method: 'PUT', 45 method: 'PUT',
46 body: JSON.stringify(pick(workspace, ['name', 'services'])), 46 body: JSON.stringify(pick(workspace, ['name', 'services'])),
diff --git a/src/features/workspaces/components/CreateWorkspaceForm.js b/src/features/workspaces/components/CreateWorkspaceForm.js
index cddbb2b04..15b97121d 100644
--- a/src/features/workspaces/components/CreateWorkspaceForm.js
+++ b/src/features/workspaces/components/CreateWorkspaceForm.js
@@ -6,8 +6,7 @@ import { Input, Button } from '@meetfranz/forms';
6import injectSheet from 'react-jss'; 6import injectSheet from 'react-jss';
7import Form from '../../../lib/Form'; 7import Form from '../../../lib/Form';
8import { required } from '../../../helpers/validation-helpers'; 8import { required } from '../../../helpers/validation-helpers';
9import { gaEvent } from '../../../lib/analytics'; 9import { workspaceStore } from '../index';
10import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index';
11 10
12const messages = defineMessages({ 11const messages = defineMessages({
13 submitButton: { 12 submitButton: {
@@ -66,7 +65,6 @@ class CreateWorkspaceForm extends Component {
66 const { onSubmit } = this.props; 65 const { onSubmit } = this.props;
67 const values = f.values(); 66 const values = f.values();
68 onSubmit(values); 67 onSubmit(values);
69 gaEvent(GA_CATEGORY_WORKSPACES, 'create', values.name);
70 }, 68 },
71 }); 69 });
72 } 70 }
diff --git a/src/features/workspaces/components/EditWorkspaceForm.js b/src/features/workspaces/components/EditWorkspaceForm.js
index e602ebd5a..b3551a7b9 100644
--- a/src/features/workspaces/components/EditWorkspaceForm.js
+++ b/src/features/workspaces/components/EditWorkspaceForm.js
@@ -12,8 +12,10 @@ import Form from '../../../lib/Form';
12import { required } from '../../../helpers/validation-helpers'; 12import { required } from '../../../helpers/validation-helpers';
13import WorkspaceServiceListItem from './WorkspaceServiceListItem'; 13import WorkspaceServiceListItem from './WorkspaceServiceListItem';
14import Request from '../../../stores/lib/Request'; 14import Request from '../../../stores/lib/Request';
15import { gaEvent } from '../../../lib/analytics'; 15
16import { GA_CATEGORY_WORKSPACES } from '../index'; 16import { KEEP_WS_LOADED_USID } from '../../../config';
17
18import Toggle from '../../../components/ui/Toggle';
17 19
18const messages = defineMessages({ 20const messages = defineMessages({
19 buttonDelete: { 21 buttonDelete: {
@@ -32,6 +34,14 @@ const messages = defineMessages({
32 id: 'settings.workspace.form.yourWorkspaces', 34 id: 'settings.workspace.form.yourWorkspaces',
33 defaultMessage: '!!!Your workspaces', 35 defaultMessage: '!!!Your workspaces',
34 }, 36 },
37 keepLoaded: {
38 id: 'settings.workspace.form.keepLoaded',
39 defaultMessage: '!!!Keep this workspace loaded*',
40 },
41 keepLoadedInfo: {
42 id: 'settings.workspace.form.keepLoadedInfo',
43 defaultMessage: '!!!*This option will be overwritten by the global "Keep all workspaces loaded" option.',
44 },
35 servicesInWorkspaceHeadline: { 45 servicesInWorkspaceHeadline: {
36 id: 'settings.workspace.form.servicesInWorkspaceHeadline', 46 id: 'settings.workspace.form.servicesInWorkspaceHeadline',
37 defaultMessage: '!!!Services in this Workspace', 47 defaultMessage: '!!!Services in this Workspace',
@@ -53,6 +63,9 @@ const styles = () => ({
53 serviceList: { 63 serviceList: {
54 height: 'auto', 64 height: 'auto',
55 }, 65 },
66 keepLoadedInfo: {
67 marginBottom: '2rem !important',
68 },
56}); 69});
57 70
58@injectSheet(styles) @observer 71@injectSheet(styles) @observer
@@ -90,6 +103,11 @@ class EditWorkspaceForm extends Component {
90 value: workspace.name, 103 value: workspace.name,
91 validators: [required], 104 validators: [required],
92 }, 105 },
106 keepLoaded: {
107 label: intl.formatMessage(messages.keepLoaded),
108 value: workspace.services.includes(KEEP_WS_LOADED_USID),
109 default: false,
110 },
93 services: { 111 services: {
94 value: workspace.services.slice(), 112 value: workspace.services.slice(),
95 }, 113 },
@@ -103,7 +121,6 @@ class EditWorkspaceForm extends Component {
103 const { onSave } = this.props; 121 const { onSave } = this.props;
104 const values = f.values(); 122 const values = f.values();
105 onSave(values); 123 onSave(values);
106 gaEvent(GA_CATEGORY_WORKSPACES, 'save');
107 }, 124 },
108 onError: async () => {}, 125 onError: async () => {},
109 }); 126 });
@@ -112,7 +129,6 @@ class EditWorkspaceForm extends Component {
112 delete() { 129 delete() {
113 const { onDelete } = this.props; 130 const { onDelete } = this.props;
114 onDelete(); 131 onDelete();
115 gaEvent(GA_CATEGORY_WORKSPACES, 'delete');
116 } 132 }
117 133
118 toggleService(service) { 134 toggleService(service) {
@@ -155,6 +171,10 @@ class EditWorkspaceForm extends Component {
155 <div className="settings__body"> 171 <div className="settings__body">
156 <div className={classes.nameInput}> 172 <div className={classes.nameInput}>
157 <Input {...form.$('name').bind()} /> 173 <Input {...form.$('name').bind()} />
174 <Toggle field={form.$('keepLoaded')} />
175 <p className={classes.keepLoadedInfo}>
176 { intl.formatMessage(messages.keepLoadedInfo) }
177 </p>
158 </div> 178 </div>
159 <h2>{intl.formatMessage(messages.servicesInWorkspaceHeadline)}</h2> 179 <h2>{intl.formatMessage(messages.servicesInWorkspaceHeadline)}</h2>
160 <div className={classes.serviceList}> 180 <div className={classes.serviceList}>
diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js
index e7bc0b157..f4ee89a14 100644
--- a/src/features/workspaces/components/WorkspaceDrawer.js
+++ b/src/features/workspaces/components/WorkspaceDrawer.js
@@ -10,8 +10,7 @@ import ReactTooltip from 'react-tooltip';
10import { mdiPlusBox, mdiSettings } from '@mdi/js'; 10import { mdiPlusBox, mdiSettings } from '@mdi/js';
11import WorkspaceDrawerItem from './WorkspaceDrawerItem'; 11import WorkspaceDrawerItem from './WorkspaceDrawerItem';
12import { workspaceActions } from '../actions'; 12import { workspaceActions } from '../actions';
13import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index'; 13import { workspaceStore } from '../index';
14import { gaEvent } from '../../../lib/analytics';
15 14
16const messages = defineMessages({ 15const messages = defineMessages({
17 headline: { 16 headline: {
@@ -155,7 +154,6 @@ class WorkspaceDrawer extends Component {
155 className={classes.workspacesSettingsButton} 154 className={classes.workspacesSettingsButton}
156 onClick={() => { 155 onClick={() => {
157 workspaceActions.openWorkspaceSettings(); 156 workspaceActions.openWorkspaceSettings();
158 gaEvent(GA_CATEGORY_WORKSPACES, 'settings', 'drawerHeadline');
159 }} 157 }}
160 data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`} 158 data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`}
161 > 159 >
@@ -177,7 +175,6 @@ class WorkspaceDrawer extends Component {
177 icon="mdiStar" 175 icon="mdiStar"
178 onClick={() => { 176 onClick={() => {
179 onUpgradeAccountClick(); 177 onUpgradeAccountClick();
180 gaEvent('User', 'upgrade', 'workspaceDrawer');
181 }} 178 }}
182 /> 179 />
183 ) : ( 180 ) : (
@@ -188,7 +185,6 @@ class WorkspaceDrawer extends Component {
188 icon={mdiPlusBox} 185 icon={mdiPlusBox}
189 onClick={() => { 186 onClick={() => {
190 workspaceActions.openWorkspaceSettings(); 187 workspaceActions.openWorkspaceSettings();
191 gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerPremiumCta');
192 }} 188 }}
193 /> 189 />
194 )} 190 )}
@@ -200,7 +196,6 @@ class WorkspaceDrawer extends Component {
200 onClick={() => { 196 onClick={() => {
201 workspaceActions.deactivate(); 197 workspaceActions.deactivate();
202 workspaceActions.toggleWorkspaceDrawer(); 198 workspaceActions.toggleWorkspaceDrawer();
203 gaEvent(GA_CATEGORY_WORKSPACES, 'switch', 'drawer');
204 }} 199 }}
205 services={getServicesForWorkspace(null)} 200 services={getServicesForWorkspace(null)}
206 isActive={actualWorkspace == null} 201 isActive={actualWorkspace == null}
@@ -214,7 +209,6 @@ class WorkspaceDrawer extends Component {
214 if (actualWorkspace === workspace) return; 209 if (actualWorkspace === workspace) return;
215 workspaceActions.activate({ workspace }); 210 workspaceActions.activate({ workspace });
216 workspaceActions.toggleWorkspaceDrawer(); 211 workspaceActions.toggleWorkspaceDrawer();
217 gaEvent(GA_CATEGORY_WORKSPACES, 'switch', 'drawer');
218 }} 212 }}
219 onContextMenuEditClick={() => workspaceActions.edit({ workspace })} 213 onContextMenuEditClick={() => workspaceActions.edit({ workspace })}
220 services={getServicesForWorkspace(workspace)} 214 services={getServicesForWorkspace(workspace)}
@@ -224,7 +218,6 @@ class WorkspaceDrawer extends Component {
224 className={classes.addNewWorkspaceLabel} 218 className={classes.addNewWorkspaceLabel}
225 onClick={() => { 219 onClick={() => {
226 workspaceActions.openWorkspaceSettings(); 220 workspaceActions.openWorkspaceSettings();
227 gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerAddLabel');
228 }} 221 }}
229 > 222 >
230 <Icon 223 <Icon
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 70e213912..977b23999 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -46,7 +46,7 @@ const messages = defineMessages({
46 }, 46 },
47 workspaceFeatureHeadline: { 47 workspaceFeatureHeadline: {
48 id: 'settings.workspaces.workspaceFeatureHeadline', 48 id: 'settings.workspaces.workspaceFeatureHeadline',
49 defaultMessage: '!!!Less is More: Introducing Franz Workspaces', 49 defaultMessage: '!!!Less is More: Introducing Ferdi Workspaces',
50 }, 50 },
51}); 51});
52 52
diff --git a/src/features/workspaces/containers/EditWorkspaceScreen.js b/src/features/workspaces/containers/EditWorkspaceScreen.js
index 248b40131..7eaabc1ea 100644
--- a/src/features/workspaces/containers/EditWorkspaceScreen.js
+++ b/src/features/workspaces/containers/EditWorkspaceScreen.js
@@ -33,7 +33,9 @@ class EditWorkspaceScreen extends Component {
33 const { workspaceBeingEdited } = workspaceStore; 33 const { workspaceBeingEdited } = workspaceStore;
34 const { actions } = this.props; 34 const { actions } = this.props;
35 const workspace = new Workspace( 35 const workspace = new Workspace(
36 Object.assign({}, workspaceBeingEdited, values), 36 Object.assign({
37 saving: true,
38 }, workspaceBeingEdited, values),
37 ); 39 );
38 actions.workspaces.update({ workspace }); 40 actions.workspaces.update({ workspace });
39 }; 41 };
diff --git a/src/features/workspaces/index.js b/src/features/workspaces/index.js
index ed3e52096..560b732ab 100644
--- a/src/features/workspaces/index.js
+++ b/src/features/workspaces/index.js
@@ -2,7 +2,7 @@ import { reaction } from 'mobx';
2import WorkspacesStore from './store'; 2import WorkspacesStore from './store';
3import { resetApiRequests } from './api'; 3import { resetApiRequests } from './api';
4 4
5const debug = require('debug')('Franz:feature:workspaces'); 5const debug = require('debug')('Ferdi:feature:workspaces');
6 6
7export const GA_CATEGORY_WORKSPACES = 'Workspaces'; 7export const GA_CATEGORY_WORKSPACES = 'Workspaces';
8export const DEFAULT_SETTING_KEEP_ALL_WORKSPACES_LOADED = false; 8export const DEFAULT_SETTING_KEEP_ALL_WORKSPACES_LOADED = false;
diff --git a/src/features/workspaces/models/Workspace.js b/src/features/workspaces/models/Workspace.js
index 6c73d7095..77c4e05f4 100644
--- a/src/features/workspaces/models/Workspace.js
+++ b/src/features/workspaces/models/Workspace.js
@@ -1,5 +1,7 @@
1import { observable } from 'mobx'; 1import { observable } from 'mobx';
2 2
3import { KEEP_WS_LOADED_USID } from '../../../config';
4
3export default class Workspace { 5export default class Workspace {
4 id = null; 6 id = null;
5 7
@@ -19,7 +21,17 @@ export default class Workspace {
19 this.id = data.id; 21 this.id = data.id;
20 this.name = data.name; 22 this.name = data.name;
21 this.order = data.order; 23 this.order = data.order;
22 this.services.replace(data.services); 24
25 let services = data.services;
26 if (data.saving && data.keepLoaded) {
27 // Keep workspaces loaded
28 services.push(KEEP_WS_LOADED_USID);
29 } else if (data.saving && data.services.includes(KEEP_WS_LOADED_USID)) {
30 // Don't keep loaded
31 services = services.filter(e => e !== KEEP_WS_LOADED_USID);
32 }
33 this.services.replace(services);
34
23 this.userId = data.userId; 35 this.userId = data.userId;
24 } 36 }
25} 37}
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js
index 7f41cfc88..949f8a792 100644
--- a/src/features/workspaces/store.js
+++ b/src/features/workspaces/store.js
@@ -17,16 +17,18 @@ import { WORKSPACES_ROUTES } from './index';
17import { createReactions } from '../../stores/lib/Reaction'; 17import { createReactions } from '../../stores/lib/Reaction';
18import { createActionBindings } from '../utils/ActionBinding'; 18import { createActionBindings } from '../utils/ActionBinding';
19 19
20const debug = require('debug')('Franz:feature:workspaces:store'); 20import { KEEP_WS_LOADED_USID } from '../../config';
21
22const debug = require('debug')('Ferdi:feature:workspaces:store');
21 23
22export default class WorkspacesStore extends FeatureStore { 24export default class WorkspacesStore extends FeatureStore {
23 @observable isFeatureEnabled = false; 25 @observable isFeatureEnabled = true;
24 26
25 @observable isFeatureActive = false; 27 @observable isFeatureActive = false;
26 28
27 @observable isPremiumFeature = true; 29 @observable isPremiumFeature = false;
28 30
29 @observable isPremiumUpgradeRequired = true; 31 @observable isPremiumUpgradeRequired = false;
30 32
31 @observable activeWorkspace = null; 33 @observable activeWorkspace = null;
32 34
@@ -54,7 +56,8 @@ export default class WorkspacesStore extends FeatureStore {
54 } 56 }
55 57
56 @computed get isUserAllowedToUseFeature() { 58 @computed get isUserAllowedToUseFeature() {
57 return !this.isPremiumUpgradeRequired; 59 return true;
60 // return !this.isPremiumUpgradeRequired;
58 } 61 }
59 62
60 @computed get isAnyWorkspaceActive() { 63 @computed get isAnyWorkspaceActive() {
@@ -258,10 +261,10 @@ export default class WorkspacesStore extends FeatureStore {
258 }; 261 };
259 262
260 _setIsPremiumFeatureReaction = () => { 263 _setIsPremiumFeatureReaction = () => {
261 const { features } = this.stores; 264 // const { features } = this.stores;
262 const { isWorkspaceIncludedInCurrentPlan } = features.features; 265 // const { isWorkspaceIncludedInCurrentPlan } = features.features;
263 this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan; 266 // this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan;
264 this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan; 267 // this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan;
265 }; 268 };
266 269
267 _setWorkspaceBeingEditedReaction = () => { 270 _setWorkspaceBeingEditedReaction = () => {
@@ -326,7 +329,7 @@ export default class WorkspacesStore extends FeatureStore {
326 // Loop through all workspaces and remove invalid service ids (locally) 329 // Loop through all workspaces and remove invalid service ids (locally)
327 this.workspaces.forEach((workspace) => { 330 this.workspaces.forEach((workspace) => {
328 workspace.services.forEach((serviceId) => { 331 workspace.services.forEach((serviceId) => {
329 if (servicesHaveBeenLoaded && !services.one(serviceId)) { 332 if (servicesHaveBeenLoaded && !services.one(serviceId) && serviceId !== KEEP_WS_LOADED_USID) {
330 workspace.services.remove(serviceId); 333 workspace.services.remove(serviceId);
331 } 334 }
332 }); 335 });