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,93 +1,94 @@
1
+ import classic from "ember-classic-decorator";
2
+ import { bool } from "@ember/object/computed";
1
3
  import Component from "@ember/component";
2
- import { computed } from "@ember/object";
4
+ import { action, computed } from "@ember/object";
3
5
  import Preload from "client-app/lib/preload";
4
- import { bool } from "@ember/object/computed";
5
6
 
6
- export default Component.extend({
7
- showSolveAllButton: bool("currentRow.group"),
7
+ @classic
8
+ export default class MessageInfo extends Component {
9
+ @bool("currentRow.group") showSolveAllButton;
8
10
 
9
- buttons: computed("currentMessage.protected", "showSolveButton", function() {
10
- const protect = this.get("currentMessage.protected");
11
+ @computed("currentMessage.protected", "showSolveAllButton", "showSolveButton")
12
+ get buttons() {
13
+ const protect = this.currentMessage.protected;
11
14
  const buttons = [];
12
- const prefix = "fas";
13
15
 
14
16
  if (!protect && this.showSolveButton) {
15
17
  buttons.push({
16
18
  klass: "solve",
17
- action: "solve",
19
+ action: this.solve,
18
20
  icon: "check-square",
19
21
  label: "Solve",
20
22
  prefix: "far",
21
- danger: true
23
+ danger: true,
22
24
  });
23
25
  }
24
26
 
25
27
  if (this.showSolveAllButton) {
26
28
  buttons.push({
27
29
  klass: "solve-all",
28
- action: "solveAll",
30
+ action: this.solveAll,
29
31
  icon: "check-square",
30
32
  label: "Solve All",
31
33
  prefix: "far",
32
- danger: true
34
+ danger: true,
33
35
  });
34
36
  }
35
37
 
36
- if (!protect) {
38
+ if (protect) {
39
+ buttons.push({
40
+ klass: "unprotect",
41
+ action: this.unprotect,
42
+ icon: "unlock",
43
+ prefix: "fas",
44
+ label: "Unprotect",
45
+ });
46
+ } else {
37
47
  buttons.push(
38
48
  {
39
49
  klass: "remove",
40
- action: "remove",
50
+ action: this.remove,
41
51
  icon: "trash-alt",
42
52
  label: "Remove",
43
53
  prefix: "far",
44
- danger: true
54
+ danger: true,
45
55
  },
46
56
  {
47
57
  klass: "protect",
48
- action: "protect",
58
+ action: this.protect,
49
59
  icon: "lock",
50
- prefix,
51
- label: "Protect"
60
+ prefix: "fas",
61
+ label: "Protect",
52
62
  }
53
63
  );
54
- } else {
55
- buttons.push({
56
- klass: "unprotect",
57
- action: "unprotect",
58
- icon: "unlock",
59
- prefix,
60
- label: "Unprotect"
61
- });
62
64
  }
63
65
 
64
66
  buttons.push({
65
67
  klass: "copy",
66
- action: "copyAction",
68
+ action: this.copy,
67
69
  icon: "copy",
68
70
  prefix: "far",
69
- label: "Copy"
71
+ label: "Copy",
70
72
  });
73
+
71
74
  return buttons;
72
- }),
73
-
74
- showSolveButton: computed(
75
- "showSolveAllButton",
76
- "currentMessage.{canSolve,env}",
77
- function() {
78
- if (this.showSolveAllButton) return false;
79
- // env isn't loaded until you switch to the env tab
80
- // so if we don't have env we show the button if
81
- // application_version is provided in the config
82
- return this.currentMessage.env
83
- ? this.currentMessage.canSolve
84
- : !!Preload.get("application_version");
75
+ }
76
+
77
+ @computed("showSolveAllButton", "currentMessage.{canSolve,env}")
78
+ get showSolveButton() {
79
+ if (this.showSolveAllButton) {
80
+ return false;
85
81
  }
86
- ),
82
+ // env isn't loaded until you switch to the env tab
83
+ // so if we don't have env we show the button if
84
+ // application_version is provided in the config
85
+ return this.currentMessage.env
86
+ ? this.currentMessage.canSolve
87
+ : !!Preload.get("application_version");
88
+ }
87
89
 
90
+ @action
88
91
  copy() {
89
- const temp = document.createElement("TEXTAREA");
90
- document.body.appendChild(temp);
91
92
  const header = this.currentMessage.showCount
92
93
  ? `Message (${this.currentMessage.count} copies reported)`
93
94
  : "Message";
@@ -100,52 +101,54 @@ export default Component.extend({
100
101
 
101
102
  const httpHosts = Array.isArray(this.currentMessage.env)
102
103
  ? this.currentMessage.env
103
- .map(e => e["HTTP_HOST"])
104
+ .map((e) => e["HTTP_HOST"])
104
105
  .filter((e, i, a) => e && a.indexOf(e) === i)
105
106
  .join(", ")
106
107
  : this.currentMessage.env["HTTP_HOST"];
107
108
 
108
109
  const env = httpHosts ? `Env\n\nHTTP HOSTS: ${httpHosts}` : "";
109
- const lines = [message, backtrace, env].filter(l => l).join("\n\n");
110
+ const lines = [message, backtrace, env].filter((l) => l).join("\n\n");
111
+
112
+ const temp = document.createElement("TEXTAREA");
113
+ document.body.appendChild(temp);
110
114
  temp.value = lines;
111
115
  temp.select();
112
116
  document.execCommand("copy");
113
117
  document.body.removeChild(temp);
114
- },
115
-
116
- actions: {
117
- tabChanged(newTab) {
118
- if (this.onTabChange) {
119
- this.onTabChange(newTab);
120
- }
121
- },
118
+ }
122
119
 
123
- protect() {
124
- this.currentMessage.protect();
125
- },
120
+ @action
121
+ tabChanged(newTab) {
122
+ this.onTabChange?.(newTab);
123
+ }
126
124
 
127
- unprotect() {
128
- this.currentMessage.unprotect();
129
- },
125
+ @action
126
+ protect() {
127
+ this.currentMessage.protect();
128
+ }
130
129
 
131
- remove() {
132
- this.removeMessage(this.currentMessage);
133
- },
130
+ @action
131
+ unprotect() {
132
+ this.currentMessage.unprotect();
133
+ }
134
134
 
135
- solve() {
136
- this.solveMessage(this.currentMessage);
137
- },
135
+ @action
136
+ remove() {
137
+ this.removeMessage(this.currentMessage);
138
+ }
138
139
 
139
- solveAll() {
140
- this.currentRow.solveAll();
141
- },
140
+ @action
141
+ solve() {
142
+ this.solveMessage(this.currentMessage);
143
+ }
142
144
 
143
- share() {
144
- window.location.pathname = this.get("currentMessage.shareUrl");
145
- },
145
+ @action
146
+ solveAll() {
147
+ this.currentRow.solveAll();
148
+ }
146
149
 
147
- copyAction() {
148
- this.copy();
149
- }
150
+ @action
151
+ share() {
152
+ window.location.pathname = this.currentMessage.shareUrl;
150
153
  }
151
- });
154
+ }
@@ -1,37 +1,36 @@
1
+ import classic from "ember-classic-decorator";
2
+ import { classNameBindings, tagName } from "@ember-decorators/component";
1
3
  import Component from "@ember/component";
2
4
 
3
5
  let CHECKED_BOTTOM;
4
6
  let STICK_TO_BOTTOM;
5
7
 
6
- export default Component.extend({
7
- tagName: "div",
8
-
9
- classNameBindings: [
10
- "model.rowClass",
11
- ":message-row",
12
- "model.selected:selected"
13
- ],
14
-
15
- click() {
16
- this.selectRow();
17
- },
18
-
8
+ @classic
9
+ @tagName("div")
10
+ @classNameBindings("model.rowClass", ":message-row", "model.selected:selected")
11
+ export default class MessageRow extends Component {
19
12
  willInsertElement() {
13
+ super.willInsertElement(...arguments);
20
14
  if (CHECKED_BOTTOM) {
21
15
  return;
22
16
  }
23
17
 
24
18
  const topPanel = document.getElementById("top-panel");
25
- if (!topPanel) return;
19
+ if (!topPanel) {
20
+ return;
21
+ }
26
22
 
27
23
  const height = parseFloat(getComputedStyle(topPanel).height);
28
24
  STICK_TO_BOTTOM = topPanel.scrollHeight - 20 < height + topPanel.scrollTop;
29
25
  CHECKED_BOTTOM = true;
30
- },
26
+ }
31
27
 
32
28
  didInsertElement() {
29
+ super.didInsertElement(...arguments);
33
30
  const topPanel = document.getElementById("top-panel");
34
- if (!topPanel) return;
31
+ if (!topPanel) {
32
+ return;
33
+ }
35
34
 
36
35
  CHECKED_BOTTOM = false;
37
36
  if (STICK_TO_BOTTOM) {
@@ -40,4 +39,8 @@ export default Component.extend({
40
39
  topPanel.scrollHeight - parseFloat(getComputedStyle(topPanel).height);
41
40
  }
42
41
  }
43
- });
42
+
43
+ click() {
44
+ this.selectRow();
45
+ }
46
+ }
@@ -1,33 +1,42 @@
1
- import Component from "@ember/component";
2
- import { computed } from "@ember/object";
1
+ import classic from "ember-classic-decorator";
2
+ import { classNameBindings, classNames } from "@ember-decorators/component";
3
3
  import { equal } from "@ember/object/computed";
4
+ import Component from "@ember/component";
5
+ import { action, computed } from "@ember/object";
4
6
 
5
- export default Component.extend({
6
- classNames: ["nav-controls"],
7
- classNameBindings: ["extraClasses"],
8
- disableBackButtons: equal("position", 0),
7
+ @classic
8
+ @classNames("nav-controls")
9
+ @classNameBindings("extraClasses")
10
+ export default class PageNav extends Component {
11
+ @equal("position", 0) disableBackButtons;
9
12
 
10
- disableForwardButtons: computed("position", "list.length", function() {
11
- return this.position === this.get("list.length") - 1;
12
- }),
13
+ @computed("position", "list.length")
14
+ get disableForwardButtons() {
15
+ return this.position === this.list.length - 1;
16
+ }
13
17
 
14
- displayNumber: computed("position", function() {
18
+ @computed("position")
19
+ get displayNumber() {
15
20
  return this.position + 1;
16
- }),
21
+ }
17
22
 
18
- actions: {
19
- takeStep(dir) {
20
- const amount = dir === "back" ? -1 : 1;
21
- if (amount === 1 && this.disableForwardButtons) return;
22
- if (amount === -1 && this.disableBackButtons) return;
23
+ @action
24
+ takeStep(dir) {
25
+ const amount = dir === "back" ? -1 : 1;
26
+ if (amount === 1 && this.disableForwardButtons) {
27
+ return;
28
+ }
29
+ if (amount === -1 && this.disableBackButtons) {
30
+ return;
31
+ }
23
32
 
24
- const newPos = this.position + amount;
25
- this.navigate(newPos);
26
- },
33
+ const newPos = this.position + amount;
34
+ this.navigate(newPos);
35
+ }
27
36
 
28
- bigJump(dir) {
29
- const newPos = dir === "back" ? 0 : this.get("list.length") - 1;
30
- this.navigate(newPos);
31
- }
37
+ @action
38
+ bigJump(dir) {
39
+ const newPos = dir === "back" ? 0 : this.list.length - 1;
40
+ this.navigate(newPos);
32
41
  }
33
- });
42
+ }
@@ -1,3 +1,6 @@
1
+ import classic from "ember-classic-decorator";
2
+ import { classNames } from "@ember-decorators/component";
3
+ import { inject as service } from "@ember/service";
1
4
  import Component from "@ember/component";
2
5
  import { scheduleOnce, throttle } from "@ember/runloop";
3
6
  import { bound } from "client-app/lib/decorators";
@@ -6,9 +9,35 @@ const MOVE_EVENTS = ["touchmove", "mousemove"];
6
9
  const UP_EVENTS = ["touchend", "mouseup"];
7
10
  const DOWN_EVENTS = ["touchstart", "mousedown"];
8
11
 
9
- export default Component.extend({
10
- resizing: false,
11
- classNames: ["divider"],
12
+ @classic
13
+ @classNames("divider")
14
+ export default class PanelResizer extends Component {
15
+ @service events;
16
+
17
+ resizing = false;
18
+
19
+ didInsertElement() {
20
+ super.didInsertElement(...arguments);
21
+ // inspired by http://plugins.jquery.com/misc/textarea.js
22
+ this.set("divider", document.querySelector(".divider"));
23
+ for (const name of DOWN_EVENTS) {
24
+ this.divider.addEventListener(name, this.dividerClickHandler);
25
+ }
26
+ scheduleOnce("afterRender", this, "initialDivideView");
27
+ }
28
+
29
+ willDestroyElement() {
30
+ super.willDestroyElement(...arguments);
31
+ for (const name of DOWN_EVENTS) {
32
+ this.divider.removeEventListener(name, this.dividerClickHandler);
33
+ }
34
+ }
35
+
36
+ initialDivideView() {
37
+ const amount = (localStorage && localStorage.logster_divider_bottom) || 300;
38
+ const fromTop = window.innerHeight - parseInt(amount, 10);
39
+ this.divideView(fromTop);
40
+ }
12
41
 
13
42
  divideView(fromTop) {
14
43
  const height = window.innerHeight;
@@ -20,12 +49,12 @@ export default Component.extend({
20
49
 
21
50
  this.divider.style.bottom = `${fromBottom - 5}px`;
22
51
  this.events.trigger("panelResized", fromBottom);
23
- },
52
+ }
24
53
 
25
54
  @bound
26
55
  performDrag(e) {
27
56
  throttle(this, this.throttledPerformDrag, e, 25);
28
- },
57
+ }
29
58
 
30
59
  throttledPerformDrag(e) {
31
60
  if (this.resizing) {
@@ -33,14 +62,15 @@ export default Component.extend({
33
62
  e.clientY || (e.touches && e.touches[0] && e.touches[0].clientY)
34
63
  );
35
64
  }
36
- },
65
+ }
37
66
 
38
67
  @bound
39
- endDrag(/* e */) {
68
+ endDrag /* e */() {
40
69
  const overlay = document.getElementById("overlay");
41
70
  if (overlay) {
42
71
  overlay.parentElement.removeChild(overlay);
43
72
  }
73
+
44
74
  this.set("resizing", false);
45
75
 
46
76
  if (localStorage) {
@@ -50,43 +80,29 @@ export default Component.extend({
50
80
  );
51
81
  }
52
82
 
53
- MOVE_EVENTS.forEach(name =>
54
- document.removeEventListener(name, this.performDrag)
55
- );
56
- UP_EVENTS.forEach(name => document.removeEventListener(name, this.endDrag));
57
- },
83
+ for (const name of MOVE_EVENTS) {
84
+ document.removeEventListener(name, this.performDrag);
85
+ }
86
+ for (const name of UP_EVENTS) {
87
+ document.removeEventListener(name, this.endDrag);
88
+ }
89
+ }
58
90
 
59
91
  @bound
60
92
  dividerClickHandler(e) {
61
93
  e.preventDefault(); // for disabling pull-down-to-refresh on mobile
94
+
62
95
  const overlay = document.createElement("DIV");
63
96
  overlay.id = "overlay";
64
97
  document.body.appendChild(overlay);
65
- this.set("resizing", true);
66
- MOVE_EVENTS.forEach(name =>
67
- document.addEventListener(name, this.performDrag)
68
- );
69
- UP_EVENTS.forEach(name => document.addEventListener(name, this.endDrag));
70
- },
71
98
 
72
- didInsertElement() {
73
- // inspired by http://plugins.jquery.com/misc/textarea.js
74
- this.set("divider", document.querySelector(".divider"));
75
- DOWN_EVENTS.forEach(name => {
76
- this.divider.addEventListener(name, this.dividerClickHandler);
77
- });
78
- scheduleOnce("afterRender", this, "initialDivideView");
79
- },
80
-
81
- initialDivideView() {
82
- const amount = (localStorage && localStorage.logster_divider_bottom) || 300;
83
- const fromTop = window.innerHeight - parseInt(amount, 10);
84
- this.divideView(fromTop);
85
- },
99
+ this.set("resizing", true);
86
100
 
87
- willDestroyElement() {
88
- DOWN_EVENTS.forEach(name =>
89
- this.divider.removeEventListener(name, this.dividerClickHandler)
90
- );
101
+ for (const name of MOVE_EVENTS) {
102
+ document.addEventListener(name, this.performDrag);
103
+ }
104
+ for (const name of UP_EVENTS) {
105
+ document.addEventListener(name, this.endDrag);
106
+ }
91
107
  }
92
- });
108
+ }