logster 2.11.4 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
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 +10 -5
  5. data/README.md +8 -0
  6. data/assets/javascript/.gitkeep +0 -0
  7. data/assets/javascript/chunk.143.2faa04830259ce9aa59a.js +22 -0
  8. data/assets/javascript/chunk.178.ca5ade1d8cbdbfbe6d72.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 +1257 -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 +89 -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 +32 -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
+ }