logster 2.11.4 → 2.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +63 -12
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +15 -5
  5. data/README.md +8 -0
  6. data/assets/javascript/.gitkeep +0 -0
  7. data/assets/javascript/chunk.143.f61340b825c6a3bf6dbe.js +22 -0
  8. data/assets/javascript/chunk.178.6d9ae01775c898e7b748.js +22 -0
  9. data/assets/javascript/chunk.468.95dd450003497c781cb3.js +1213 -0
  10. data/assets/javascript/chunk.916.85a3fc9d873df80f5ea5.js +579 -0
  11. data/assets/javascript/client-app.js +1259 -280
  12. data/assets/javascript/vendor.js +4068 -3375
  13. data/assets/stylesheets/.gitkeep +0 -0
  14. data/assets/stylesheets/client-app.css +1 -1
  15. data/assets/stylesheets/vendor.css +1 -1
  16. data/build_client_app.sh +6 -8
  17. data/client-app/.editorconfig +0 -1
  18. data/client-app/.eslintignore +2 -0
  19. data/client-app/.eslintrc +10 -0
  20. data/client-app/.gitignore +1 -1
  21. data/client-app/.prettierignore +21 -0
  22. data/client-app/.prettierrc +1 -0
  23. data/client-app/.template-lintrc.js +10 -0
  24. data/client-app/README.md +4 -5
  25. data/client-app/app/app.js +2 -2
  26. data/client-app/app/components/actions-menu.js +21 -21
  27. data/client-app/app/components/back-trace.js +93 -90
  28. data/client-app/app/components/env-tab.js +41 -29
  29. data/client-app/app/components/message-info.js +78 -75
  30. data/client-app/app/components/message-row.js +20 -17
  31. data/client-app/app/components/page-nav.js +33 -24
  32. data/client-app/app/components/panel-resizer.js +53 -37
  33. data/client-app/app/components/patterns-list.js +101 -84
  34. data/client-app/app/components/tab-contents.js +15 -19
  35. data/client-app/app/components/tabbed-section.js +30 -18
  36. data/client-app/app/components/time-formatter.js +29 -18
  37. data/client-app/app/controllers/index.js +143 -119
  38. data/client-app/app/controllers/show.js +17 -13
  39. data/client-app/app/helpers/or.js +1 -1
  40. data/client-app/app/initializers/app-init.js +23 -34
  41. data/client-app/app/lib/decorators.js +4 -2
  42. data/client-app/app/lib/preload.js +7 -4
  43. data/client-app/app/lib/utilities.js +55 -54
  44. data/client-app/app/models/group.js +20 -15
  45. data/client-app/app/models/message-collection.js +153 -149
  46. data/client-app/app/models/message.js +60 -58
  47. data/client-app/app/models/pattern-item.js +24 -22
  48. data/client-app/app/router.js +2 -2
  49. data/client-app/app/routes/index.js +19 -12
  50. data/client-app/app/routes/settings.js +12 -10
  51. data/client-app/app/routes/show.js +6 -4
  52. data/client-app/app/services/events.js +4 -0
  53. data/client-app/app/styles/app.css +2 -0
  54. data/client-app/app/templates/application.hbs +1 -2
  55. data/client-app/app/templates/components/actions-menu.hbs +23 -8
  56. data/client-app/app/templates/components/back-trace.hbs +10 -3
  57. data/client-app/app/templates/components/env-tab.hbs +9 -7
  58. data/client-app/app/templates/components/message-info.hbs +65 -34
  59. data/client-app/app/templates/components/message-row.hbs +25 -8
  60. data/client-app/app/templates/components/page-nav.hbs +34 -10
  61. data/client-app/app/templates/components/panel-resizer.hbs +3 -3
  62. data/client-app/app/templates/components/patterns-list.hbs +54 -20
  63. data/client-app/app/templates/components/tabbed-section.hbs +12 -4
  64. data/client-app/app/templates/components/time-formatter.hbs +1 -1
  65. data/client-app/app/templates/index.hbs +100 -78
  66. data/client-app/app/templates/settings.hbs +30 -19
  67. data/client-app/app/templates/show.hbs +9 -8
  68. data/client-app/config/ember-cli-update.json +18 -0
  69. data/client-app/config/environment.js +13 -13
  70. data/client-app/config/icons.js +3 -3
  71. data/client-app/config/targets.js +16 -8
  72. data/client-app/ember-cli-build.js +4 -4
  73. data/client-app/package.json +41 -31
  74. data/client-app/testem.js +16 -17
  75. data/client-app/tests/index.html +8 -1
  76. data/client-app/tests/integration/components/back-trace-test.js +49 -26
  77. data/client-app/tests/integration/components/env-tab-test.js +79 -53
  78. data/client-app/tests/integration/components/message-info-test.js +25 -23
  79. data/client-app/tests/integration/components/patterns-list-test.js +14 -11
  80. data/client-app/tests/test-helper.js +8 -4
  81. data/client-app/tests/unit/controllers/index-test.js +32 -16
  82. data/client-app/tests/unit/controllers/show-test.js +5 -5
  83. data/client-app/tests/unit/routes/index-test.js +5 -5
  84. data/client-app/tests/unit/routes/show-test.js +5 -5
  85. data/client-app/yarn.lock +9673 -0
  86. data/lib/logster/version.rb +1 -1
  87. data/logster.gemspec +6 -3
  88. metadata +15 -6
  89. data/client-app/.eslintrc.js +0 -60
  90. data/client-app/.travis.yml +0 -28
  91. data/client-app/app/components/update-time.js +0 -21
  92. data/client-app/package-lock.json +0 -16639
