aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorLibravatar Dominik Guzei <dominik.guzei@gmail.com>2019-09-05 14:34:13 +0200
committerLibravatar Dominik Guzei <dominik.guzei@gmail.com>2019-09-05 14:34:13 +0200
commit5336eab8b279eea886d8ce6efb03bd771d65ddc8 (patch)
tree79ebdf1a60ed0f2f1c8de93c90e90d7d2f5dab47 /src/features
parentMerge branch 'feature/todos' into develop (diff)
parentFix headline spacing (diff)
downloadferdium-app-5336eab8b279eea886d8ce6efb03bd771d65ddc8.tar.gz
ferdium-app-5336eab8b279eea886d8ce6efb03bd771d65ddc8.tar.zst
ferdium-app-5336eab8b279eea886d8ce6efb03bd771d65ddc8.zip
Merge branch 'develop' of https://github.com/meetfranz/franz into develop
Diffstat (limited to 'src/features')
-rw-r--r--src/features/delayApp/Component.js1
-rw-r--r--src/features/todos/components/TodosWebview.js12
-rw-r--r--src/features/todos/store.js20
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js167
-rw-r--r--src/features/workspaces/containers/WorkspacesScreen.js2
5 files changed, 111 insertions, 91 deletions
diff --git a/src/features/delayApp/Component.js b/src/features/delayApp/Component.js
index de5653f04..6344edb89 100644
--- a/src/features/delayApp/Component.js
+++ b/src/features/delayApp/Component.js
@@ -77,7 +77,6 @@ export default @inject('stores', 'actions') @injectSheet(styles) @observer class
77 const { defaultTrialPlan } = stores.features.features; 77 const { defaultTrialPlan } = stores.features.features;
78 78
79 if (!hadSubscription) { 79 if (!hadSubscription) {
80 console.log('directly activate trial');
81 actions.user.activateTrial({ planId: defaultTrialPlan }); 80 actions.user.activateTrial({ planId: defaultTrialPlan });
82 81
83 gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature'); 82 gaEvent('DelayApp', 'subscribe_click', 'Delay App Feature');
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js
index 143955a7b..c06183e37 100644
--- a/src/features/todos/components/TodosWebview.js
+++ b/src/features/todos/components/TodosWebview.js
@@ -9,7 +9,7 @@ import { defineMessages, intlShape } from 'react-intl';
9import { mdiChevronRight, mdiCheckAll } from '@mdi/js'; 9import { mdiChevronRight, mdiCheckAll } from '@mdi/js';
10import * as environment from '../../../environment'; 10import * as environment from '../../../environment';
11import Appear from '../../../components/ui/effects/Appear'; 11import Appear from '../../../components/ui/effects/Appear';
12import ActivateTrialButton from '../../../components/ui/ActivateTrialButton'; 12import UpgradeButton from '../../../components/ui/UpgradeButton';
13 13
14const OPEN_TODOS_BUTTON_SIZE = 45; 14const OPEN_TODOS_BUTTON_SIZE = 45;
15const CLOSE_TODOS_BUTTON_SIZE = 35; 15const CLOSE_TODOS_BUTTON_SIZE = 35;
@@ -17,7 +17,7 @@ const CLOSE_TODOS_BUTTON_SIZE = 35;
17const messages = defineMessages({ 17const messages = defineMessages({
18 premiumInfo: { 18 premiumInfo: {
19 id: 'feature.todos.premium.info', 19 id: 'feature.todos.premium.info',
20 defaultMessage: '!!!The Franz Todos Preview is currently only available for Franz Premium accounts.', 20 defaultMessage: '!!!Franz Todos are available to premium users now!',
21 }, 21 },
22 upgradeCTA: { 22 upgradeCTA: {
23 id: 'feature.todos.premium.upgrade', 23 id: 'feature.todos.premium.upgrade',
@@ -25,7 +25,7 @@ const messages = defineMessages({
25 }, 25 },
26 rolloutInfo: { 26 rolloutInfo: {
27 id: 'feature.todos.premium.rollout', 27 id: 'feature.todos.premium.rollout',
28 defaultMessage: '!!!Franz Todos will be available to everyone soon.', 28 defaultMessage: '!!!Everyone else will have to wait a little longer.',
29 }, 29 },
30}); 30});
31 31
@@ -112,7 +112,7 @@ const styles = theme => ({
112 alignItems: 'center', 112 alignItems: 'center',
113 width: '80%', 113 width: '80%',
114 maxWidth: 300, 114 maxWidth: 300,
115 margin: [-50, 'auto', 0], 115 margin: [0, 'auto'],
116 textAlign: 'center', 116 textAlign: 'center',
117 }, 117 },
118 premiumIcon: { 118 premiumIcon: {
@@ -281,10 +281,10 @@ class TodosWebview extends Component {
281 ) : ( 281 ) : (
282 <Appear> 282 <Appear>
283 <div className={classes.premiumContainer}> 283 <div className={classes.premiumContainer}>
284 <Icon icon={mdiCheckAll} className={classes.premiumIcon} size={5} /> 284 <Icon icon={mdiCheckAll} className={classes.premiumIcon} size={4} />
285 <p>{intl.formatMessage(messages.premiumInfo)}</p> 285 <p>{intl.formatMessage(messages.premiumInfo)}</p>
286 <p>{intl.formatMessage(messages.rolloutInfo)}</p> 286 <p>{intl.formatMessage(messages.rolloutInfo)}</p>
287 <ActivateTrialButton 287 <UpgradeButton
288 className={classes.premiumCTA} 288 className={classes.premiumCTA}
289 gaEventInfo={{ category: 'Todos', event: 'upgrade' }} 289 gaEventInfo={{ category: 'Todos', event: 'upgrade' }}
290 short 290 short
diff --git a/src/features/todos/store.js b/src/features/todos/store.js
index 170408ebb..aebe0dcbe 100644
--- a/src/features/todos/store.js
+++ b/src/features/todos/store.js
@@ -30,7 +30,7 @@ export default class TodoStore extends FeatureStore {
30 } 30 }
31 31
32 @computed get isTodosPanelVisible() { 32 @computed get isTodosPanelVisible() {
33 if (this.stores.services.all.length === 0 || delayAppState.isDelayAppScreenVisible) return false; 33 if (delayAppState.isDelayAppScreenVisible) return false;
34 if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; 34 if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE;
35 35
36 return this.settings.isTodosPanelVisible; 36 return this.settings.isTodosPanelVisible;
@@ -62,6 +62,7 @@ export default class TodoStore extends FeatureStore {
62 this._allReactions = createReactions([ 62 this._allReactions = createReactions([
63 this._setFeatureEnabledReaction, 63 this._setFeatureEnabledReaction,
64 this._updateTodosConfig, 64 this._updateTodosConfig,
65 this._firstLaunchReaction,
65 ]); 66 ]);
66 67
67 this._registerReactions(this._allReactions); 68 this._registerReactions(this._allReactions);
@@ -156,5 +157,20 @@ export default class TodoStore extends FeatureStore {
156 _updateTodosConfig = () => { 157 _updateTodosConfig = () => {
157 // Resend the config if any part changes in Franz: 158 // Resend the config if any part changes in Franz:
158 this._onTodosClientInitialized(); 159 this._onTodosClientInitialized();
159 } 160 };
161
162 _firstLaunchReaction = () => {
163 const { stats } = this.stores.settings.all;
164
165 // Hide todos layer on first app start but show on second
166 if (stats.appStarts <= 1) {
167 this._updateSettings({
168 isTodosPanelVisible: false,
169 });
170 } else if (stats.appStarts <= 2) {
171 this._updateSettings({
172 isTodosPanelVisible: true,
173 });
174 }
175 };
160} 176}
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 059a681de..70e213912 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react'; 3import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 4import { defineMessages, intlShape } from 'react-intl';
5import injectSheet from 'react-jss'; 5import injectSheet from 'react-jss';
6import { Infobox } from '@meetfranz/ui'; 6import { Infobox, Badge } from '@meetfranz/ui';
7 7
8import Loader from '../../../components/ui/Loader'; 8import Loader from '../../../components/ui/Loader';
9import WorkspaceItem from './WorkspaceItem'; 9import WorkspaceItem from './WorkspaceItem';
@@ -11,9 +11,9 @@ import CreateWorkspaceForm from './CreateWorkspaceForm';
11import Request from '../../../stores/lib/Request'; 11import Request from '../../../stores/lib/Request';
12import Appear from '../../../components/ui/effects/Appear'; 12import Appear from '../../../components/ui/effects/Appear';
13import { workspaceStore } from '../index'; 13import { workspaceStore } from '../index';
14import PremiumFeatureContainer from '../../../components/ui/PremiumFeatureContainer';
15import UIStore from '../../../stores/UIStore'; 14import UIStore from '../../../stores/UIStore';
16import ActivateTrialButton from '../../../components/ui/ActivateTrialButton'; 15import globalMessages from '../../../i18n/globalMessages';
16import UpgradeButton from '../../../components/ui/UpgradeButton';
17 17
18const messages = defineMessages({ 18const messages = defineMessages({
19 headline: { 19 headline: {
@@ -50,7 +50,7 @@ const messages = defineMessages({
50 }, 50 },
51}); 51});
52 52
53const styles = theme => ({ 53const styles = () => ({
54 table: { 54 table: {
55 width: '100%', 55 width: '100%',
56 '& td': { 56 '& td': {
@@ -64,23 +64,24 @@ const styles = theme => ({
64 height: 'auto', 64 height: 'auto',
65 }, 65 },
66 premiumAnnouncement: { 66 premiumAnnouncement: {
67 padding: 20,
68 // backgroundColor: '#3498db',
69 marginLeft: -20,
70 marginBottom: 40,
71 paddingBottom: 40,
72 height: 'auto', 67 height: 'auto',
68 },
69 premiumAnnouncementContainer: {
73 display: 'flex', 70 display: 'flex',
74 borderBottom: [1, 'solid', theme.inputBackground], 71 },
72 announcementHeadline: {
73 marginBottom: 0,
75 }, 74 },
76 teaserImage: { 75 teaserImage: {
77 width: 200, 76 width: 250,
78 height: '100%', 77 margin: [-8, 0, 0, 20],
79 float: 'left', 78 alignSelf: 'center',
80 margin: [-8, 0, 0, -20],
81 }, 79 },
82 upgradeCTA: { 80 upgradeCTA: {
83 marginTop: 20, 81 margin: [40, 'auto'],
82 },
83 proRequired: {
84 margin: [10, 0, 40],
84 }, 85 },
85}); 86});
86 87
@@ -152,76 +153,80 @@ class WorkspacesDashboard extends Component {
152 153
153 {workspaceStore.isPremiumUpgradeRequired && ( 154 {workspaceStore.isPremiumUpgradeRequired && (
154 <div className={classes.premiumAnnouncement}> 155 <div className={classes.premiumAnnouncement}>
155 <img src={`./assets/images/workspaces/teaser_${this.props.stores.ui.isDarkThemeActive ? 'dark' : 'light'}.png`} className={classes.teaserImage} alt="" /> 156
156 <div> 157 <h1 className={classes.announcementHeadline}>{intl.formatMessage(messages.workspaceFeatureHeadline)}</h1>
157 <h2>{intl.formatMessage(messages.workspaceFeatureHeadline)}</h2> 158 <Badge className={classes.proRequired}>{intl.formatMessage(globalMessages.proRequired)}</Badge>
158 <p>{intl.formatMessage(messages.workspaceFeatureInfo)}</p> 159 <div className={classes.premiumAnnouncementContainer}>
159 <ActivateTrialButton 160 <div className={classes.premiumAnnouncementContent}>
160 className={classes.upgradeCTA} 161 <p>{intl.formatMessage(messages.workspaceFeatureInfo)}</p>
161 gaEventInfo={{ category: 'Workspaces', event: 'upgrade' }} 162 <UpgradeButton
162 short 163 className={classes.upgradeCTA}
163 /> 164 gaEventInfo={{ category: 'Workspaces', event: 'upgrade' }}
165 short
166 requiresPro
167 />
168 </div>
169 <img src={`https://cdn.franzinfra.com/announcements/assets/workspaces_${this.props.stores.ui.isDarkThemeActive ? 'dark' : 'light'}.png`} className={classes.teaserImage} alt="" />
164 </div> 170 </div>
165 </div> 171 </div>
166 )} 172 )}
167 173
168 <PremiumFeatureContainer 174 {!workspaceStore.isPremiumUpgradeRequired && (
169 condition={() => workspaceStore.isPremiumUpgradeRequired} 175 <>
170 gaEventInfo={{ category: 'User', event: 'upgrade', label: 'workspaces' }} 176 {/* ===== Create workspace form ===== */}
171 > 177 <div className={classes.createForm}>
172 {/* ===== Create workspace form ===== */} 178 <CreateWorkspaceForm
173 <div className={classes.createForm}> 179 isSubmitting={createWorkspaceRequest.isExecuting}
174 <CreateWorkspaceForm 180 onSubmit={onCreateWorkspaceSubmit}
175 isSubmitting={createWorkspaceRequest.isExecuting} 181 />
176 onSubmit={onCreateWorkspaceSubmit} 182 </div>
177 /> 183 {getUserWorkspacesRequest.isExecuting ? (
178 </div> 184 <Loader />
179 {getUserWorkspacesRequest.isExecuting ? ( 185 ) : (
180 <Loader /> 186 <Fragment>
181 ) : ( 187 {/* ===== Workspace could not be loaded error ===== */}
182 <Fragment> 188 {getUserWorkspacesRequest.error ? (
183 {/* ===== Workspace could not be loaded error ===== */} 189 <Infobox
184 {getUserWorkspacesRequest.error ? ( 190 icon="alert"
185 <Infobox 191 type="danger"
186 icon="alert" 192 ctaLabel={intl.formatMessage(messages.tryReloadWorkspaces)}
187 type="danger" 193 ctaLoading={getUserWorkspacesRequest.isExecuting}
188 ctaLabel={intl.formatMessage(messages.tryReloadWorkspaces)} 194 ctaOnClick={getUserWorkspacesRequest.retry}
189 ctaLoading={getUserWorkspacesRequest.isExecuting} 195 >
190 ctaOnClick={getUserWorkspacesRequest.retry} 196 {intl.formatMessage(messages.workspacesRequestFailed)}
191 > 197 </Infobox>
192 {intl.formatMessage(messages.workspacesRequestFailed)} 198 ) : (
193 </Infobox> 199 <Fragment>
194 ) : ( 200 {workspaces.length === 0 ? (
195 <Fragment> 201 <div className="align-middle settings__empty-state">
196 {workspaces.length === 0 ? ( 202 {/* ===== Workspaces empty state ===== */}
197 <div className="align-middle settings__empty-state"> 203 <p className="settings__empty-text">
198 {/* ===== Workspaces empty state ===== */} 204 <span className="emoji">
199 <p className="settings__empty-text"> 205 <img src="./assets/images/emoji/sad.png" alt="" />
200 <span className="emoji"> 206 </span>
201 <img src="./assets/images/emoji/sad.png" alt="" /> 207 {intl.formatMessage(messages.noServicesAdded)}
202 </span> 208 </p>
203 {intl.formatMessage(messages.noServicesAdded)} 209 </div>
204 </p> 210 ) : (
205 </div> 211 <table className={classes.table}>
206 ) : ( 212 {/* ===== Workspaces list ===== */}
207 <table className={classes.table}> 213 <tbody>
208 {/* ===== Workspaces list ===== */} 214 {workspaces.map(workspace => (
209 <tbody> 215 <WorkspaceItem
210 {workspaces.map(workspace => ( 216 key={workspace.id}
211 <WorkspaceItem 217 workspace={workspace}
212 key={workspace.id} 218 onItemClick={w => onWorkspaceClick(w)}
213 workspace={workspace} 219 />
214 onItemClick={w => onWorkspaceClick(w)} 220 ))}
215 /> 221 </tbody>
216 ))} 222 </table>
217 </tbody> 223 )}
218 </table> 224 </Fragment>
219 )} 225 )}
220 </Fragment> 226 </Fragment>
221 )} 227 )}
222 </Fragment> 228 </>
223 )} 229 )}
224 </PremiumFeatureContainer>
225 </div> 230 </div>
226 </div> 231 </div>
227 ); 232 );
diff --git a/src/features/workspaces/containers/WorkspacesScreen.js b/src/features/workspaces/containers/WorkspacesScreen.js
index 2ab565fa1..affbd230d 100644
--- a/src/features/workspaces/containers/WorkspacesScreen.js
+++ b/src/features/workspaces/containers/WorkspacesScreen.js
@@ -11,7 +11,7 @@ import {
11 updateWorkspaceRequest, 11 updateWorkspaceRequest,
12} from '../api'; 12} from '../api';
13 13
14@inject('actions') @observer 14@inject('stores', 'actions') @observer
15class WorkspacesScreen extends Component { 15class WorkspacesScreen extends Component {
16 static propTypes = { 16 static propTypes = {
17 actions: PropTypes.shape({ 17 actions: PropTypes.shape({