aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/config.js2
-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
10 files changed, 107 insertions, 32 deletions
diff --git a/README.md b/README.md
index 9326aab39..7cd3d4808 100644
--- a/README.md
+++ b/README.md
@@ -25,6 +25,8 @@ You can find the installers in the [latest release](https://github.com/kytwb/fer
25- [x] Makes all users Premium by default 25- [x] Makes all users Premium by default
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 an option keep individual workspaces always loaded](https://github.com/kytwb/ferdi/issues/37)
29- [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))
28- [x] Remove "Franz is better together" popup 30- [x] Remove "Franz is better together" popup
29- [x] [Makes it possible to edit the "Franz Todo" server](https://github.com/kytwb/ferdi/wiki/Custom-Todo) 31- [x] [Makes it possible to edit the "Franz Todo" server](https://github.com/kytwb/ferdi/wiki/Custom-Todo)
30- [x] Makes RocketChat self-hosted generally available 32- [x] Makes RocketChat self-hosted generally available
diff --git a/src/config.js b/src/config.js
index 66789f2a4..f9689b3ff 100644
--- a/src/config.js
+++ b/src/config.js
@@ -31,6 +31,8 @@ export const DEVELOPMENT_TODOS_FRONTEND_URL = 'https://development--franz-todos.
31 31
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 KEEP_WS_LOADED_USID = '0a0aa000-0a0a-49a0-a000-a0a0a0a0a0a0';
35
34export const DEFAULT_APP_SETTINGS = { 36export const DEFAULT_APP_SETTINGS = {
35 autoLaunchInBackground: false, 37 autoLaunchInBackground: false,
36 runInBackground: true, 38 runInBackground: true,
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 907f519b0..7fce61486 100644
--- a/src/i18n/locales/defaultMessages.json
+++ b/src/i18n/locales/defaultMessages.json
@@ -4187,91 +4187,91 @@
4187 "defaultMessage": "!!!Delete workspace", 4187 "defaultMessage": "!!!Delete workspace",
4188 "end": { 4188 "end": {
4189 "column": 3, 4189 "column": 3,
4190 "line": 20 4190 "line": 24
4191 }, 4191 },
4192 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4192 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4193 "id": "settings.workspace.form.buttonDelete", 4193 "id": "settings.workspace.form.buttonDelete",
4194 "start": { 4194 "start": {
4195 "column": 16, 4195 "column": 16,
4196 "line": 17 4196 "line": 21
4197 } 4197 }
4198 }, 4198 },
4199 { 4199 {
4200 "defaultMessage": "!!!Save workspace", 4200 "defaultMessage": "!!!Save workspace",
4201 "end": { 4201 "end": {
4202 "column": 3, 4202 "column": 3,
4203 "line": 24 4203 "line": 28
4204 }, 4204 },
4205 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4205 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4206 "id": "settings.workspace.form.buttonSave", 4206 "id": "settings.workspace.form.buttonSave",
4207 "start": { 4207 "start": {
4208 "column": 14, 4208 "column": 14,
4209 "line": 21 4209 "line": 25
4210 } 4210 }
4211 }, 4211 },
4212 { 4212 {
4213 "defaultMessage": "!!!Name", 4213 "defaultMessage": "!!!Name",
4214 "end": { 4214 "end": {
4215 "column": 3, 4215 "column": 3,
4216 "line": 28 4216 "line": 32
4217 }, 4217 },
4218 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4218 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4219 "id": "settings.workspace.form.name", 4219 "id": "settings.workspace.form.name",
4220 "start": { 4220 "start": {
4221 "column": 8, 4221 "column": 8,
4222 "line": 25 4222 "line": 29
4223 } 4223 }
4224 }, 4224 },
4225 { 4225 {
4226 "defaultMessage": "!!!Your workspaces", 4226 "defaultMessage": "!!!Your workspaces",
4227 "end": { 4227 "end": {
4228 "column": 3, 4228 "column": 3,
4229 "line": 32 4229 "line": 36
4230 }, 4230 },
4231 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4231 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4232 "id": "settings.workspace.form.yourWorkspaces", 4232 "id": "settings.workspace.form.yourWorkspaces",
4233 "start": { 4233 "start": {
4234 "column": 18, 4234 "column": 18,
4235 "line": 29 4235 "line": 33
4236 } 4236 }
4237 }, 4237 },
4238 { 4238 {
4239 "defaultMessage": "!!!Services in this Workspace", 4239 "defaultMessage": "!!!Services in this Workspace",
4240 "end": { 4240 "end": {
4241 "column": 3, 4241 "column": 3,
4242 "line": 36 4242 "line": 40
4243 }, 4243 },
4244 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4244 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4245 "id": "settings.workspace.form.servicesInWorkspaceHeadline", 4245 "id": "settings.workspace.form.servicesInWorkspaceHeadline",
4246 "start": { 4246 "start": {
4247 "column": 31, 4247 "column": 31,
4248 "line": 33 4248 "line": 37
4249 } 4249 }
4250 }, 4250 },
4251 { 4251 {
4252 "defaultMessage": "!!!You haven't added any services yet.", 4252 "defaultMessage": "!!!You haven't added any services yet.",
4253 "end": { 4253 "end": {
4254 "column": 3, 4254 "column": 3,
4255 "line": 40 4255 "line": 44
4256 }, 4256 },
4257 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4257 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4258 "id": "settings.services.noServicesAdded", 4258 "id": "settings.services.noServicesAdded",
4259 "start": { 4259 "start": {
4260 "column": 19, 4260 "column": 19,
4261 "line": 37 4261 "line": 41
4262 } 4262 }
4263 }, 4263 },
4264 { 4264 {
4265 "defaultMessage": "!!!Discover services", 4265 "defaultMessage": "!!!Discover services",
4266 "end": { 4266 "end": {
4267 "column": 3, 4267 "column": 3,
4268 "line": 44 4268 "line": 48
4269 }, 4269 },
4270 "file": "src/features/workspaces/components/EditWorkspaceForm.js", 4270 "file": "src/features/workspaces/components/EditWorkspaceForm.js",
4271 "id": "settings.services.discoverServices", 4271 "id": "settings.services.discoverServices",
4272 "start": { 4272 "start": {
4273 "column": 20, 4273 "column": 20,
4274 "line": 41 4274 "line": 45
4275 } 4275 }
4276 } 4276 }
4277 ], 4277 ],
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index 12e2bea88..d19ddff13 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -329,6 +329,8 @@
329 "settings.workspace.add.form.submitButton": "Create workspace", 329 "settings.workspace.add.form.submitButton": "Create workspace",
330 "settings.workspace.form.buttonDelete": "Delete workspace", 330 "settings.workspace.form.buttonDelete": "Delete workspace",
331 "settings.workspace.form.buttonSave": "Save workspace", 331 "settings.workspace.form.buttonSave": "Save workspace",
332 "settings.workspace.form.keepLoaded": "Keep this workspace loaded*",
333 "settings.workspace.form.keepLoadedInfo": "*This option will be overwritten by the global \"Keep all workspaces loaded\" option.",
332 "settings.workspace.form.name": "Name", 334 "settings.workspace.form.name": "Name",
333 "settings.workspace.form.servicesInWorkspaceHeadline": "Services in this Workspace", 335 "settings.workspace.form.servicesInWorkspaceHeadline": "Services in this Workspace",
334 "settings.workspace.form.yourWorkspaces": "Your workspaces", 336 "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() {