aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Bennett <properly@protonmail.com>2019-09-17 12:20:57 +0200
committerLibravatar GitHub <noreply@github.com>2019-09-17 12:20:57 +0200
commit4ec6e8625e9a1ea995cd1557a06c17ef0b0774bd (patch)
tree702a4a712e18befb543389aee4aabf308de03846
parentImplement #41 (diff)
parentMerge pull request #44 from kytwb/issue-37 (diff)
downloadferdium-app-4ec6e8625e9a1ea995cd1557a06c17ef0b0774bd.tar.gz
ferdium-app-4ec6e8625e9a1ea995cd1557a06c17ef0b0774bd.tar.zst
ferdium-app-4ec6e8625e9a1ea995cd1557a06c17ef0b0774bd.zip
Merge branch 'master' into issue-41
-rw-r--r--.all-contributorsrc3
-rw-r--r--.travis.yml10
-rw-r--r--README.md4
-rw-r--r--package.json2
-rw-r--r--src/config.js1
-rw-r--r--src/features/workspaces/components/EditWorkspaceForm.js24
-rw-r--r--src/features/workspaces/containers/EditWorkspaceScreen.js4
-rw-r--r--src/features/workspaces/models/Workspace.js14
-rw-r--r--src/features/workspaces/store.js4
-rw-r--r--src/i18n/locales/defaultMessages.json28
-rw-r--r--src/i18n/locales/en-US.json2
-rw-r--r--src/i18n/messages/src/features/workspaces/components/EditWorkspaceForm.json28
-rw-r--r--src/stores/ServicesStore.js31
13 files changed, 115 insertions, 40 deletions
diff --git a/.all-contributorsrc b/.all-contributorsrc
index bafe1843e..4e252f7df 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -90,7 +90,8 @@
90 "avatar_url": "https://avatars1.githubusercontent.com/u/5861826?v=4", 90 "avatar_url": "https://avatars1.githubusercontent.com/u/5861826?v=4",
91 "profile": "https://github.com/justus-saul", 91 "profile": "https://github.com/justus-saul",
92 "contributions": [ 92 "contributions": [
93 "bug" 93 "bug",
94 "ideas"
94 ] 95 ]
95 }, 96 },
96 { 97 {
diff --git a/.travis.yml b/.travis.yml
index 831f411f8..4cc941eff 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,14 +33,14 @@ deploy:
33 skip_cleanup: true 33 skip_cleanup: true
34 acl: public_read 34 acl: public_read
35 on: 35 on:
36 all_branches: true 36 tags: true
37 37
38env: 38env:
39 global: 39 global:
40 - secure: fddJzSmNYVX024jnhnFXEuAK1spEYi3y3RZdWaBtjQnzoObAxkcRW263JNpXQy+b7egnp2hSy8FvlQU+L967911F5Y70Pe3An4oI72hnS3DL4Njp2Dw5PwviwMA+X2ddWhzK4+k/JU6r8jBv1FGQ6ZjwSeaO/t8UKOsE8wDBFLRhnHqoR7QbM7zmKjzh/1oofunGbHsPOHmN4f7jBwSuSFTZltEENcQg3ZP++0NHU8UJdlpfqZOkro8v4AJMngAHeHlNtjwaAHdVv+6+kkwc4E/0Cy6YNyyBkbzipyngNY3GwnwzmNzvsfICD1TGklksjBlMQq7ld7eCiaYRNvyHVEmXJ17qlq7HhxkYgNy32hPRwb5Cv6o4M4tv8qS8UUk4W1RvBJ5fcmfZGQwGXPyQ/m85RJtrNfbYtr84jYcprTnSeji/9PuZv0f87dxELYm3DYmNUa1cgJqEdLUsEd0bMwUYNLnCSfu4ea2zxwir6LSBtJJCbGKxX87s5IOTrHkrWDe+PWd52v+UjQks7MBRlJnntTWo69Yy+ayXV1TnGVOHA5znHvPOvFlAF+y8tLGd4AGvehK1SAkf0+idmc9Q9xKk0QypT3ibjJui4D50p7sSajkzz3P2pUqOS/9HmjMfPMPN+Nl+48GU0CvB2aBGhdmp9vu54VaFzUaAGNGj4WI= 40 - secure: fddJzSmNYVX024jnhnFXEuAK1spEYi3y3RZdWaBtjQnzoObAxkcRW263JNpXQy+b7egnp2hSy8FvlQU+L967911F5Y70Pe3An4oI72hnS3DL4Njp2Dw5PwviwMA+X2ddWhzK4+k/JU6r8jBv1FGQ6ZjwSeaO/t8UKOsE8wDBFLRhnHqoR7QbM7zmKjzh/1oofunGbHsPOHmN4f7jBwSuSFTZltEENcQg3ZP++0NHU8UJdlpfqZOkro8v4AJMngAHeHlNtjwaAHdVv+6+kkwc4E/0Cy6YNyyBkbzipyngNY3GwnwzmNzvsfICD1TGklksjBlMQq7ld7eCiaYRNvyHVEmXJ17qlq7HhxkYgNy32hPRwb5Cv6o4M4tv8qS8UUk4W1RvBJ5fcmfZGQwGXPyQ/m85RJtrNfbYtr84jYcprTnSeji/9PuZv0f87dxELYm3DYmNUa1cgJqEdLUsEd0bMwUYNLnCSfu4ea2zxwir6LSBtJJCbGKxX87s5IOTrHkrWDe+PWd52v+UjQks7MBRlJnntTWo69Yy+ayXV1TnGVOHA5znHvPOvFlAF+y8tLGd4AGvehK1SAkf0+idmc9Q9xKk0QypT3ibjJui4D50p7sSajkzz3P2pUqOS/9HmjMfPMPN+Nl+48GU0CvB2aBGhdmp9vu54VaFzUaAGNGj4WI=
41 - secure: AjJvKhQ1jIloxogMdtOzJqovPQUBSA0lfHcRsmGdP8HIRKSRi9tKxCCgicTMpMWfvY7qtdexXBbl2/zl6cOhjfTYeAhNwwCg+dw7OVcE8LUn4E+gYZCYIKbNmmkVKsSckQd4h2IcyvqdqLwzjrEzdF95MoUI8WqdLwvQJLkoIaXju6ZT76FslGSUVXk58ZN7p2nr3kW8V7KclIzn/yyyYXE4bjBmS4djuvCReeSfSViCuX5CGT8avBb/IF/M5S7hcQVybmmalysOrranzSx0o9PPUIT9hHqqRpXW6iss2qVj+kCaFiC3ftlApVgizBoGcNAMA8N7hX8kkEjJSpiy7Vswuev9mVN9X94VwVZGyNvdYD8cKKxqTsfFDZDgefnuSYUhymKSBgM4yScYF6IPNJWFWJTugtVeMJ8ivqZhwJuD20nt6x7gGB1FS6m7axxRWeyp7h0FqWU9l6ZfmwHcRziVKNTk9BB4XIqco9M2wjV/YH321IGVwtVR5y6zty10+xk38TthCOidgBurFlMKbFKH5g9K5+84dhsCW0avMlJ0+QkgId0uAVyho+09Wx4cKqXLfobpznkUX+S0Um6G/NbAaUAU+SqBsm+X9CKFsPd/YJoxLdF7eBCG/3Fy4roKg3J4mBYeXe3wVnGft8Eeg0aNpOArMSStMY337UpdV80= 41 - secure: AjJvKhQ1jIloxogMdtOzJqovPQUBSA0lfHcRsmGdP8HIRKSRi9tKxCCgicTMpMWfvY7qtdexXBbl2/zl6cOhjfTYeAhNwwCg+dw7OVcE8LUn4E+gYZCYIKbNmmkVKsSckQd4h2IcyvqdqLwzjrEzdF95MoUI8WqdLwvQJLkoIaXju6ZT76FslGSUVXk58ZN7p2nr3kW8V7KclIzn/yyyYXE4bjBmS4djuvCReeSfSViCuX5CGT8avBb/IF/M5S7hcQVybmmalysOrranzSx0o9PPUIT9hHqqRpXW6iss2qVj+kCaFiC3ftlApVgizBoGcNAMA8N7hX8kkEjJSpiy7Vswuev9mVN9X94VwVZGyNvdYD8cKKxqTsfFDZDgefnuSYUhymKSBgM4yScYF6IPNJWFWJTugtVeMJ8ivqZhwJuD20nt6x7gGB1FS6m7axxRWeyp7h0FqWU9l6ZfmwHcRziVKNTk9BB4XIqco9M2wjV/YH321IGVwtVR5y6zty10+xk38TthCOidgBurFlMKbFKH5g9K5+84dhsCW0avMlJ0+QkgId0uAVyho+09Wx4cKqXLfobpznkUX+S0Um6G/NbAaUAU+SqBsm+X9CKFsPd/YJoxLdF7eBCG/3Fy4roKg3J4mBYeXe3wVnGft8Eeg0aNpOArMSStMY337UpdV80=
42 - secure: WNQBUyNvjTwMFm6pPzNXZYRvgLCTgEm93vLX/0amtr6gT6N8ZsTLL5+Ht3+v51MUOsjEe6tCM4cLSh4wSuwWcSEsUjK0jiqknlpgKKl6xLeo+1t8u6BKSgTpipWqrSD24TbvMrFUyeQrqCGRdZc3Ax/F1ERD81SXcsrg2evCL8g8zsYjxSMXc44drKrvYi68s/5ALrI+oH3t2PYsGuuP1ipj5CbaizUHEa5d8TukHRl96lxoEKCQ4Sa8UXRPNQsdb3TdkVmIEPIoioWU6AMPweBWR6Ky994aKwp0wWn1adWP49v8skMYWbirENniSxShtztF/NYqPQFyoyh0WD/C/ZJPh04HlMxnmQPUROq+LxBFz8WBY1eHDmz6GxH1lDYzneTtlRa5K8izvs2+ROhpVmmKeOgWHaL1ZRMy8Cn3V88kadF7i1K9NnqB6ZPyynJJctj7o0af6Os9/ZPqWfqIOWWeXgfXVzj17xJADfh6Z9epW95hdKZjnIf9IqGAI8aYTqhVL8DKTJ+PSGhJIOEX+ERm+0U9gMlwllwjHCDhBe42zCGuLaWZ239yD1eacM0Ko7yUM+xobiiF0FlB8VI/nBOpGdeUKNLeUfikLHILWd04AVRCNaQU67GMOHekfWdGR8tEh9I/5Y6GJR0IQL5eGmDUjSN0u/Ovss4jSEBOaXo= 42 - secure: WNQBUyNvjTwMFm6pPzNXZYRvgLCTgEm93vLX/0amtr6gT6N8ZsTLL5+Ht3+v51MUOsjEe6tCM4cLSh4wSuwWcSEsUjK0jiqknlpgKKl6xLeo+1t8u6BKSgTpipWqrSD24TbvMrFUyeQrqCGRdZc3Ax/F1ERD81SXcsrg2evCL8g8zsYjxSMXc44drKrvYi68s/5ALrI+oH3t2PYsGuuP1ipj5CbaizUHEa5d8TukHRl96lxoEKCQ4Sa8UXRPNQsdb3TdkVmIEPIoioWU6AMPweBWR6Ky994aKwp0wWn1adWP49v8skMYWbirENniSxShtztF/NYqPQFyoyh0WD/C/ZJPh04HlMxnmQPUROq+LxBFz8WBY1eHDmz6GxH1lDYzneTtlRa5K8izvs2+ROhpVmmKeOgWHaL1ZRMy8Cn3V88kadF7i1K9NnqB6ZPyynJJctj7o0af6Os9/ZPqWfqIOWWeXgfXVzj17xJADfh6Z9epW95hdKZjnIf9IqGAI8aYTqhVL8DKTJ+PSGhJIOEX+ERm+0U9gMlwllwjHCDhBe42zCGuLaWZ239yD1eacM0Ko7yUM+xobiiF0FlB8VI/nBOpGdeUKNLeUfikLHILWd04AVRCNaQU67GMOHekfWdGR8tEh9I/5Y6GJR0IQL5eGmDUjSN0u/Ovss4jSEBOaXo=
43 43
44branches: 44branches:
45 except: 45 except:
46 - i18n 46 - i18n
diff --git a/README.md b/README.md
index d6f53adac..ecfc28580 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,8 @@ You can find the installers in the [latest release](https://github.com/kytwb/fer
26- [x] [Add option to change server to a custom](https://github.com/kytwb/ferdi/wiki/Custom-Server) [ferdi-server](https://github.com/vantezzen/ferdi-server) 26- [x] [Add option to change server to a custom](https://github.com/kytwb/ferdi/wiki/Custom-Server) [ferdi-server](https://github.com/vantezzen/ferdi-server)
27- [x] Add "Private Notification"-Mode, that hides message content from notifications (as suggested in [meetfranz/franz#879](https://github.com/meetfranz/franz/issues/879)) 27- [x] Add "Private Notification"-Mode, that hides message content from notifications (as suggested in [meetfranz/franz#879](https://github.com/meetfranz/franz/issues/879))
28- [x] Add Password Lock feature to keep your messages protected. ([ferdi#41](https://github.com/kytwb/ferdi/issues/41) and [meetfranz#810](https://github.com/meetfranz/franz/issues/810)) 28- [x] Add Password Lock feature to keep your messages protected. ([ferdi#41](https://github.com/kytwb/ferdi/issues/41) and [meetfranz#810](https://github.com/meetfranz/franz/issues/810))
29- [x] [Add an option to keep individual workspaces always loaded](https://github.com/kytwb/ferdi/issues/37)
30- [x] Add an option to auto-hide the menubar ([#7](https://github.com/kytwb/ferdi/issues/7), [meetfranz#833](https://github.com/meetfranz/franz/issues/833))
29- [x] [Add CTRL+← and CTRL+→ shortcuts and menu options to go back and forward in the service browsing history](https://github.com/kytwb/ferdi/issues/39) 31- [x] [Add CTRL+← and CTRL+→ shortcuts and menu options to go back and forward in the service browsing history](https://github.com/kytwb/ferdi/issues/39)
30- [x] Add "npm run prepare-code" command for development to lint and beautify code 32- [x] Add "npm run prepare-code" command for development to lint and beautify code
31- [x] Remove "Franz is better together" popup 33- [x] Remove "Franz is better together" popup
@@ -85,7 +87,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
85 <td align="center"><a href="http://seriesgt.com"><img src="https://avatars3.githubusercontent.com/u/5977640?v=4" width="100px;" alt="ZeroCool"/><br /><sub><b>ZeroCool</b></sub></a><br /><a href="https://github.com/kytwb/ferdi/commits?author=ZeroCool940711" title="Code">💻</a> <a href="#ideas-ZeroCool940711" title="Ideas, Planning, & Feedback">🤔</a></td> 87 <td align="center"><a href="http://seriesgt.com"><img src="https://avatars3.githubusercontent.com/u/5977640?v=4" width="100px;" alt="ZeroCool"/><br /><sub><b>ZeroCool</b></sub></a><br /><a href="https://github.com/kytwb/ferdi/commits?author=ZeroCool940711" title="Code">💻</a> <a href="#ideas-ZeroCool940711" title="Ideas, Planning, & Feedback">🤔</a></td>
86 <td align="center"><a href="https://github.com/rseitbekov"><img src="https://avatars2.githubusercontent.com/u/35684439?v=4" width="100px;" alt="rseitbekov"/><br /><sub><b>rseitbekov</b></sub></a><br /><a href="https://github.com/kytwb/ferdi/commits?author=rseitbekov" title="Code">💻</a></td> 88 <td align="center"><a href="https://github.com/rseitbekov"><img src="https://avatars2.githubusercontent.com/u/35684439?v=4" width="100px;" alt="rseitbekov"/><br /><sub><b>rseitbekov</b></sub></a><br /><a href="https://github.com/kytwb/ferdi/commits?author=rseitbekov" title="Code">💻</a></td>
87 <td align="center"><a href="https://djangogigs.com/developers/peter-bittner/"><img src="https://avatars2.githubusercontent.com/u/665072?v=4" width="100px;" alt="Peter Bittner"/><br /><sub><b>Peter Bittner</b></sub></a><br /><a href="#ideas-bittner" title="Ideas, Planning, & Feedback">🤔</a></td> 89 <td align="center"><a href="https://djangogigs.com/developers/peter-bittner/"><img src="https://avatars2.githubusercontent.com/u/665072?v=4" width="100px;" alt="Peter Bittner"/><br /><sub><b>Peter Bittner</b></sub></a><br /><a href="#ideas-bittner" title="Ideas, Planning, & Feedback">🤔</a></td>
88 <td align="center"><a href="https://github.com/justus-saul"><img src="https://avatars1.githubusercontent.com/u/5861826?v=4" width="100px;" alt="Justus Saul"/><br /><sub><b>Justus Saul</b></sub></a><br /><a href="https://github.com/kytwb/ferdi/issues?q=author%3Ajustus-saul" title="Bug reports">🐛</a></td> 90 <td align="center"><a href="https://github.com/justus-saul"><img src="https://avatars1.githubusercontent.com/u/5861826?v=4" width="100px;" alt="Justus Saul"/><br /><sub><b>Justus Saul</b></sub></a><br /><a href="https://github.com/kytwb/ferdi/issues?q=author%3Ajustus-saul" title="Bug reports">🐛</a> <a href="#ideas-justus-saul" title="Ideas, Planning, & Feedback">🤔</a></td>
89 </tr> 91 </tr>
90 <tr> 92 <tr>
91 <td align="center"><a href="https://github.com/igreil"><img src="https://avatars0.githubusercontent.com/u/17239151?v=4" width="100px;" alt="igreil"/><br /><sub><b>igreil</b></sub></a><br /><a href="#ideas-igreil" title="Ideas, Planning, & Feedback">🤔</a></td> 93 <td align="center"><a href="https://github.com/igreil"><img src="https://avatars0.githubusercontent.com/u/17239151?v=4" width="100px;" alt="igreil"/><br /><sub><b>igreil</b></sub></a><br /><a href="#ideas-igreil" title="Ideas, Planning, & Feedback">🤔</a></td>
diff --git a/package.json b/package.json
index 50c3003ff..134fa691d 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
2 "name": "ferdi", 2 "name": "ferdi",
3 "productName": "Ferdi", 3 "productName": "Ferdi",
4 "appId": "com.kytwb.ferdi", 4 "appId": "com.kytwb.ferdi",
5 "version": "5.3.2", 5 "version": "5.3.3-beta.1",
6 "description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.", 6 "description": "Messaging app for WhatsApp, Slack, Telegram, HipChat, Hangouts and many many more.",
7 "copyright": "kytwb", 7 "copyright": "kytwb",
8 "main": "index.js", 8 "main": "index.js",
diff --git a/src/config.js b/src/config.js
index 77fb34d3c..d01ece849 100644
--- a/src/config.js
+++ b/src/config.js
@@ -32,6 +32,7 @@ export const DEVELOPMENT_TODOS_FRONTEND_URL = 'https://development--franz-todos.
32export const GA_ID = !isDevMode ? 'UA-74126766-10' : 'UA-74126766-12'; 32export const GA_ID = !isDevMode ? 'UA-74126766-10' : 'UA-74126766-12';
33 33
34export const DEFAULT_LOCK_PASSWORD = 'ferdi'; 34export const DEFAULT_LOCK_PASSWORD = 'ferdi';
35export const KEEP_WS_LOADED_USID = '0a0aa000-0a0a-49a0-a000-a0a0a0a0a0a0';
35 36
36export const DEFAULT_APP_SETTINGS = { 37export const DEFAULT_APP_SETTINGS = {
37 autoLaunchInBackground: false, 38 autoLaunchInBackground: false,
diff --git a/src/features/workspaces/components/EditWorkspaceForm.js b/src/features/workspaces/components/EditWorkspaceForm.js
index 82ea1b564..b3551a7b9 100644
--- a/src/features/workspaces/components/EditWorkspaceForm.js
+++ b/src/features/workspaces/components/EditWorkspaceForm.js
@@ -13,6 +13,10 @@ import { 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';
15 15
16import { KEEP_WS_LOADED_USID } from '../../../config';
17
18import Toggle from '../../../components/ui/Toggle';
19
16const messages = defineMessages({ 20const messages = defineMessages({
17 buttonDelete: { 21 buttonDelete: {
18 id: 'settings.workspace.form.buttonDelete', 22 id: 'settings.workspace.form.buttonDelete',
@@ -30,6 +34,14 @@ const messages = defineMessages({
30 id: 'settings.workspace.form.yourWorkspaces', 34 id: 'settings.workspace.form.yourWorkspaces',
31 defaultMessage: '!!!Your workspaces', 35 defaultMessage: '!!!Your workspaces',
32 }, 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 },
33 servicesInWorkspaceHeadline: { 45 servicesInWorkspaceHeadline: {
34 id: 'settings.workspace.form.servicesInWorkspaceHeadline', 46 id: 'settings.workspace.form.servicesInWorkspaceHeadline',
35 defaultMessage: '!!!Services in this Workspace', 47 defaultMessage: '!!!Services in this Workspace',
@@ -51,6 +63,9 @@ const styles = () => ({
51 serviceList: { 63 serviceList: {
52 height: 'auto', 64 height: 'auto',
53 }, 65 },
66 keepLoadedInfo: {
67 marginBottom: '2rem !important',
68 },
54}); 69});
55 70
56@injectSheet(styles) @observer 71@injectSheet(styles) @observer
@@ -88,6 +103,11 @@ class EditWorkspaceForm extends Component {
88 value: workspace.name, 103 value: workspace.name,
89 validators: [required], 104 validators: [required],
90 }, 105 },
106 keepLoaded: {
107 label: intl.formatMessage(messages.keepLoaded),
108 value: workspace.services.includes(KEEP_WS_LOADED_USID),
109 default: false,
110 },
91 services: { 111 services: {
92 value: workspace.services.slice(), 112 value: workspace.services.slice(),
93 }, 113 },
@@ -151,6 +171,10 @@ class EditWorkspaceForm extends Component {
151 <div className="settings__body"> 171 <div className="settings__body">
152 <div className={classes.nameInput}> 172 <div className={classes.nameInput}>
153 <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>
154 </div> 178 </div>
155 <h2>{intl.formatMessage(messages.servicesInWorkspaceHeadline)}</h2> 179 <h2>{intl.formatMessage(messages.servicesInWorkspaceHeadline)}</h2>
156 <div className={classes.serviceList}> 180 <div className={classes.serviceList}>
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/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 da1582a77..949f8a792 100644
--- a/src/features/workspaces/store.js
+++ b/src/features/workspaces/store.js
@@ -17,6 +17,8 @@ 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
20import { KEEP_WS_LOADED_USID } from '../../config';
21
20const debug = require('debug')('Ferdi:feature:workspaces:store'); 22const debug = require('debug')('Ferdi:feature:workspaces:store');
21 23
22export default class WorkspacesStore extends FeatureStore { 24export default class WorkspacesStore extends FeatureStore {
@@ -327,7 +329,7 @@ export default class WorkspacesStore extends FeatureStore {
327 // Loop through all workspaces and remove invalid service ids (locally) 329 // Loop through all workspaces and remove invalid service ids (locally)
328 this.workspaces.forEach((workspace) => { 330 this.workspaces.forEach((workspace) => {
329 workspace.services.forEach((serviceId) => { 331 workspace.services.forEach((serviceId) => {
330 if (servicesHaveBeenLoaded && !services.one(serviceId)) { 332 if (servicesHaveBeenLoaded && !services.one(serviceId) && serviceId !== KEEP_WS_LOADED_USID) {
331 workspace.services.remove(serviceId); 333 workspace.services.remove(serviceId);
332 } 334 }
333 }); 335 });
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json
index febdd0d53..ab1279964 100644
--- a/src/i18n/locales/defaultMessages.json
+++ b/src/i18n/locales/defaultMessages.json
@@ -4322,91 +4322,91 @@
4322 "defaultMessage": "!!!Delete workspace", 4322 "defaultMessage": "!!!Delete workspace",
4323 "end": { 4323 "end": {
4324 "column": 3, 4324 "column": 3,
4325 "line": 20 4325 "line": 24
4326 }, 4326 },
4327 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4327 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4328 "id": "settings.workspace.form.buttonDelete", 4328 "id": "settings.workspace.form.buttonDelete",
4329 "start": { 4329 "start": {
4330 "column": 16, 4330 "column": 16,
4331 "line": 17 4331 "line": 21
4332 } 4332 }
4333 }, 4333 },
4334 { 4334 {
4335 "defaultMessage": "!!!Save workspace", 4335 "defaultMessage": "!!!Save workspace",
4336 "end": { 4336 "end": {
4337 "column": 3, 4337 "column": 3,
4338 "line": 24 4338 "line": 28
4339 }, 4339 },
4340 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4340 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4341 "id": "settings.workspace.form.buttonSave", 4341 "id": "settings.workspace.form.buttonSave",
4342 "start": { 4342 "start": {
4343 "column": 14, 4343 "column": 14,
4344 "line": 21 4344 "line": 25
4345 } 4345 }
4346 }, 4346 },
4347 { 4347 {
4348 "defaultMessage": "!!!Name", 4348 "defaultMessage": "!!!Name",
4349 "end": { 4349 "end": {
4350 "column": 3, 4350 "column": 3,
4351 "line": 28 4351 "line": 32
4352 }, 4352 },
4353 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4353 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4354 "id": "settings.workspace.form.name", 4354 "id": "settings.workspace.form.name",
4355 "start": { 4355 "start": {
4356 "column": 8, 4356 "column": 8,
4357 "line": 25 4357 "line": 29
4358 } 4358 }
4359 }, 4359 },
4360 { 4360 {
4361 "defaultMessage": "!!!Your workspaces", 4361 "defaultMessage": "!!!Your workspaces",
4362 "end": { 4362 "end": {
4363 "column": 3, 4363 "column": 3,
4364 "line": 32 4364 "line": 36
4365 }, 4365 },
4366 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4366 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4367 "id": "settings.workspace.form.yourWorkspaces", 4367 "id": "settings.workspace.form.yourWorkspaces",
4368 "start": { 4368 "start": {
4369 "column": 18, 4369 "column": 18,
4370 "line": 29 4370 "line": 33
4371 } 4371 }
4372 }, 4372 },
4373 { 4373 {
4374 "defaultMessage": "!!!Services in this Workspace", 4374 "defaultMessage": "!!!Services in this Workspace",
4375 "end": { 4375 "end": {
4376 "column": 3, 4376 "column": 3,
4377 "line": 36 4377 "line": 40
4378 }, 4378 },
4379 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4379 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4380 "id": "settings.workspace.form.servicesInWorkspaceHeadline", 4380 "id": "settings.workspace.form.servicesInWorkspaceHeadline",
4381 "start": { 4381 "start": {
4382 "column": 31, 4382 "column": 31,
4383 "line": 33 4383 "line": 37
4384 } 4384 }
4385 }, 4385 },
4386 { 4386 {
4387 "defaultMessage": "!!!You haven't added any services yet.", 4387 "defaultMessage": "!!!You haven't added any services yet.",
4388 "end": { 4388 "end": {
4389 "column": 3, 4389 "column": 3,
4390 "line": 40 4390 "line": 44
4391 }, 4391 },
4392 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4392 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4393 "id": "settings.services.noServicesAdded", 4393 "id": "settings.services.noServicesAdded",
4394 "start": { 4394 "start": {
4395 "column": 19, 4395 "column": 19,
4396 "line": 37 4396 "line": 41
4397 } 4397 }
4398 }, 4398 },
4399 { 4399 {
4400 "defaultMessage": "!!!Discover services", 4400 "defaultMessage": "!!!Discover services",
4401 "end": { 4401 "end": {
4402 "column": 3, 4402 "column": 3,
4403 "line": 44 4403 "line": 48
4404 }, 4404 },
4405 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4405 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4406 "id": "settings.services.discoverServices", 4406 "id": "settings.services.discoverServices",
4407 "start": { 4407 "start": {
4408 "column": 20, 4408 "column": 20,
4409 "line": 41 4409 "line": 45
4410 } 4410 }
4411 } 4411 }
4412 ], 4412 ],
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index fb1d84cb6..122739d03 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -341,6 +341,8 @@
341 "settings.workspace.add.form.submitButton": "Create workspace", 341 "settings.workspace.add.form.submitButton": "Create workspace",
342 "settings.workspace.form.buttonDelete": "Delete workspace", 342 "settings.workspace.form.buttonDelete": "Delete workspace",
343 "settings.workspace.form.buttonSave": "Save workspace", 343 "settings.workspace.form.buttonSave": "Save workspace",
344 "settings.workspace.form.keepLoaded": "Keep this workspace loaded*",
345 "settings.workspace.form.keepLoadedInfo": "*This option will be overwritten by the global \"Keep all workspaces loaded\" option.",
344 "settings.workspace.form.name": "Name", 346 "settings.workspace.form.name": "Name",
345 "settings.workspace.form.servicesInWorkspaceHeadline": "Services in this Workspace", 347 "settings.workspace.form.servicesInWorkspaceHeadline": "Services in this Workspace",
346 "settings.workspace.form.yourWorkspaces": "Your workspaces", 348 "settings.workspace.form.yourWorkspaces": "Your workspaces",
diff --git a/src/i18n/messages/src/features/workspaces/components/EditWorkspaceForm.json b/src/i18n/messages/src/features/workspaces/components/EditWorkspaceForm.json
index 61abf8ba0..5bb13a415 100644
--- a/src/i18n/messages/src/features/workspaces/components/EditWorkspaceForm.json
+++ b/src/i18n/messages/src/features/workspaces/components/EditWorkspaceForm.json
@@ -4,11 +4,11 @@
4 "defaultMessage": "!!!Delete workspace", 4 "defaultMessage": "!!!Delete workspace",
5 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 5 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
6 "start": { 6 "start": {
7 "line": 17, 7 "line": 21,
8 "column": 16 8 "column": 16
9 }, 9 },
10 "end": { 10 "end": {
11 "line": 20, 11 "line": 24,
12 "column": 3 12 "column": 3
13 } 13 }
14 }, 14 },
@@ -17,11 +17,11 @@
17 "defaultMessage": "!!!Save workspace", 17 "defaultMessage": "!!!Save workspace",
18 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 18 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
19 "start": { 19 "start": {
20 "line": 21, 20 "line": 25,
21 "column": 14 21 "column": 14
22 }, 22 },
23 "end": { 23 "end": {
24 "line": 24, 24 "line": 28,
25 "column": 3 25 "column": 3
26 } 26 }
27 }, 27 },
@@ -30,11 +30,11 @@
30 "defaultMessage": "!!!Name", 30 "defaultMessage": "!!!Name",
31 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 31 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
32 "start": { 32 "start": {
33 "line": 25, 33 "line": 29,
34 "column": 8 34 "column": 8
35 }, 35 },
36 "end": { 36 "end": {
37 "line": 28, 37 "line": 32,
38 "column": 3 38 "column": 3
39 } 39 }
40 }, 40 },
@@ -43,11 +43,11 @@
43 "defaultMessage": "!!!Your workspaces", 43 "defaultMessage": "!!!Your workspaces",
44 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 44 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
45 "start": { 45 "start": {
46 "line": 29, 46 "line": 33,
47 "column": 18 47 "column": 18
48 }, 48 },
49 "end": { 49 "end": {
50 "line": 32, 50 "line": 36,
51 "column": 3 51 "column": 3
52 } 52 }
53 }, 53 },
@@ -56,11 +56,11 @@
56 "defaultMessage": "!!!Services in this Workspace", 56 "defaultMessage": "!!!Services in this Workspace",
57 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 57 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
58 "start": { 58 "start": {
59 "line": 33, 59 "line": 37,
60 "column": 31 60 "column": 31
61 }, 61 },
62 "end": { 62 "end": {
63 "line": 36, 63 "line": 40,
64 "column": 3 64 "column": 3
65 } 65 }
66 }, 66 },
@@ -69,11 +69,11 @@
69 "defaultMessage": "!!!You haven't added any services yet.", 69 "defaultMessage": "!!!You haven't added any services yet.",
70 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 70 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
71 "start": { 71 "start": {
72 "line": 37, 72 "line": 41,
73 "column": 19 73 "column": 19
74 }, 74 },
75 "end": { 75 "end": {
76 "line": 40, 76 "line": 44,
77 "column": 3 77 "column": 3
78 } 78 }
79 }, 79 },
@@ -82,11 +82,11 @@
82 "defaultMessage": "!!!Discover services", 82 "defaultMessage": "!!!Discover services",
83 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 83 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
84 "start": { 84 "start": {
85 "line": 41, 85 "line": 45,
86 "column": 20 86 "column": 20
87 }, 87 },
88 "end": { 88 "end": {
89 "line": 44, 89 "line": 48,
90 "column": 3 90 "column": 3
91 } 91 }
92 } 92 }
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 374daf333..f88b14983 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -14,6 +14,7 @@ import { matchRoute } from '../helpers/routing-helpers';
14import { workspaceStore } from '../features/workspaces'; 14import { workspaceStore } from '../features/workspaces';
15import { serviceLimitStore } from '../features/serviceLimit'; 15import { serviceLimitStore } from '../features/serviceLimit';
16import { RESTRICTION_TYPES } from '../models/Service'; 16import { RESTRICTION_TYPES } from '../models/Service';
17import { KEEP_WS_LOADED_USID } from '../config';
17 18
18const debug = require('debug')('Ferdi:ServiceStore'); 19const debug = require('debug')('Ferdi:ServiceStore');
19 20
@@ -124,7 +125,35 @@ export default class ServicesStore extends Store {
124 const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings; 125 const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings;
125 const services = this.allServicesRequest.execute().result || []; 126 const services = this.allServicesRequest.execute().result || [];
126 const filteredServices = showDisabledServices ? services : services.filter(service => service.isEnabled); 127 const filteredServices = showDisabledServices ? services : services.filter(service => service.isEnabled);
127 return keepAllWorkspacesLoaded ? filteredServices : workspaceStore.filterServicesByActiveWorkspace(filteredServices); 128
129 let displayedServices;
130 if (keepAllWorkspacesLoaded) {
131 // Keep all enabled services loaded
132 displayedServices = filteredServices;
133 } else {
134 // Keep all services in current workspace loaded
135 displayedServices = workspaceStore.filterServicesByActiveWorkspace(filteredServices);
136
137 // Keep all services active in workspaces that should be kept loaded
138 for (const workspace of this.stores.workspaces.workspaces) {
139 // Check if workspace needs to be kept loaded
140 if (workspace.services.includes(KEEP_WS_LOADED_USID)) {
141 // Get services for workspace
142 const serviceIDs = workspace.services.filter(i => i !== KEEP_WS_LOADED_USID);
143 const wsServices = filteredServices.filter(service => serviceIDs.includes(service.id));
144
145 displayedServices = [
146 ...displayedServices,
147 ...wsServices,
148 ];
149 }
150 }
151
152 // Make sure every service is in the list only once
153 displayedServices = displayedServices.filter((v, i, a) => a.indexOf(v) === i);
154 }
155
156 return displayedServices;
128 } 157 }
129 158
130 @computed get filtered() { 159 @computed get filtered() {