aboutsummaryrefslogtreecommitdiffstats
path: root/src/features/workspaces
diff options
context:
space:
mode:
authorLibravatar vantezzen <properly@protonmail.com>2019-09-07 15:50:23 +0200
committerLibravatar vantezzen <properly@protonmail.com>2019-09-07 15:50:23 +0200
commite7a74514c1e7c3833dfdcf5900cb87f9e6e8354e (patch)
treeb8314e4155503b135dcb07e8b4a0e847e25c19cf /src/features/workspaces
parentUpdate CHANGELOG.md (diff)
parentUpdate CHANGELOG.md (diff)
downloadferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.tar.gz
ferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.tar.zst
ferdium-app-e7a74514c1e7c3833dfdcf5900cb87f9e6e8354e.zip
Merge branch 'master' of https://github.com/meetfranz/franz into franz-5.3.0
Diffstat (limited to 'src/features/workspaces')
-rw-r--r--src/features/workspaces/components/WorkspaceDrawer.js7
-rw-r--r--src/features/workspaces/components/WorkspaceSwitchingIndicator.js8
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js173
-rw-r--r--src/features/workspaces/containers/WorkspacesScreen.js2
-rw-r--r--src/features/workspaces/store.js9
5 files changed, 114 insertions, 85 deletions
diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js
index cbc7372ca..f4ee89a14 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 { workspaceStore } from '../index'; 13import { workspaceStore } from '../index';
@@ -157,7 +158,7 @@ class WorkspaceDrawer extends Component {
157 data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`} 158 data-tip={`${intl.formatMessage(messages.workspacesSettingsTooltip)}`}
158 > 159 >
159 <Icon 160 <Icon
160 icon="mdiSettings" 161 icon={mdiSettings}
161 size={1.5} 162 size={1.5}
162 className={classes.workspacesSettingsButtonIcon} 163 className={classes.workspacesSettingsButtonIcon}
163 /> 164 />
@@ -181,7 +182,7 @@ class WorkspaceDrawer extends Component {
181 className={classes.premiumCtaButton} 182 className={classes.premiumCtaButton}
182 buttonType="primary" 183 buttonType="primary"
183 label={intl.formatMessage(messages.premiumCtaButtonLabel)} 184 label={intl.formatMessage(messages.premiumCtaButtonLabel)}
184 icon="mdiPlusBox" 185 icon={mdiPlusBox}
185 onClick={() => { 186 onClick={() => {
186 workspaceActions.openWorkspaceSettings(); 187 workspaceActions.openWorkspaceSettings();
187 }} 188 }}
@@ -220,7 +221,7 @@ class WorkspaceDrawer extends Component {
220 }} 221 }}
221 > 222 >
222 <Icon 223 <Icon
223 icon="mdiPlusBox" 224 icon={mdiPlusBox}
224 size={1} 225 size={1}
225 className={classes.workspacesSettingsButtonIcon} 226 className={classes.workspacesSettingsButtonIcon}
226 /> 227 />
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}>
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 9b51f2602..977b23999 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -1,9 +1,9 @@
1import React, { Component, Fragment } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } 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,7 +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'; 14import UIStore from '../../../stores/UIStore';
15import globalMessages from '../../../i18n/globalMessages';
16import UpgradeButton from '../../../components/ui/UpgradeButton';
15 17
16const messages = defineMessages({ 18const messages = defineMessages({
17 headline: { 19 headline: {
@@ -48,7 +50,7 @@ const messages = defineMessages({
48 }, 50 },
49}); 51});
50 52
51const styles = theme => ({ 53const styles = () => ({
52 table: { 54 table: {
53 width: '100%', 55 width: '100%',
54 '& td': { 56 '& td': {
@@ -62,17 +64,28 @@ const styles = theme => ({
62 height: 'auto', 64 height: 'auto',
63 }, 65 },
64 premiumAnnouncement: { 66 premiumAnnouncement: {
65 padding: '20px',
66 backgroundColor: '#3498db',
67 marginLeft: '-20px',
68 marginBottom: '20px',
69 height: 'auto', 67 height: 'auto',
70 color: 'white', 68 },
71 borderRadius: theme.borderRadius, 69 premiumAnnouncementContainer: {
70 display: 'flex',
71 },
72 announcementHeadline: {
73 marginBottom: 0,
74 },
75 teaserImage: {
76 width: 250,
77 margin: [-8, 0, 0, 20],
78 alignSelf: 'center',
79 },
80 upgradeCTA: {
81 margin: [40, 'auto'],
82 },
83 proRequired: {
84 margin: [10, 0, 40],
72 }, 85 },
73}); 86});
74 87
75@injectSheet(styles) @observer 88@inject('stores') @injectSheet(styles) @observer
76class WorkspacesDashboard extends Component { 89class WorkspacesDashboard extends Component {
77 static propTypes = { 90 static propTypes = {
78 classes: PropTypes.object.isRequired, 91 classes: PropTypes.object.isRequired,
@@ -100,7 +113,9 @@ class WorkspacesDashboard extends Component {
100 onWorkspaceClick, 113 onWorkspaceClick,
101 workspaces, 114 workspaces,
102 } = this.props; 115 } = this.props;
116
103 const { intl } = this.context; 117 const { intl } = this.context;
118
104 return ( 119 return (
105 <div className="settings__main"> 120 <div className="settings__main">
106 <div className="settings__header"> 121 <div className="settings__header">
@@ -138,68 +153,80 @@ class WorkspacesDashboard extends Component {
138 153
139 {workspaceStore.isPremiumUpgradeRequired && ( 154 {workspaceStore.isPremiumUpgradeRequired && (
140 <div className={classes.premiumAnnouncement}> 155 <div className={classes.premiumAnnouncement}>
141 <h2>{intl.formatMessage(messages.workspaceFeatureHeadline)}</h2> 156
142 <p>{intl.formatMessage(messages.workspaceFeatureInfo)}</p> 157 <h1 className={classes.announcementHeadline}>{intl.formatMessage(messages.workspaceFeatureHeadline)}</h1>
158 <Badge className={classes.proRequired}>{intl.formatMessage(globalMessages.proRequired)}</Badge>
159 <div className={classes.premiumAnnouncementContainer}>
160 <div className={classes.premiumAnnouncementContent}>
161 <p>{intl.formatMessage(messages.workspaceFeatureInfo)}</p>
162 <UpgradeButton
163 className={classes.upgradeCTA}
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="" />
170 </div>
143 </div> 171 </div>
144 )} 172 )}
145 173
146 <PremiumFeatureContainer 174 {!workspaceStore.isPremiumUpgradeRequired && (
147 condition={workspaceStore.isPremiumFeature} 175 <>
148 gaEventInfo={{ category: 'User', event: 'upgrade', label: 'workspaces' }} 176 {/* ===== Create workspace form ===== */}
149 > 177 <div className={classes.createForm}>
150 {/* ===== Create workspace form ===== */} 178 <CreateWorkspaceForm
151 <div className={classes.createForm}> 179 isSubmitting={createWorkspaceRequest.isExecuting}
152 <CreateWorkspaceForm 180 onSubmit={onCreateWorkspaceSubmit}
153 isSubmitting={createWorkspaceRequest.isExecuting} 181 />
154 onSubmit={onCreateWorkspaceSubmit} 182 </div>
155 /> 183 {getUserWorkspacesRequest.isExecuting ? (
156 </div> 184 <Loader />
157 {getUserWorkspacesRequest.isExecuting ? ( 185 ) : (
158 <Loader /> 186 <Fragment>
159 ) : ( 187 {/* ===== Workspace could not be loaded error ===== */}
160 <Fragment> 188 {getUserWorkspacesRequest.error ? (
161 {/* ===== Workspace could not be loaded error ===== */} 189 <Infobox
162 {getUserWorkspacesRequest.error ? ( 190 icon="alert"
163 <Infobox 191 type="danger"
164 icon="alert" 192 ctaLabel={intl.formatMessage(messages.tryReloadWorkspaces)}
165 type="danger" 193 ctaLoading={getUserWorkspacesRequest.isExecuting}
166 ctaLabel={intl.formatMessage(messages.tryReloadWorkspaces)} 194 ctaOnClick={getUserWorkspacesRequest.retry}
167 ctaLoading={getUserWorkspacesRequest.isExecuting} 195 >
168 ctaOnClick={getUserWorkspacesRequest.retry} 196 {intl.formatMessage(messages.workspacesRequestFailed)}
169 > 197 </Infobox>
170 {intl.formatMessage(messages.workspacesRequestFailed)} 198 ) : (
171 </Infobox> 199 <Fragment>
172 ) : ( 200 {workspaces.length === 0 ? (
173 <Fragment> 201 <div className="align-middle settings__empty-state">
174 {workspaces.length === 0 ? ( 202 {/* ===== Workspaces empty state ===== */}
175 <div className="align-middle settings__empty-state"> 203 <p className="settings__empty-text">
176 {/* ===== Workspaces empty state ===== */} 204 <span className="emoji">
177 <p className="settings__empty-text"> 205 <img src="./assets/images/emoji/sad.png" alt="" />
178 <span className="emoji"> 206 </span>
179 <img src="./assets/images/emoji/sad.png" alt="" /> 207 {intl.formatMessage(messages.noServicesAdded)}
180 </span> 208 </p>
181 {intl.formatMessage(messages.noServicesAdded)} 209 </div>
182 </p> 210 ) : (
183 </div> 211 <table className={classes.table}>
184 ) : ( 212 {/* ===== Workspaces list ===== */}
185 <table className={classes.table}> 213 <tbody>
186 {/* ===== Workspaces list ===== */} 214 {workspaces.map(workspace => (
187 <tbody> 215 <WorkspaceItem
188 {workspaces.map(workspace => ( 216 key={workspace.id}
189 <WorkspaceItem 217 workspace={workspace}
190 key={workspace.id} 218 onItemClick={w => onWorkspaceClick(w)}
191 workspace={workspace} 219 />
192 onItemClick={w => onWorkspaceClick(w)} 220 ))}
193 /> 221 </tbody>
194 ))} 222 </table>
195 </tbody> 223 )}
196 </table> 224 </Fragment>
197 )} 225 )}
198 </Fragment> 226 </Fragment>
199 )} 227 )}
200 </Fragment> 228 </>
201 )} 229 )}
202 </PremiumFeatureContainer>
203 </div> 230 </div>
204 </div> 231 </div>
205 ); 232 );
@@ -207,3 +234,9 @@ class WorkspacesDashboard extends Component {
207} 234}
208 235
209export default WorkspacesDashboard; 236export default WorkspacesDashboard;
237
238WorkspacesDashboard.wrappedComponent.propTypes = {
239 stores: PropTypes.shape({
240 ui: PropTypes.instanceOf(UIStore).isRequired,
241 }).isRequired,
242};
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({
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js
index a82f6895c..4a1f80b4e 100644
--- a/src/features/workspaces/store.js
+++ b/src/features/workspaces/store.js
@@ -253,11 +253,10 @@ export default class WorkspacesStore extends FeatureStore {
253 }; 253 };
254 254
255 _setIsPremiumFeatureReaction = () => { 255 _setIsPremiumFeatureReaction = () => {
256 const { features, user } = this.stores; 256 const { features } = this.stores;
257 const { isPremium } = user.data; 257 const { isWorkspaceIncludedInCurrentPlan } = features.features;
258 const { isWorkspacePremiumFeature } = features.features; 258 this.isPremiumFeature = !isWorkspaceIncludedInCurrentPlan;
259 this.isPremiumFeature = isWorkspacePremiumFeature; 259 this.isPremiumUpgradeRequired = !isWorkspaceIncludedInCurrentPlan;
260 this.isPremiumUpgradeRequired = isWorkspacePremiumFeature && !isPremium;
261 }; 260 };
262 261
263 _setWorkspaceBeingEditedReaction = () => { 262 _setWorkspaceBeingEditedReaction = () => {