@@ -1,23 +1,26 @@
1
+ import classic from "ember-classic-decorator";
1
2
  import { ajax, increaseTitleCount } from "client-app/lib/utilities";
2
3
  import Message from "client-app/models/message";
3
4
  import Group from "client-app/models/group";
4
5
  import { compare } from "@ember/utils";
5
- import { default as EmberObject, computed } from "@ember/object";
6
+ import EmberObject, { computed } from "@ember/object";
6
7
  import { A } from "@ember/array";
7
8
 
8
9
  const BATCH_SIZE = 50;
9
-
10
10
  export const SEVERITIES = ["Debug", "Info", "Warn", "Err", "Fatal"];
11
11
 
12
- export default EmberObject.extend({
13
- total: 0,
14
- rows: null,
15
- currentRow: null,
16
- currentTab: null,
17
- currentEnvPosition: 0,
18
- currentGroupedMessagesPosition: 0,
19
-
20
- filter: computed(...SEVERITIES.map(s => `show${s}`), function() {
12
+ @classic
13
+ export default class MessageCollection extends EmberObject {
14
+ total = 0;
15
+ rows = A();
16
+ currentRow = null;
17
+ currentTab = null;
18
+ currentEnvPosition = 0;
19
+ currentGroupedMessagesPosition = 0;
20
+ search = "";
21
+
22
+ @computed(...SEVERITIES.map((s) => `show${s}`))
23
+ get filter() {
21
24
  const filter = [];
22
25
  SEVERITIES.forEach((severity, index) => {
23
26
  if (this[`show${severity}`]) {
@@ -26,35 +29,57 @@ export default EmberObject.extend({
26
29
  });
27
30
  filter.push(5); // always show unknown, rare
28
31
  return filter;
29
- }),
32
+ }
30
33
 
31
- init() {
32
- this._super(...arguments);
33
- this.setProperties({
34
- search: "",
35
- rows: A()
36
- });
37
- },
38
-
39
- currentMessage: computed(
40
- "currentRow",
41
- "currentGroupedMessagesPosition",
42
- function() {
43
- const row = this.currentRow;
44
- const position = this.currentGroupedMessagesPosition;
45
- if (row && row.group) {
46
- return row.messages[position];
47
- } else {
48
- return row;
34
+ @computed("currentRow", "currentGroupedMessagesPosition")
35
+ get currentMessage() {
36
+ const row = this.currentRow;
37
+ const position = this.currentGroupedMessagesPosition;
38
+ if (row && row.group) {
39
+ return row.messages[position];
40
+ } else {
41
+ return row;
42
+ }
43
+ }
44
+
45
+ @computed("filter", "search.length")
46
+ get hideCountInLoadMore() {
47
+ const filter = this.filter;
48
+ return (
49
+ (this.search && this.search.length > 0) || (filter && filter.length < 6)
50
+ );
51
+ }
52
+
53
+ @computed("rows.length", "canLoadMore")
54
+ get moreBefore() {
55
+ return this.rows.length >= BATCH_SIZE && this.canLoadMore;
56
+ }
57
+
58
+ @computed("total", "rows.length")
59
+ get totalBefore() {
60
+ return this.total - this.rows.length;
61
+ }
62
+
63
+ @computed("search")
64
+ get regexSearch() {
65
+ const search = this.search;
66
+ if (search && search.length > 2 && search[0] === "/") {
67
+ const match = search.match(/\/(.*)\/(.*)/);
68
+ if (match && match.length === 3) {
69
+ try {
70
+ return new RegExp(match[1], match[2]);
71
+ } catch (err) {
72
+ // don't care
73
+ }
49
74
  }
50
75
  }
51
- ),
76
+ return null;
77
+ }
52
78
 
53
- solve(message) {
54
- message.solve().then(() => {
55
- this.reload();
56
- });
57
- },
79
+ async solve(message) {
80
+ await message.solve();
81
+ this.reload();
82
+ }
58
83
 
59
84
  selectRow(row, opts = {}) {
60
85
  const old = this.currentRow;
@@ -69,35 +94,36 @@ export default EmberObject.extend({
69
94
  currentRow: row,
70
95
  loadingEnv: false,
71
96
  currentGroupedMessagesPosition,
72
- currentEnvPosition: 0
97
+ currentEnvPosition: 0,
73
98
  });
74
- if (shouldRefresh)
99
+ if (shouldRefresh) {
75
100
  this.notifyPropertyChange("currentGroupedMessagesPosition");
101
+ }
76
102
  const forceFetchEnv = this.currentMessage && !this.currentMessage.env;
77
103
  this.fetchEnv({ force: forceFetchEnv });
78
- },
104
+ }
79
105
 
80
106
  tabChanged(newTab) {
81
107
  this.setProperties({
82
108
  currentTab: newTab,
83
- loadingEnv: false
109
+ loadingEnv: false,
84
110
  });
85
111
  this.fetchEnv();
86
- },
112
+ }
87
113
 
88
114
  groupedMessageChanged(newPosition) {
89
115
  this.setProperties({
90
116
  currentGroupedMessagesPosition: newPosition,
91
- currentEnvPosition: 0
117
+ currentEnvPosition: 0,
92
118
  });
93
119
  const forceFetchEnv = this.currentMessage && !this.currentMessage.env;
94
120
  this.fetchEnv({ force: forceFetchEnv });
95
- },
121
+ }
96
122
 
97
123
  envChanged(newPosition) {
98
124
  this.set("currentEnvPosition", newPosition);
99
125
  this.fetchEnv();
100
- },
126
+ }
101
127
 
102
128
  fetchEnv(opts = {}) {
103
129
  const message = this.currentMessage;
@@ -108,27 +134,27 @@ export default EmberObject.extend({
108
134
  this.set("loadingEnv", true);
109
135
  return message.fetchEnv().finally(() => this.set("loadingEnv", false));
110
136
  }
111
- },
137
+ }
112
138
 
113
139
  findEquivalentMessageIndex(row) {
114
140
  let messageIndex = 0;
115
141
  if (
116
- row &&
117
- row.group &&
118
- this.currentRow &&
119
- this.currentRow.group &&
142
+ row?.group &&
143
+ this.currentRow?.group &&
120
144
  row.key === this.currentRow.key
121
145
  ) {
122
146
  messageIndex = row.messages.mapBy("key").indexOf(this.currentMessage.key);
123
147
  messageIndex = Math.max(0, messageIndex);
124
148
  }
149
+
125
150
  return messageIndex;
126
- },
151
+ }
127
152
 
128
153
  updateSelectedRow() {
129
- const currentKey = this.get("currentRow.key");
154
+ const currentKey = this.currentRow?.key;
155
+
130
156
  if (currentKey && this.rows) {
131
- const match = this.rows.find(m => m.key === currentKey);
157
+ const match = this.rows.find((m) => m.key === currentKey);
132
158
  if (match) {
133
159
  const messageIndex = this.findEquivalentMessageIndex(match);
134
160
  this.selectRow(match, { messageIndex });
@@ -136,17 +162,17 @@ export default EmberObject.extend({
136
162
  this.setProperties({
137
163
  currentRow: null,
138
164
  currentEnvPosition: 0,
139
- currentGroupedMessagesPosition: 0
165
+ currentGroupedMessagesPosition: 0,
140
166
  });
141
167
  }
142
168
  }
143
- },
169
+ }
144
170
 
145
- load(opts) {
146
- opts = opts || {};
171
+ async load(opts) {
172
+ opts ||= {};
147
173
 
148
174
  const data = {
149
- filter: this.filter.join("_")
175
+ filter: this.filter.join("_"),
150
176
  };
151
177
 
152
178
  if (this.search && this.search.length > 0) {
@@ -169,131 +195,109 @@ export default EmberObject.extend({
169
195
  }
170
196
 
171
197
  this.set("loading", true);
172
- return ajax("/messages.json", {
173
- data: data,
174
- method: "POST"
175
- })
176
- .then(data => {
177
- // guard against race: ensure the results we're trying to apply
178
- // match the current search terms
179
- if (compare(data.filter, this.filter) != 0) {
180
- return;
181
- }
182
- if (compare(data.search, this.search) != 0) {
183
- return;
184
- }
185
198
 
186
- if (data.messages.length > 0) {
187
- const newRows = this.toObjects(data.messages);
188
- const rows = this.rows;
189
- if (opts.before) {
190
- rows.unshiftObjects(newRows);
191
- } else {
192
- newRows.forEach(nrow => {
193
- rows.forEach(erow => {
194
- if (erow.key === nrow.key) {
195
- rows.removeObject(erow);
196
- if (this.currentRow === erow) {
197
- // TODO would updateFromJson() work here?
198
- const messageIndex = this.findEquivalentMessageIndex(nrow);
199
- this.selectRow(nrow, { messageIndex });
200
- }
201
- }
202
- });
203
- });
204
- rows.addObjects(newRows);
205
- if (newRows.length > 0) {
206
- increaseTitleCount(newRows.length);
199
+ try {
200
+ const response = await ajax("/messages.json", {
201
+ data,
202
+ method: "POST",
203
+ });
204
+
205
+ // guard against race: ensure the results we're trying to apply
206
+ // match the current search terms
207
+ if (compare(response.filter, this.filter) !== 0) {
208
+ return;
209
+ }
210
+
211
+ if (compare(response.search, this.search) !== 0) {
212
+ return;
213
+ }
214
+
215
+ if (response.messages.length > 0) {
216
+ const newRows = this.toObjects(response.messages);
217
+
218
+ if (opts.before) {
219
+ this.rows.unshiftObjects(newRows);
220
+ } else {
221
+ for (const newRow of newRows) {
222
+ for (const row of this.rows) {
223
+ if (row.key !== newRow.key) {
224
+ continue;
225
+ }
226
+
227
+ this.rows.removeObject(row);
228
+
229
+ if (this.currentRow === row) {
230
+ const messageIndex = this.findEquivalentMessageIndex(newRow);
231
+ this.selectRow(newRow, { messageIndex });
232
+ }
207
233
  }
208
234
  }
235
+
236
+ this.rows.addObjects(newRows);
237
+
238
+ if (newRows.length > 0) {
239
+ increaseTitleCount(newRows.length);
240
+ }
209
241
  }
210
- this.set("total", data.total);
211
- return data;
212
- })
213
- .finally(() => this.set("loading", false));
214
- },
242
+ }
243
+
244
+ this.set("total", response.total);
245
+ return response;
246
+ } finally {
247
+ this.set("loading", false);
248
+ }
249
+ }
215
250
 
216
- reload() {
251
+ async reload() {
217
252
  this.set("total", 0);
218
253
  this.rows.clear();
219
254
 
220
- return this.load().then(data => this.updateCanLoadMore(data));
221
- },
255
+ const data = await this.load();
256
+ this.updateCanLoadMore(data);
257
+ }
222
258
 
223
259
  updateCanLoadMore(data) {
224
260
  if (!data) {
225
261
  return;
226
262
  }
263
+
227
264
  if (data.messages.length < BATCH_SIZE) {
228
265
  this.set("canLoadMore", false);
229
266
  } else {
230
267
  this.set("canLoadMore", true);
231
268
  }
232
- },
269
+ }
233
270
 
234
271
  loadMore() {
235
- const rows = this.rows;
236
- if (rows.length === 0) {
272
+ if (this.rows.length === 0) {
237
273
  this.load({});
238
274
  return;
239
275
  }
240
276
 
241
- const lastLog = rows[rows.length - 1];
277
+ const lastLog = this.rows[this.rows.length - 1];
242
278
  const lastKey = lastLog.group ? lastLog.row_id : lastLog.key;
279
+
243
280
  this.load({
244
- after: lastKey
281
+ after: lastKey,
245
282
  });
246
- },
247
-
248
- hideCountInLoadMore: computed("search", "filter", function() {
249
- const filter = this.filter;
250
- return (
251
- (this.search && this.search.length > 0) || (filter && filter.length < 6)
252
- );
253
- }),
254
-
255
- moreBefore: computed("rows.length", "canLoadMore", function() {
256
- return this.get("rows.length") >= BATCH_SIZE && this.canLoadMore;
257
- }),
258
-
259
- totalBefore: computed("total", "rows.length", function() {
260
- return this.total - this.rows.length;
261
- }),
283
+ }
262
284
 
263
- showMoreBefore: function() {
264
- const rows = this.rows;
265
- const firstLog = rows[0];
285
+ async showMoreBefore() {
286
+ const firstLog = this.rows[0];
266
287
  const firstKey = firstLog.group ? firstLog.row_id : firstLog.key;
267
- const knownGroups = rows.filterBy("group").mapBy("regex");
288
+ const knownGroups = this.rows.filterBy("group").mapBy("regex");
268
289
 
269
- this.load({
290
+ const data = await this.load({
270
291
  before: firstKey,
271
- knownGroups
272
- }).then(data => this.updateCanLoadMore(data));
273
- },
292
+ knownGroups,
293
+ });
274
294
 
275
- regexSearch: computed("search", function() {
276
- const search = this.search;
277
- if (search && search.length > 2 && search[0] === "/") {
278
- const match = search.match(/\/(.*)\/(.*)/);
279
- if (match && match.length === 3) {
280
- try {
281
- return new RegExp(match[1], match[2]);
282
- } catch (err) {
283
- // don't care
284
- }
285
- }
286
- }
287
- return null;
288
- }),
295
+ this.updateCanLoadMore(data);
296
+ }
289
297
 
290
298
  toObjects(rows) {
291
- return rows.map(m => {
292
- if (m.group) {
293
- return Group.create(m);
294
- } else {
295
- return Message.create(m);
296
- }
299
+ return rows.map((m) => {
300
+ return m.group ? Group.create(m) : Message.create(m);
297
301
  });
298
302
  }
299
- });
303
+ }
@@ -1,76 +1,49 @@
1
+ import classic from "ember-classic-decorator";
2
+ import { gt } from "@ember/object/computed";
3
+ import EmberObject, { computed } from "@ember/object";
1
4
  import { ajax } from "client-app/lib/utilities";
2
5
  import { getRootPath } from "client-app/lib/preload";
3
- import { computed } from "@ember/object";
4
6
 
5
- export default Em.Object.extend({
6
- MAX_LEN: 200,
7
+ @classic
8
+ export default class Message extends EmberObject {
9
+ MAX_LEN = 200;
7
10
 
8
- fetchEnv() {
9
- return ajax(`/fetch-env/${this.key}.json`).then(env =>
10
- this.set("env", env)
11
- );
12
- },
11
+ @gt("count", 1) showCount;
13
12
 
14
- expand() {
15
- this.set("expanded", true);
16
- },
17
-
18
- solve() {
19
- return ajax(`/solve/${this.key}`, { type: "PUT" });
20
- },
21
-
22
- destroy() {
23
- return ajax(`/message/${this.key}`, { type: "DELETE" });
24
- },
25
-
26
- protect() {
27
- this.set("protected", true);
28
- return ajax(`/protect/${this.key}`, { type: "PUT" });
29
- },
30
-
31
- unprotect() {
32
- this.set("protected", false);
33
- return ajax(`/unprotect/${this.key}`, { type: "DELETE" });
34
- },
35
-
36
- showCount: computed("count", function() {
37
- return this.count > 1;
38
- }),
39
-
40
- hasMore: computed("message", "expanded", function() {
13
+ @computed("MAX_LEN", "expanded", "message.length")
14
+ get hasMore() {
41
15
  return !this.expanded && this.message.length > this.MAX_LEN;
42
- }),
16
+ }
43
17
 
44
- shareUrl: computed("key", function() {
18
+ @computed("key")
19
+ get shareUrl() {
45
20
  return `${getRootPath()}/show/${this.key}`;
46
- }),
21
+ }
47
22
 
48
- displayMessage: computed("message", "expanded", function() {
23
+ @computed("MAX_LEN", "expanded", "message.length")
24
+ get displayMessage() {
49
25
  let message = this.message;
50
26
 
51
27
  if (!this.expanded && this.message.length > this.MAX_LEN) {
52
28
  message = this.message.substr(0, this.MAX_LEN);
53
29
  }
54
30
  return message;
55
- }),
56
-
57
- updateFromObject(other) {
58
- // XXX Only updatable property is count right now
59
- this.set("count", other.get("count"));
60
- },
31
+ }
61
32
 
62
- canSolve: computed("env.{application_version,length}", function() {
33
+ @computed("backtrace.length", "env.{application_version,length}")
34
+ get canSolve() {
63
35
  const appVersion = Array.isArray(this.env)
64
36
  ? this.env
65
- .map(e => e.application_version)
37
+ .map((e) => e.application_version)
66
38
  .compact()
67
39
  .join("")
68
40
  : this.env && this.env.application_version;
69
41
  return appVersion && this.backtrace && this.backtrace.length > 0;
70
- }),
42
+ }
71
43
 
72
- rowClass: computed("severity", function() {
73
- switch (this.get("severity")) {
44
+ @computed("severity")
45
+ get rowClass() {
46
+ switch (this.severity) {
74
47
  case 0:
75
48
  return "debug";
76
49
  case 1:
@@ -84,9 +57,10 @@ export default Em.Object.extend({
84
57
  default:
85
58
  return "unknown";
86
59
  }
87
- }),
60
+ }
88
61
 
89
- glyph: computed("severity", function() {
62
+ @computed("severity")
63
+ get glyph() {
90
64
  switch (this.severity) {
91
65
  case 0:
92
66
  return "";
@@ -101,13 +75,14 @@ export default Em.Object.extend({
101
75
  default:
102
76
  return "question-circle";
103
77
  }
104
- }),
78
+ }
105
79
 
106
- prefix: computed(function() {
80
+ get prefix() {
107
81
  return "fas";
108
- }),
82
+ }
109
83
 
110
- klass: computed("severity", function() {
84
+ @computed("severity")
85
+ get klass() {
111
86
  switch (this.severity) {
112
87
  case 0:
113
88
  return "";
@@ -122,5 +97,32 @@ export default Em.Object.extend({
122
97
  default:
123
98
  return "unknown";
124
99
  }
125
- })
126
- });
100
+ }
101
+
102
+ async fetchEnv() {
103
+ const env = await ajax(`/fetch-env/${this.key}.json`);
104
+ this.set("env", env);
105
+ }
106
+
107
+ expand() {
108
+ this.set("expanded", true);
109
+ }
110
+
111
+ solve() {
112
+ return ajax(`/solve/${this.key}`, { type: "PUT" });
113
+ }
114
+
115
+ destroy() {
116
+ return ajax(`/message/${this.key}`, { type: "DELETE" });
117
+ }
118
+
119
+ protect() {
120
+ this.set("protected", true);
121
+ return ajax(`/protect/${this.key}`, { type: "PUT" });
122
+ }
123
+
124
+ unprotect() {
125
+ this.set("protected", false);
126
+ return ajax(`/unprotect/${this.key}`, { type: "DELETE" });
127
+ }
128
+ }
@@ -1,30 +1,32 @@
1
- import { default as EmberObject, computed } from "@ember/object";
1
+ import classic from "ember-classic-decorator";
2
+ import { lte } from "@ember/object/computed";
3
+ import EmberObject, { computed } from "@ember/object";
2
4
 
3
- export default EmberObject.extend({
4
- isNew: false,
5
- value: "",
6
- valueBuffer: "",
7
- error: null,
8
- saving: false,
9
- count: 0,
5
+ @classic
6
+ export default class PatternItem extends EmberObject {
7
+ isNew = false;
8
+ value = "";
9
+ valueBuffer = "";
10
+ error = null;
11
+ saving = false;
12
+ count = 0;
13
+
14
+ @lte("count", 0) zeroCount;
10
15
 
11
16
  init() {
12
- this._super(...arguments);
13
- this.set("valueBuffer", this.get("value"));
14
- },
17
+ super.init(...arguments);
18
+ this.set("valueBuffer", this.value);
19
+ }
20
+
21
+ @computed("value", "valueBuffer")
22
+ get hasBuffer() {
23
+ return this.value !== this.valueBuffer;
24
+ }
15
25
 
16
26
  updateValue(newValue) {
17
27
  this.setProperties({
18
28
  value: newValue,
19
- valueBuffer: newValue
29
+ valueBuffer: newValue,
20
30
  });
21
- },
22
-
23
- hasBuffer: computed("value", "valueBuffer", function() {
24
- return this.get("value") !== this.get("valueBuffer");
25
- }),
26
-
27
- zeroCount: computed("count", function() {
28
- return this.get("count") <= 0;
29
- })
30
- });
31
+ }
32
+ }
@@ -1,12 +1,12 @@
1
1
  import EmberRouter from "@ember/routing/router";
2
- import config from "./config/environment";
2
+ import config from "client-app/config/environment";
3
3
 
4
4
  export default class Router extends EmberRouter {
5
5
  location = config.locationType;
6
6
  rootURL = config.rootURL;
7
7
  }
8
8
 
9
- Router.map(function() {
9
+ Router.map(function () {
10
10
  this.route("index", { path: "/" });
11
11
  this.route("show", { path: "/show/:id" });
12
12
  this.route("settings");