aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
diff options
context:
space:
mode:
authorLibravatar Markus Hatvan <markus_hatvan@aon.at>2021-09-04 17:03:53 +0200
committerLibravatar GitHub <noreply@github.com>2021-09-04 17:03:53 +0200
commitf39cbe7d803245702885b308ab1cee4551aea9a1 (patch)
tree56d2e5dbe6242bb64b03ba5028b8bac39ea0c7ed /src/features
parentUse namespaces when pulling docker base images since this is reqd for podman (diff)
downloadferdium-app-f39cbe7d803245702885b308ab1cee4551aea9a1.tar.gz
ferdium-app-f39cbe7d803245702885b308ab1cee4551aea9a1.tar.zst
ferdium-app-f39cbe7d803245702885b308ab1cee4551aea9a1.zip
chore: remove what's new functionality (#1864)
Diffstat (limited to 'src/features')
-rw-r--r--src/features/announcements/actions.js10
-rw-r--r--src/features/announcements/api.js35
-rw-r--r--src/features/announcements/components/AnnouncementScreen.js300
-rw-r--r--src/features/announcements/constants.js5
-rw-r--r--src/features/announcements/index.js29
-rw-r--r--src/features/announcements/store.js148
-rw-r--r--src/features/todos/store.js79
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js14
8 files changed, 54 insertions, 566 deletions
diff --git a/src/features/announcements/actions.js b/src/features/announcements/actions.js
deleted file mode 100644
index bab496314..000000000
--- a/src/features/announcements/actions.js
+++ /dev/null
@@ -1,10 +0,0 @@
1import PropTypes from 'prop-types';
2import { createActionsFromDefinitions } from '../../actions/lib/actions';
3
4export const announcementActions = createActionsFromDefinitions({
5 show: {
6 targetVersion: PropTypes.string,
7 },
8}, PropTypes.checkPropTypes);
9
10export default announcementActions;
diff --git a/src/features/announcements/api.js b/src/features/announcements/api.js
deleted file mode 100644
index 962f3e694..000000000
--- a/src/features/announcements/api.js
+++ /dev/null
@@ -1,35 +0,0 @@
1import Request from '../../stores/lib/Request';
2import apiBase from '../../api/apiBase';
3import { GITHUB_FERDI_REPO_NAME, GITHUB_NIGHTLIES_REPO_NAME, GITHUB_ORG_NAME } from '../../config';
4import { ferdiVersion } from '../../environment';
5
6const debug = require('debug')('Ferdi:feature:announcements:api');
7
8export const announcementsApi = {
9 async getCurrentVersion() {
10 debug('getting current version of electron app');
11 return Promise.resolve(ferdiVersion);
12 },
13
14 async getChangelog(version) {
15 const ferdiRepoName = version.includes('nightly') ? GITHUB_NIGHTLIES_REPO_NAME : GITHUB_FERDI_REPO_NAME;
16 const url = `https://api.github.com/repos/${GITHUB_ORG_NAME}/${ferdiRepoName}/releases/tags/v${version}`;
17 debug(`fetching release changelog from Github url: ${url}`);
18 const request = await window.fetch(url, { method: 'GET' });
19 if (!request.ok) return null;
20 const data = await request.json();
21 return data.body;
22 },
23
24 async getAnnouncement(version) {
25 const url = `${apiBase()}/announcements/${version}`;
26 debug(`fetching release announcement from api url: ${url}`);
27 const response = await window.fetch(url, { method: 'GET' });
28 if (!response.ok) return null;
29 return response.json();
30 },
31};
32
33export const getCurrentVersionRequest = new Request(announcementsApi, 'getCurrentVersion');
34export const getChangelogRequest = new Request(announcementsApi, 'getChangelog');
35export const getAnnouncementRequest = new Request(announcementsApi, 'getAnnouncement');
diff --git a/src/features/announcements/components/AnnouncementScreen.js b/src/features/announcements/components/AnnouncementScreen.js
deleted file mode 100644
index 315843db3..000000000
--- a/src/features/announcements/components/AnnouncementScreen.js
+++ /dev/null
@@ -1,300 +0,0 @@
1import React, { Component } from 'react';
2import marked from 'marked';
3import PropTypes from 'prop-types';
4import { inject, observer } from 'mobx-react';
5import { defineMessages, intlShape } from 'react-intl';
6import injectSheet from 'react-jss';
7import { Button } from '@meetfranz/forms';
8
9import { announcementsStore } from '../index';
10import UIStore from '../../../stores/UIStore';
11import AppStore from '../../../stores/AppStore';
12
13const renderer = new marked.Renderer();
14
15renderer.link = (href, title, text) => `<a target="_blank" href="${href}" title="${title}">${text}</a>`;
16
17const markedOptions = { sanitize: true, renderer };
18
19const messages = defineMessages({
20 headline: {
21 id: 'feature.announcements.changelog.headline',
22 defaultMessage: '!!!Changes in Ferdi {version}',
23 },
24});
25
26const smallScreen = '1000px';
27
28const styles = (theme) => ({
29 container: {
30 background: theme.colorBackground,
31 position: 'relative',
32 top: 0,
33 zIndex: 140,
34 width: '100%',
35 height: '100%',
36 overflowY: 'auto',
37 },
38 headline: {
39 color: theme.colorHeadline,
40 margin: [25, 0, 40],
41 // 'max-width': 500,
42 'text-align': 'center',
43 'line-height': '1.3em',
44 },
45 announcement: {
46 height: 'auto',
47
48 [`@media(min-width: ${smallScreen})`]: {
49 display: 'flex',
50 flexDirection: 'column',
51 justifyContent: 'center',
52 height: '100vh',
53 },
54 },
55 main: {
56 display: 'flex',
57 flexDirection: 'column',
58 flexGrow: 1,
59 justifyContent: 'center',
60
61 '& h1': {
62 margin: [40, 0, 15],
63 fontSize: 70,
64 color: theme.styleTypes.primary.accent,
65 textAlign: 'center',
66
67 [`@media(min-width: ${smallScreen})`]: {
68 marginTop: 0,
69 },
70 },
71 '& h2': {
72 fontSize: 30,
73 fontWeight: 300,
74 color: theme.colorText,
75 textAlign: 'center',
76 marginBottom: 60,
77 },
78 },
79 mainBody: {
80 display: 'flex',
81 flexDirection: 'column',
82 alignItems: 'center',
83 width: 'calc(100% - 80px)',
84 height: 'auto',
85 margin: '0 auto',
86 [`@media(min-width: ${smallScreen})`]: {
87 flexDirection: 'row',
88 justifyContent: 'center',
89 },
90 },
91 mainImage: {
92 minWidth: 250,
93 maxWidth: 400,
94 margin: '0 auto',
95 marginBottom: 40,
96 '& img': {
97 width: '100%',
98 },
99 [`@media(min-width: ${smallScreen})`]: {
100 margin: 0,
101 },
102 },
103 mainText: {
104 height: 'auto',
105 maxWidth: 600,
106 textAlign: 'center',
107 '& p': {
108 lineHeight: '1.5em',
109 },
110 [`@media(min-width: ${smallScreen})`]: {
111 textAlign: 'left',
112 },
113 },
114 mainCtaButton: {
115 textAlign: 'center',
116 marginTop: 40,
117 [`@media(min-width: ${smallScreen})`]: {
118 textAlign: 'left',
119 },
120 },
121 spotlight: {
122 height: 'auto',
123 background: theme.announcements.spotlight.background,
124 padding: [40, 0],
125 marginTop: 80,
126 [`@media(min-width: ${smallScreen})`]: {
127 marginTop: 0,
128 justifyContent: 'center',
129 alignItems: 'flex-start',
130 display: 'flex',
131 flexDirection: 'row',
132 },
133 },
134 spotlightTopicContainer: {
135 textAlign: 'center',
136 marginBottom: 20,
137
138 [`@media(min-width: ${smallScreen})`]: {
139 marginBottom: 0,
140 minWidth: 250,
141 maxWidth: 330,
142 width: '100%',
143 textAlign: 'right',
144 marginRight: 60,
145 },
146 },
147 spotlightContentContainer: {
148 textAlign: 'center',
149 [`@media(min-width: ${smallScreen})`]: {
150 height: 'auto',
151 maxWidth: 600,
152 paddingRight: 40,
153 textAlign: 'left',
154 },
155 '& p': {
156 lineHeight: '1.5em',
157 },
158 },
159 spotlightTopic: {
160 fontSize: 20,
161 marginBottom: 5,
162 letterSpacing: 0,
163 fontWeight: 100,
164 },
165 spotlightSubject: {
166 fontSize: 20,
167 },
168 changelog: {
169 padding: [0, 60],
170 maxWidth: 700,
171 margin: [100, 'auto'],
172 height: 'auto',
173
174 '& h3': {
175 fontSize: '24px',
176 margin: '1.5em 0 1em 0',
177 },
178 '& li': {
179 marginBottom: '1em',
180 lineHeight: '1.4em',
181 },
182 '& div': {
183 height: 'auto',
184 },
185 },
186});
187
188@inject('stores', 'actions') @injectSheet(styles) @observer
189class AnnouncementScreen extends Component {
190 static propTypes = {
191 classes: PropTypes.object.isRequired,
192 stores: PropTypes.shape({
193 ui: PropTypes.instanceOf(UIStore).isRequired,
194 }).isRequired,
195 actions: PropTypes.shape({
196 app: PropTypes.instanceOf(AppStore).isRequired,
197 }).isRequired,
198 };
199
200 static contextTypes = {
201 intl: intlShape,
202 };
203
204 render() {
205 const { classes, stores, actions } = this.props;
206 const { intl } = this.context;
207 const { changelog, announcement } = announcementsStore;
208 const themeImage = stores.ui.isDarkThemeActive ? 'dark' : 'light';
209 return (
210 <div className={classes.container}>
211 {announcement && (
212 <div className={classes.announcement}>
213 <div className={classes.main}>
214 <h1>{announcement.main.headline}</h1>
215 <h2>{announcement.main.subHeadline}</h2>
216 <div className={classes.mainBody}>
217 <div className={classes.mainImage}>
218 <img
219 src={announcement.main.image[themeImage]}
220 alt=""
221 />
222 </div>
223 <div className={classes.mainText}>
224 <div
225 dangerouslySetInnerHTML={{
226 __html: marked(announcement.main.text, markedOptions),
227 }}
228 />
229 {(announcement.main.cta.label || announcement.main.cta.href) && (
230 <div className={classes.mainCtaButton}>
231 <Button
232 label={announcement.main.cta.label}
233 onClick={() => {
234 const {
235 href,
236 } = announcement.main.cta;
237 if (announcement.main.cta.href.startsWith('http')) {
238 actions.app.openExternalUrl({ url: href });
239 } else {
240 window.location.href = `#${href}`;
241 }
242 }}
243 />
244 </div>
245 )}
246 </div>
247 </div>
248 </div>
249 {announcement.spotlight && (
250 <div className={classes.spotlight}>
251 <div className={classes.spotlightTopicContainer}>
252 <h2 className={classes.spotlightTopic}>{announcement.spotlight.title}</h2>
253 <h3 className={classes.spotlightSubject}>{announcement.spotlight.subject}</h3>
254 </div>
255 <div className={classes.spotlightContentContainer}>
256 <div
257 dangerouslySetInnerHTML={{
258 __html: marked(announcement.spotlight.text, markedOptions),
259 }}
260 />
261 <div className={classes.mainCtaButton}>
262 <Button
263 label={announcement.spotlight.cta.label}
264 onClick={() => {
265 const {
266 href,
267 } = announcement.spotlight.cta;
268 if (announcement.spotlight.cta.href.startsWith('http')) {
269 actions.app.openExternalUrl({ url: href });
270 } else {
271 window.location.href = `#${href}`;
272 }
273 }}
274 />
275 </div>
276 </div>
277 </div>
278 )}
279 </div>
280 )}
281 {changelog && (
282 <div className={classes.changelog}>
283 <h1 className={classes.headline}>
284 {intl.formatMessage(messages.headline, {
285 version: announcementsStore.targetVersion,
286 })}
287 </h1>
288 <div
289 dangerouslySetInnerHTML={{
290 __html: marked(changelog, markedOptions),
291 }}
292 />
293 </div>
294 )}
295 </div>
296 );
297 }
298}
299
300export default AnnouncementScreen;
diff --git a/src/features/announcements/constants.js b/src/features/announcements/constants.js
deleted file mode 100644
index 284226fdf..000000000
--- a/src/features/announcements/constants.js
+++ /dev/null
@@ -1,5 +0,0 @@
1export const ANNOUNCEMENTS_ROUTES = {
2 TARGET: '/announcements/:id',
3};
4
5export const GA_CATEGORY_ANNOUNCEMENTS = 'Announcements';
diff --git a/src/features/announcements/index.js b/src/features/announcements/index.js
deleted file mode 100644
index 19930c5b1..000000000
--- a/src/features/announcements/index.js
+++ /dev/null
@@ -1,29 +0,0 @@
1import { reaction } from 'mobx';
2import { AnnouncementsStore } from './store';
3
4const debug = require('debug')('Ferdi:feature:announcements');
5
6export const GA_CATEGORY_ANNOUNCEMENTS = 'Announcements';
7
8export const announcementsStore = new AnnouncementsStore();
9
10export default function initAnnouncements(stores, actions) {
11 const { features } = stores;
12
13 // Toggle announcement feature
14 reaction(
15 () => (
16 features.features.isAnnouncementsEnabled
17 ),
18 (isEnabled) => {
19 if (isEnabled) {
20 debug('Initializing `announcements` feature');
21 announcementsStore.start(stores, actions);
22 } else if (announcementsStore.isFeatureActive) {
23 debug('Disabling `announcements` feature');
24 announcementsStore.stop();
25 }
26 },
27 { fireImmediately: true },
28 );
29}
diff --git a/src/features/announcements/store.js b/src/features/announcements/store.js
deleted file mode 100644
index 794d20142..000000000
--- a/src/features/announcements/store.js
+++ /dev/null
@@ -1,148 +0,0 @@
1import {
2 action,
3 computed,
4 observable,
5} from 'mobx';
6import semver from 'semver';
7import localStorage from 'mobx-localstorage';
8
9import { FeatureStore } from '../utils/FeatureStore';
10import { ANNOUNCEMENTS_ROUTES } from './constants';
11import { getAnnouncementRequest, getChangelogRequest, getCurrentVersionRequest } from './api';
12import { announcementActions } from './actions';
13import { createActionBindings } from '../utils/ActionBinding';
14import { createReactions } from '../../stores/lib/Reaction';
15import { matchRoute } from '../../helpers/routing-helpers';
16import { DEFAULT_APP_SETTINGS } from '../../environment';
17
18const LOCAL_STORAGE_KEY = 'announcements';
19
20const debug = require('debug')('Ferdi:feature:announcements:store');
21
22export class AnnouncementsStore extends FeatureStore {
23 @observable targetVersion = null;
24
25 @observable isFeatureActive = false;
26
27 @computed get changelog() {
28 return getChangelogRequest.result;
29 }
30
31 @computed get announcement() {
32 if (!this.stores || !getAnnouncementRequest.result) return null;
33 const { locale } = this.stores.app;
34 const announcement = getAnnouncementRequest.result;
35 // User locale
36 if (announcement[locale]) return announcement[locale];
37 // Default locale
38 if (announcement[DEFAULT_APP_SETTINGS.fallbackLocale]) return announcement[DEFAULT_APP_SETTINGS.fallbackLocale];
39 // No locales specified
40 return announcement;
41 }
42
43 @computed get areNewsAvailable() {
44 const isChangelogAvailable = getChangelogRequest.wasExecuted && !!this.changelog;
45 const isAnnouncementAvailable = getAnnouncementRequest.wasExecuted && !!this.announcement;
46 return isChangelogAvailable || isAnnouncementAvailable;
47 }
48
49 @computed get settings() {
50 return localStorage.getItem(LOCAL_STORAGE_KEY) || {};
51 }
52
53 @computed get lastSeenAnnouncementVersion() {
54 return this.settings.lastSeenAnnouncementVersion || null;
55 }
56
57 @computed get currentVersion() {
58 return getCurrentVersionRequest.result;
59 }
60
61 @computed get isNewUser() {
62 return this.stores.settings.stats.appStarts <= 1;
63 }
64
65 @computed get isAnnouncementShown() {
66 const { router } = this.stores;
67 return router.location.pathname.includes('/announcements');
68 }
69
70 async start(stores, actions) {
71 debug('AnnouncementsStore::start');
72 this.stores = stores;
73 this.actions = actions;
74 getCurrentVersionRequest.execute();
75
76 this._registerActions(createActionBindings([
77 [announcementActions.show, this._showAnnouncement],
78 ]));
79
80 this._reactions = createReactions([
81 this._showAnnouncementOnRouteMatch,
82 this._showAnnouncementToUsersWhoUpdatedApp,
83 this._fetchAnnouncements,
84 ]);
85 this._registerReactions(this._reactions);
86 this.isFeatureActive = true;
87 }
88
89 stop() {
90 super.stop();
91 debug('AnnouncementsStore::stop');
92 this.isFeatureActive = false;
93 }
94
95 // ======= HELPERS ======= //
96
97 _updateSettings = (changes) => {
98 localStorage.setItem(LOCAL_STORAGE_KEY, {
99 ...this.settings,
100 ...changes,
101 });
102 };
103
104 // ======= ACTIONS ======= //
105
106 @action _showAnnouncement = ({ targetVersion } = {}) => {
107 const { router } = this.stores;
108 this.targetVersion = targetVersion || this.currentVersion;
109 this._updateSettings({
110 lastSeenAnnouncementVersion: this.currentVersion,
111 });
112 const targetRoute = `/announcements/${this.targetVersion}`;
113 if (router.location.pathname !== targetRoute) {
114 this.stores.router.push(targetRoute);
115 }
116 };
117
118 // ======= REACTIONS ========
119
120 _showAnnouncementToUsersWhoUpdatedApp = () => {
121 const { announcement, isNewUser } = this;
122 // Check if there is an announcement and don't show announcements to new users
123 if (!announcement || isNewUser) return;
124
125 // Check if the user has already used current version (= has seen the announcement)
126 const { currentVersion, lastSeenAnnouncementVersion } = this;
127 if (semver.gt(currentVersion, lastSeenAnnouncementVersion || '0.0.0')) {
128 debug(`${currentVersion} > ${lastSeenAnnouncementVersion}: announcement is shown`);
129 this._showAnnouncement();
130 }
131 };
132
133 _fetchAnnouncements = () => {
134 const targetVersion = this.targetVersion || this.currentVersion;
135 if (!targetVersion) return;
136 getChangelogRequest.reset().execute(targetVersion);
137 getAnnouncementRequest.reset().execute(targetVersion);
138 };
139
140 _showAnnouncementOnRouteMatch = () => {
141 const { router } = this.stores;
142 const match = matchRoute(ANNOUNCEMENTS_ROUTES.TARGET, router.location.pathname);
143 if (match) {
144 const targetVersion = match.id;
145 this._showAnnouncement({ targetVersion });
146 }
147 }
148}
diff --git a/src/features/todos/store.js b/src/features/todos/store.js
index f283c1e59..ec06c279d 100644
--- a/src/features/todos/store.js
+++ b/src/features/todos/store.js
@@ -1,9 +1,5 @@
1import { ThemeType } from '@meetfranz/theme'; 1import { ThemeType } from '@meetfranz/theme';
2import { 2import { computed, action, observable } from 'mobx';
3 computed,
4 action,
5 observable,
6} from 'mobx';
7import localStorage from 'mobx-localstorage'; 3import localStorage from 'mobx-localstorage';
8 4
9import { todoActions } from './actions'; 5import { todoActions } from './actions';
@@ -44,12 +40,13 @@ export default class TodoStore extends FeatureStore {
44 } 40 }
45 41
46 @computed get isTodosPanelForceHidden() { 42 @computed get isTodosPanelForceHidden() {
47 const { isAnnouncementShown } = this.stores.announcements; 43 return !this.isFeatureEnabledByUser;
48 return !this.isFeatureEnabledByUser || isAnnouncementShown;
49 } 44 }
50 45
51 @computed get isTodosPanelVisible() { 46 @computed get isTodosPanelVisible() {
52 if (this.settings.isTodosPanelVisible === undefined) return DEFAULT_TODOS_VISIBLE; 47 if (this.settings.isTodosPanelVisible === undefined) {
48 return DEFAULT_TODOS_VISIBLE;
49 }
53 return this.settings.isTodosPanelVisible; 50 return this.settings.isTodosPanelVisible;
54 } 51 }
55 52
@@ -66,7 +63,10 @@ export default class TodoStore extends FeatureStore {
66 } 63 }
67 64
68 @computed get isUsingPredefinedTodoServer() { 65 @computed get isUsingPredefinedTodoServer() {
69 return this.stores && this.stores.settings.app.predefinedTodoServer !== CUSTOM_TODO_SERVICE; 66 return (
67 this.stores &&
68 this.stores.settings.app.predefinedTodoServer !== CUSTOM_TODO_SERVICE
69 );
70 } 70 }
71 71
72 @computed get todoUrl() { 72 @computed get todoUrl() {
@@ -79,12 +79,17 @@ export default class TodoStore extends FeatureStore {
79 } 79 }
80 80
81 @computed get isTodoUrlValid() { 81 @computed get isTodoUrlValid() {
82 return !this.isUsingPredefinedTodoServer || isValidExternalURL(this.todoUrl); 82 return (
83 !this.isUsingPredefinedTodoServer || isValidExternalURL(this.todoUrl)
84 );
83 } 85 }
84 86
85 @computed get todoRecipeId() { 87 @computed get todoRecipeId() {
86 if (this.isFeatureEnabledByUser && this.isUsingPredefinedTodoServer 88 if (
87 && this.todoUrl in TODO_SERVICE_RECIPE_IDS) { 89 this.isFeatureEnabledByUser &&
90 this.isUsingPredefinedTodoServer &&
91 this.todoUrl in TODO_SERVICE_RECIPE_IDS
92 ) {
88 return TODO_SERVICE_RECIPE_IDS[this.todoUrl]; 93 return TODO_SERVICE_RECIPE_IDS[this.todoUrl];
89 } 94 }
90 return null; 95 return null;
@@ -99,16 +104,21 @@ export default class TodoStore extends FeatureStore {
99 104
100 // ACTIONS 105 // ACTIONS
101 106
102 this._registerActions(createActionBindings([ 107 this._registerActions(
103 [todoActions.resize, this._resize], 108 createActionBindings([
104 [todoActions.toggleTodosPanel, this._toggleTodosPanel], 109 [todoActions.resize, this._resize],
105 [todoActions.setTodosWebview, this._setTodosWebview], 110 [todoActions.toggleTodosPanel, this._toggleTodosPanel],
106 [todoActions.handleHostMessage, this._handleHostMessage], 111 [todoActions.setTodosWebview, this._setTodosWebview],
107 [todoActions.handleClientMessage, this._handleClientMessage], 112 [todoActions.handleHostMessage, this._handleHostMessage],
108 [todoActions.toggleTodosFeatureVisibility, this._toggleTodosFeatureVisibility], 113 [todoActions.handleClientMessage, this._handleClientMessage],
109 [todoActions.openDevTools, this._openDevTools], 114 [
110 [todoActions.reload, this._reload], 115 todoActions.toggleTodosFeatureVisibility,
111 ])); 116 this._toggleTodosFeatureVisibility,
117 ],
118 [todoActions.openDevTools, this._openDevTools],
119 [todoActions.reload, this._reload],
120 ]),
121 );
112 122
113 // REACTIONS 123 // REACTIONS
114 124
@@ -133,7 +143,7 @@ export default class TodoStore extends FeatureStore {
133 143
134 // ========== PRIVATE METHODS ========= // 144 // ========== PRIVATE METHODS ========= //
135 145
136 _updateSettings = (changes) => { 146 _updateSettings = changes => {
137 localStorage.setItem('todos', { 147 localStorage.setItem('todos', {
138 ...this.settings, 148 ...this.settings,
139 ...changes, 149 ...changes,
@@ -162,7 +172,7 @@ export default class TodoStore extends FeatureStore {
162 } 172 }
163 }; 173 };
164 174
165 @action _handleHostMessage = (message) => { 175 @action _handleHostMessage = message => {
166 debug('_handleHostMessage', message); 176 debug('_handleHostMessage', message);
167 if (message.action === 'todos:create') { 177 if (message.action === 'todos:create') {
168 this.webview.send(IPC.TODOS_HOST_CHANNEL, message); 178 this.webview.send(IPC.TODOS_HOST_CHANNEL, message);
@@ -172,11 +182,18 @@ export default class TodoStore extends FeatureStore {
172 @action _handleClientMessage = ({ channel, message = {} }) => { 182 @action _handleClientMessage = ({ channel, message = {} }) => {
173 debug('_handleClientMessage', channel, message); 183 debug('_handleClientMessage', channel, message);
174 switch (message.action) { 184 switch (message.action) {
175 case 'todos:initialized': this._onTodosClientInitialized(); break; 185 case 'todos:initialized':
176 case 'todos:goToService': this._goToService(message.data); break; 186 this._onTodosClientInitialized();
187 break;
188 case 'todos:goToService':
189 this._goToService(message.data);
190 break;
177 default: 191 default:
178 debug('Other message received', channel, message); 192 debug('Other message received', channel, message);
179 console.log('this.stores.services.isTodosServiceAdded', this.stores.services.isTodosServiceAdded); 193 console.log(
194 'this.stores.services.isTodosServiceAdded',
195 this.stores.services.isTodosServiceAdded,
196 );
180 if (this.stores.services.isTodosServiceAdded) { 197 if (this.stores.services.isTodosServiceAdded) {
181 this.actions.service.handleIPCMessage({ 198 this.actions.service.handleIPCMessage({
182 serviceId: this.stores.services.isTodosServiceAdded.id, 199 serviceId: this.stores.services.isTodosServiceAdded.id,
@@ -189,7 +206,7 @@ export default class TodoStore extends FeatureStore {
189 206
190 _handleNewWindowEvent = ({ url }) => { 207 _handleNewWindowEvent = ({ url }) => {
191 this.actions.app.openExternalUrl({ url }); 208 this.actions.app.openExternalUrl({ url });
192 } 209 };
193 210
194 @action _toggleTodosFeatureVisibility = () => { 211 @action _toggleTodosFeatureVisibility = () => {
195 debug('_toggleTodosFeatureVisibility'); 212 debug('_toggleTodosFeatureVisibility');
@@ -204,14 +221,14 @@ export default class TodoStore extends FeatureStore {
204 221
205 const webview = document.querySelector('#todos-panel webview'); 222 const webview = document.querySelector('#todos-panel webview');
206 if (webview) webview.openDevTools(); 223 if (webview) webview.openDevTools();
207 } 224 };
208 225
209 _reload = () => { 226 _reload = () => {
210 debug('_reload'); 227 debug('_reload');
211 228
212 const webview = document.querySelector('#todos-panel webview'); 229 const webview = document.querySelector('#todos-panel webview');
213 if (webview) webview.reload(); 230 if (webview) webview.reload();
214 } 231 };
215 232
216 // Todos client message handlers 233 // Todos client message handlers
217 234
@@ -291,5 +308,5 @@ export default class TodoStore extends FeatureStore {
291 }); 308 });
292 } 309 }
293 } 310 }
294 } 311 };
295} 312}
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 8319d3bc6..5f34204f1 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -20,7 +20,7 @@ const messages = defineMessages({
20 }, 20 },
21 noServicesAdded: { 21 noServicesAdded: {
22 id: 'settings.workspaces.noWorkspacesAdded', 22 id: 'settings.workspaces.noWorkspacesAdded',
23 defaultMessage: '!!!You haven\'t created any workspaces yet.', 23 defaultMessage: "!!!You haven't created any workspaces yet.",
24 }, 24 },
25 workspacesRequestFailed: { 25 workspacesRequestFailed: {
26 id: 'settings.workspaces.workspacesRequestFailed', 26 id: 'settings.workspaces.workspacesRequestFailed',
@@ -61,9 +61,6 @@ const styles = () => ({
61 appear: { 61 appear: {
62 height: 'auto', 62 height: 'auto',
63 }, 63 },
64 announcementHeadline: {
65 marginBottom: 0,
66 },
67 teaserImage: { 64 teaserImage: {
68 width: 250, 65 width: 250,
69 margin: [-8, 0, 0, 20], 66 margin: [-8, 0, 0, 20],
@@ -71,7 +68,9 @@ const styles = () => ({
71 }, 68 },
72}); 69});
73 70
74@inject('stores') @injectSheet(styles) @observer 71@inject('stores')
72@injectSheet(styles)
73@observer
75class WorkspacesDashboard extends Component { 74class WorkspacesDashboard extends Component {
76 static propTypes = { 75 static propTypes = {
77 classes: PropTypes.object.isRequired, 76 classes: PropTypes.object.isRequired,
@@ -108,7 +107,6 @@ class WorkspacesDashboard extends Component {
108 <h1>{intl.formatMessage(messages.headline)}</h1> 107 <h1>{intl.formatMessage(messages.headline)}</h1>
109 </div> 108 </div>
110 <div className="settings__body"> 109 <div className="settings__body">
111
112 {/* ===== Workspace updated info ===== */} 110 {/* ===== Workspace updated info ===== */}
113 {updateWorkspaceRequest.wasExecuted && updateWorkspaceRequest.result && ( 111 {updateWorkspaceRequest.wasExecuted && updateWorkspaceRequest.result && (
114 <Appear className={classes.appear}> 112 <Appear className={classes.appear}>
@@ -175,11 +173,11 @@ class WorkspacesDashboard extends Component {
175 <table className={classes.table}> 173 <table className={classes.table}>
176 {/* ===== Workspaces list ===== */} 174 {/* ===== Workspaces list ===== */}
177 <tbody> 175 <tbody>
178 {workspaces.map((workspace) => ( 176 {workspaces.map(workspace => (
179 <WorkspaceItem 177 <WorkspaceItem
180 key={workspace.id} 178 key={workspace.id}
181 workspace={workspace} 179 workspace={workspace}
182 onItemClick={(w) => onWorkspaceClick(w)} 180 onItemClick={w => onWorkspaceClick(w)}
183 /> 181 />
184 ))} 182 ))}
185 </tbody> 183 </tbody>