aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2019-09-04 11:51:28 +0200
committerLibravatar Stefan Malzner <stefan@adlk.io>2019-09-04 11:51:28 +0200
commit71544483caadbdd240f423e7660c242ef458a1d2 (patch)
tree4d0d6dc345fe3c19eb2b0f2fc340d29818e098de /src/features
parentUpdate en-US.json (diff)
downloadferdium-app-71544483caadbdd240f423e7660c242ef458a1d2.tar.gz
ferdium-app-71544483caadbdd240f423e7660c242ef458a1d2.tar.zst
ferdium-app-71544483caadbdd240f423e7660c242ef458a1d2.zip
Add pre-launch notice
Diffstat (limited to 'src/features')
-rw-r--r--src/features/todos/components/TodosWebview.js104
-rw-r--r--src/features/todos/containers/TodosScreen.js19
-rw-r--r--src/features/todos/store.js1
-rw-r--r--src/features/workspaces/components/WorkspaceDrawer.js7
-rw-r--r--src/features/workspaces/components/WorkspaceSwitchingIndicator.js8
5 files changed, 112 insertions, 27 deletions
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js
index 288c1906f..d8d96ba85 100644
--- a/src/features/todos/components/TodosWebview.js
+++ b/src/features/todos/components/TodosWebview.js
@@ -4,12 +4,31 @@ import { observer } from 'mobx-react';
4import injectSheet from 'react-jss'; 4import injectSheet from 'react-jss';
5import Webview from 'react-electron-web-view'; 5import Webview from 'react-electron-web-view';
6import { Icon } from '@meetfranz/ui'; 6import { Icon } from '@meetfranz/ui';
7import { defineMessages, intlShape } from 'react-intl';
7 8
9import { mdiChevronRight, mdiCheckAll } from '@mdi/js';
10import { Button } from '@meetfranz/forms';
8import * as environment from '../../../environment'; 11import * as environment from '../../../environment';
12import Appear from '../../../components/ui/effects/Appear';
9 13
10const OPEN_TODOS_BUTTON_SIZE = 45; 14const OPEN_TODOS_BUTTON_SIZE = 45;
11const CLOSE_TODOS_BUTTON_SIZE = 35; 15const CLOSE_TODOS_BUTTON_SIZE = 35;
12 16
17const messages = defineMessages({
18 premiumInfo: {
19 id: 'feature.todos.premium.info',
20 defaultMessage: '!!!The Franz Todos Preview is currently only available for Franz Premium accounts.',
21 },
22 upgradeCTA: {
23 id: 'feature.todos.premium.upgrade',
24 defaultMessage: '!!!Upgrade Account',
25 },
26 rolloutInfo: {
27 id: 'feature.todos.premium.rollout',
28 defaultMessage: '!!!Franz Todos will be available to everyone soon.',
29 },
30});
31
13const styles = theme => ({ 32const styles = theme => ({
14 root: { 33 root: {
15 background: theme.colorBackground, 34 background: theme.colorBackground,
@@ -78,7 +97,7 @@ const styles = theme => ({
78 bottom: 80, 97 bottom: 80,
79 right: ({ width }) => (width + -CLOSE_TODOS_BUTTON_SIZE / 2), 98 right: ({ width }) => (width + -CLOSE_TODOS_BUTTON_SIZE / 2),
80 borderRadius: CLOSE_TODOS_BUTTON_SIZE / 2, 99 borderRadius: CLOSE_TODOS_BUTTON_SIZE / 2,
81 opacity: 0, 100 opacity: ({ isTodosIncludedInCurrentPlan }) => (!isTodosIncludedInCurrentPlan ? 1 : 0),
82 transition: 'opacity 0.5s', 101 transition: 'opacity 0.5s',
83 zIndex: 600, 102 zIndex: 600,
84 display: 'flex', 103 display: 'flex',
@@ -90,6 +109,26 @@ const styles = theme => ({
90 fill: theme.todos.toggleButton.textColor, 109 fill: theme.todos.toggleButton.textColor,
91 }, 110 },
92 }, 111 },
112 premiumContainer: {
113 display: 'flex',
114 flexDirection: 'column',
115 justifyContent: 'center',
116 alignItems: 'center',
117 width: '80%',
118 maxWidth: 300,
119 margin: [-50, 'auto', 0],
120 textAlign: 'center',
121 },
122 premiumIcon: {
123 marginBottom: 40,
124 background: theme.styleTypes.primary.accent,
125 fill: theme.styleTypes.primary.contrast,
126 padding: 10,
127 borderRadius: 10,
128 },
129 premiumCTA: {
130 marginTop: 40,
131 },
93}); 132});
94 133
95@injectSheet(styles) @observer 134@injectSheet(styles) @observer
@@ -103,6 +142,8 @@ class TodosWebview extends Component {
103 resize: PropTypes.func.isRequired, 142 resize: PropTypes.func.isRequired,
104 width: PropTypes.number.isRequired, 143 width: PropTypes.number.isRequired,
105 minWidth: PropTypes.number.isRequired, 144 minWidth: PropTypes.number.isRequired,
145 isTodosIncludedInCurrentPlan: PropTypes.bool.isRequired,
146 upgradeAccount: PropTypes.func.isRequired,
106 }; 147 };
107 148
108 state = { 149 state = {
@@ -110,6 +151,10 @@ class TodosWebview extends Component {
110 width: 300, 151 width: 300,
111 }; 152 };
112 153
154 static contextTypes = {
155 intl: intlShape,
156 };
157
113 componentWillMount() { 158 componentWillMount() {
114 const { width } = this.props; 159 const { width } = this.props;
115 160
@@ -186,9 +231,20 @@ class TodosWebview extends Component {
186 231
187 render() { 232 render() {
188 const { 233 const {
189 classes, isVisible, togglePanel, 234 classes,
235 isVisible,
236 togglePanel,
237 isTodosIncludedInCurrentPlan,
238 upgradeAccount,
190 } = this.props; 239 } = this.props;
191 const { width, delta, isDragging } = this.state; 240
241 const {
242 width,
243 delta,
244 isDragging,
245 } = this.state;
246
247 const { intl } = this.context;
192 248
193 return ( 249 return (
194 <> 250 <>
@@ -203,7 +259,7 @@ class TodosWebview extends Component {
203 className={isVisible ? classes.closeTodosButton : classes.openTodosButton} 259 className={isVisible ? classes.closeTodosButton : classes.openTodosButton}
204 type="button" 260 type="button"
205 > 261 >
206 <Icon icon={isVisible ? 'mdiChevronRight' : 'mdiCheckAll'} size={2} /> 262 <Icon icon={isVisible ? mdiChevronRight : mdiCheckAll} size={2} />
207 </button> 263 </button>
208 <div 264 <div
209 className={classes.resizeHandler} 265 className={classes.resizeHandler}
@@ -216,18 +272,34 @@ class TodosWebview extends Component {
216 style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad 272 style={{ left: delta }} // This hack is required as resizing with webviews beneath behaves quite bad
217 /> 273 />
218 )} 274 )}
219 <Webview 275 {isTodosIncludedInCurrentPlan ? (
220 className={classes.webview} 276 <Webview
221 onDidAttach={() => { 277 className={classes.webview}
222 const { setTodosWebview } = this.props; 278 onDidAttach={() => {
223 setTodosWebview(this.webview); 279 const { setTodosWebview } = this.props;
224 this.startListeningToIpcMessages(); 280 setTodosWebview(this.webview);
225 }} 281 this.startListeningToIpcMessages();
226 partition="persist:todos" 282 }}
227 preload="./features/todos/preload.js" 283 partition="persist:todos"
228 ref={(webview) => { this.webview = webview ? webview.view : null; }} 284 preload="./features/todos/preload.js"
229 src={environment.TODOS_FRONTEND} 285 ref={(webview) => { this.webview = webview ? webview.view : null; }}
230 /> 286 src={environment.TODOS_FRONTEND}
287 />
288 ) : (
289 <Appear>
290 <div className={classes.premiumContainer}>
291 <Icon icon={mdiCheckAll} className={classes.premiumIcon} size={5} />
292 <p>{intl.formatMessage(messages.premiumInfo)}</p>
293 <p>{intl.formatMessage(messages.rolloutInfo)}</p>
294 <Button
295 label={intl.formatMessage(messages.upgradeCTA)}
296 className={classes.premiumCTA}
297 onClick={upgradeAccount}
298 buttonType="inverted"
299 />
300 </div>
301 </Appear>
302 )}
231 </div> 303 </div>
232 </> 304 </>
233 ); 305 );
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js
index d071d0677..7f3688828 100644
--- a/src/features/todos/containers/TodosScreen.js
+++ b/src/features/todos/containers/TodosScreen.js
@@ -1,12 +1,14 @@
1import React, { Component } from 'react'; 1import React, { Component } from 'react';
2import { observer } from 'mobx-react'; 2import { observer, inject } from 'mobx-react';
3import PropTypes from 'prop-types';
3 4
5import FeaturesStore from '../../../stores/FeaturesStore';
4import TodosWebview from '../components/TodosWebview'; 6import TodosWebview from '../components/TodosWebview';
5import ErrorBoundary from '../../../components/util/ErrorBoundary'; 7import ErrorBoundary from '../../../components/util/ErrorBoundary';
6import { TODOS_MIN_WIDTH, todosStore } from '..'; 8import { TODOS_MIN_WIDTH, todosStore } from '..';
7import { todoActions } from '../actions'; 9import { todoActions } from '../actions';
8 10
9@observer 11@inject('stores', 'actions') @observer
10class TodosScreen extends Component { 12class TodosScreen extends Component {
11 render() { 13 render() {
12 if (!todosStore || !todosStore.isFeatureActive) { 14 if (!todosStore || !todosStore.isFeatureActive) {
@@ -23,6 +25,8 @@ class TodosScreen extends Component {
23 width={todosStore.width} 25 width={todosStore.width}
24 minWidth={TODOS_MIN_WIDTH} 26 minWidth={TODOS_MIN_WIDTH}
25 resize={width => todoActions.resize({ width })} 27 resize={width => todoActions.resize({ width })}
28 isTodosIncludedInCurrentPlan={this.props.stores.features.features.isTodosIncludedInCurrentPlan || false}
29 upgradeAccount={() => this.props.actions.ui.openSettings({ path: 'user' })}
26 /> 30 />
27 </ErrorBoundary> 31 </ErrorBoundary>
28 ); 32 );
@@ -30,3 +34,14 @@ class TodosScreen extends Component {
30} 34}
31 35
32export default TodosScreen; 36export default TodosScreen;
37
38TodosScreen.wrappedComponent.propTypes = {
39 stores: PropTypes.shape({
40 features: PropTypes.instanceOf(FeaturesStore).isRequired,
41 }).isRequired,
42 actions: PropTypes.shape({
43 ui: PropTypes.shape({
44 openSettings: PropTypes.func.isRequired,
45 }).isRequired,
46 }).isRequired,
47};
diff --git a/src/features/todos/store.js b/src/features/todos/store.js
index acf95df0d..7da3b7f49 100644
--- a/src/features/todos/store.js
+++ b/src/features/todos/store.js
@@ -29,6 +29,7 @@ export default class TodoStore extends FeatureStore {
29 } 29 }
30 30
31 @computed get isTodosPanelVisible() { 31 @computed get isTodosPanelVisible() {
32 if (this.stores.services.all.length === 0) return false;
32 if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; 33 if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE;
33 34
34 return this.settings.isTodosPanelVisible; 35 return this.settings.isTodosPanelVisible;
diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js
index 684e50dd0..e7bc0b157 100644
--- a/src/features/workspaces/components/WorkspaceDrawer.js
+++ b/src/features/workspaces/components/WorkspaceDrawer.js
@@ -7,6 +7,7 @@ import { H1, Icon, ProBadge } from '@meetfranz/ui';
7import { Button } from '@meetfranz/forms/lib'; 7import { Button } from '@meetfranz/forms/lib';
8import ReactTooltip from 'react-tooltip'; 8import ReactTooltip from 'react-tooltip';
9 9
10import { mdiPlusBox, mdiSettings } from '@mdi/js';
10import WorkspaceDrawerItem from './WorkspaceDrawerItem'; 11import WorkspaceDrawerItem from './WorkspaceDrawerItem';
11import { workspaceActions } from '../actions'; 12import { workspaceActions } from '../actions';
12import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index'; 13import { GA_CATEGORY_WORKSPACES, workspaceStore } from '../index';
@@ -159,7 +160,7 @@ class WorkspaceDrawer extends Component {
159 data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`} 160 data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`}
160 > 161 >
161 <Icon 162 <Icon
162 icon="mdiSettings" 163 icon={mdiSettings}
163 size={1.5} 164 size={1.5}
164 className={classes.workspacesSettingsButtonIcon} 165 className={classes.workspacesSettingsButtonIcon}
165 /> 166 />
@@ -184,7 +185,7 @@ class WorkspaceDrawer extends Component {
184 className={classes.premiumCtaButton} 185 className={classes.premiumCtaButton}
185 buttonType="primary" 186 buttonType="primary"
186 label={intl.formatMessage(messages.premiumCtaButtonLabel)} 187 label={intl.formatMessage(messages.premiumCtaButtonLabel)}
187 icon="mdiPlusBox" 188 icon={mdiPlusBox}
188 onClick={() => { 189 onClick={() => {
189 workspaceActions.openWorkspaceSettings(); 190 workspaceActions.openWorkspaceSettings();
190 gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerPremiumCta'); 191 gaEvent(GA_CATEGORY_WORKSPACES, 'add', 'drawerPremiumCta');
@@ -227,7 +228,7 @@ class WorkspaceDrawer extends Component {
227 }} 228 }}
228 > 229 >
229 <Icon 230 <Icon
230 icon="mdiPlusBox" 231 icon={mdiPlusBox}
231 size={1} 232 size={1}
232 className={classes.workspacesSettingsButtonIcon} 233 className={classes.workspacesSettingsButtonIcon}
233 /> 234 />
diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
index c4a800a7b..a70d1d66f 100644
--- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
+++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
@@ -21,11 +21,8 @@ const styles = theme => ({
21 alignItems: 'flex-start', 21 alignItems: 'flex-start',
22 position: 'absolute', 22 position: 'absolute',
23 transition: 'width 0.5s ease', 23 transition: 'width 0.5s ease',
24 width: '100%',
25 marginTop: '20px',
26 },
27 wrapperWhenDrawerIsOpen: {
28 width: `calc(100% - ${theme.workspaces.drawer.width}px)`, 24 width: `calc(100% - ${theme.workspaces.drawer.width}px)`,
25 marginTop: '20px',
29 }, 26 },
30 component: { 27 component: {
31 background: 'rgba(20, 20, 20, 0.4)', 28 background: 'rgba(20, 20, 20, 0.4)',
@@ -64,14 +61,13 @@ class WorkspaceSwitchingIndicator extends Component {
64 render() { 61 render() {
65 const { classes, theme } = this.props; 62 const { classes, theme } = this.props;
66 const { intl } = this.context; 63 const { intl } = this.context;
67 const { isSwitchingWorkspace, isWorkspaceDrawerOpen, nextWorkspace } = workspaceStore; 64 const { isSwitchingWorkspace, nextWorkspace } = workspaceStore;
68 if (!isSwitchingWorkspace) return null; 65 if (!isSwitchingWorkspace) return null;
69 const nextWorkspaceName = nextWorkspace ? nextWorkspace.name : 'All services'; 66 const nextWorkspaceName = nextWorkspace ? nextWorkspace.name : 'All services';
70 return ( 67 return (
71 <div 68 <div
72 className={classnames([ 69 className={classnames([
73 classes.wrapper, 70 classes.wrapper,
74 isWorkspaceDrawerOpen ? classes.wrapperWhenDrawerIsOpen : null,
75 ])} 71 ])}
76 > 72 >
77 <div className={classes.component}> 73 <div className={classes.component}>