logster 2.11.3 → 2.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +72 -11
- data/.gitignore +2 -0
- data/CHANGELOG.md +13 -3
- data/README.md +8 -0
- data/assets/javascript/.gitkeep +0 -0
- data/assets/javascript/chunk.143.2faa04830259ce9aa59a.js +22 -0
- data/assets/javascript/chunk.178.ca5ade1d8cbdbfbe6d72.js +22 -0
- data/assets/javascript/chunk.468.95dd450003497c781cb3.js +1213 -0
- data/assets/javascript/chunk.916.85a3fc9d873df80f5ea5.js +579 -0
- data/assets/javascript/client-app.js +1261 -276
- data/assets/javascript/vendor.js +4199 -3514
- data/assets/stylesheets/.gitkeep +0 -0
- data/assets/stylesheets/client-app.css +1 -1
- data/assets/stylesheets/vendor.css +1 -1
- data/build_client_app.sh +6 -8
- data/client-app/.editorconfig +0 -1
- data/client-app/.eslintignore +2 -0
- data/client-app/.eslintrc +10 -0
- data/client-app/.gitignore +1 -1
- data/client-app/.prettierignore +21 -0
- data/client-app/.prettierrc +1 -0
- data/client-app/.template-lintrc.js +10 -0
- data/client-app/README.md +4 -5
- data/client-app/app/app.js +2 -2
- data/client-app/app/components/actions-menu.js +21 -21
- data/client-app/app/components/back-trace.js +89 -90
- data/client-app/app/components/env-tab.js +41 -29
- data/client-app/app/components/message-info.js +78 -75
- data/client-app/app/components/message-row.js +20 -17
- data/client-app/app/components/page-nav.js +33 -24
- data/client-app/app/components/panel-resizer.js +53 -37
- data/client-app/app/components/patterns-list.js +101 -84
- data/client-app/app/components/tab-contents.js +15 -19
- data/client-app/app/components/tabbed-section.js +30 -18
- data/client-app/app/components/time-formatter.js +29 -18
- data/client-app/app/controllers/index.js +143 -119
- data/client-app/app/controllers/show.js +17 -13
- data/client-app/app/helpers/or.js +1 -1
- data/client-app/app/initializers/app-init.js +23 -34
- data/client-app/app/lib/decorators.js +4 -2
- data/client-app/app/lib/preload.js +7 -4
- data/client-app/app/lib/utilities.js +55 -54
- data/client-app/app/models/group.js +20 -15
- data/client-app/app/models/message-collection.js +153 -148
- data/client-app/app/models/message.js +60 -58
- data/client-app/app/models/pattern-item.js +24 -22
- data/client-app/app/router.js +2 -2
- data/client-app/app/routes/index.js +19 -12
- data/client-app/app/routes/settings.js +12 -10
- data/client-app/app/routes/show.js +6 -4
- data/client-app/app/services/events.js +4 -0
- data/client-app/app/styles/app.css +2 -0
- data/client-app/app/templates/application.hbs +1 -2
- data/client-app/app/templates/components/actions-menu.hbs +23 -8
- data/client-app/app/templates/components/back-trace.hbs +10 -3
- data/client-app/app/templates/components/env-tab.hbs +9 -7
- data/client-app/app/templates/components/message-info.hbs +65 -34
- data/client-app/app/templates/components/message-row.hbs +25 -8
- data/client-app/app/templates/components/page-nav.hbs +34 -10
- data/client-app/app/templates/components/panel-resizer.hbs +3 -3
- data/client-app/app/templates/components/patterns-list.hbs +54 -20
- data/client-app/app/templates/components/tabbed-section.hbs +12 -4
- data/client-app/app/templates/components/time-formatter.hbs +1 -1
- data/client-app/app/templates/index.hbs +100 -78
- data/client-app/app/templates/settings.hbs +30 -19
- data/client-app/app/templates/show.hbs +9 -8
- data/client-app/config/ember-cli-update.json +18 -0
- data/client-app/config/environment.js +13 -13
- data/client-app/config/icons.js +3 -3
- data/client-app/config/targets.js +16 -8
- data/client-app/ember-cli-build.js +4 -4
- data/client-app/package.json +43 -30
- data/client-app/testem.js +16 -17
- data/client-app/tests/index.html +8 -1
- data/client-app/tests/integration/components/back-trace-test.js +32 -26
- data/client-app/tests/integration/components/env-tab-test.js +79 -53
- data/client-app/tests/integration/components/message-info-test.js +25 -23
- data/client-app/tests/integration/components/patterns-list-test.js +14 -11
- data/client-app/tests/test-helper.js +8 -4
- data/client-app/tests/unit/controllers/index-test.js +32 -16
- data/client-app/tests/unit/controllers/show-test.js +5 -5
- data/client-app/tests/unit/routes/index-test.js +5 -5
- data/client-app/tests/unit/routes/show-test.js +5 -5
- data/client-app/yarn.lock +9673 -0
- data/lib/logster/middleware/viewer.rb +12 -12
- data/lib/logster/version.rb +1 -1
- data/logster.gemspec +6 -3
- data/test/logster/middleware/test_viewer.rb +14 -8
- metadata +15 -6
- data/client-app/.eslintrc.js +0 -60
- data/client-app/.travis.yml +0 -28
- data/client-app/app/components/update-time.js +0 -21
- data/client-app/package-lock.json +0 -39196
@@ -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
|
-
|
7
|
-
|
7
|
+
@classic
|
8
|
+
export default class MessageInfo extends Component {
|
9
|
+
@bool("currentRow.group") showSolveAllButton;
|
8
10
|
|
9
|
-
|
10
|
-
|
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:
|
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:
|
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 (
|
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:
|
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:
|
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:
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
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
|
-
|
124
|
-
|
125
|
-
|
120
|
+
@action
|
121
|
+
tabChanged(newTab) {
|
122
|
+
this.onTabChange?.(newTab);
|
123
|
+
}
|
126
124
|
|
127
|
-
|
128
|
-
|
129
|
-
|
125
|
+
@action
|
126
|
+
protect() {
|
127
|
+
this.currentMessage.protect();
|
128
|
+
}
|
130
129
|
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
@action
|
131
|
+
unprotect() {
|
132
|
+
this.currentMessage.unprotect();
|
133
|
+
}
|
134
134
|
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
@action
|
136
|
+
remove() {
|
137
|
+
this.removeMessage(this.currentMessage);
|
138
|
+
}
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
140
|
+
@action
|
141
|
+
solve() {
|
142
|
+
this.solveMessage(this.currentMessage);
|
143
|
+
}
|
142
144
|
|
143
|
-
|
144
|
-
|
145
|
-
|
145
|
+
@action
|
146
|
+
solveAll() {
|
147
|
+
this.currentRow.solveAll();
|
148
|
+
}
|
146
149
|
|
147
|
-
|
148
|
-
|
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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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)
|
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)
|
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
|
2
|
-
import {
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
@classic
|
8
|
+
@classNames("nav-controls")
|
9
|
+
@classNameBindings("extraClasses")
|
10
|
+
export default class PageNav extends Component {
|
11
|
+
@equal("position", 0) disableBackButtons;
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
+
@computed("position", "list.length")
|
14
|
+
get disableForwardButtons() {
|
15
|
+
return this.position === this.list.length - 1;
|
16
|
+
}
|
13
17
|
|
14
|
-
|
18
|
+
@computed("position")
|
19
|
+
get displayNumber() {
|
15
20
|
return this.position + 1;
|
16
|
-
}
|
21
|
+
}
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
33
|
+
const newPos = this.position + amount;
|
34
|
+
this.navigate(newPos);
|
35
|
+
}
|
27
36
|
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
10
|
-
|
11
|
-
|
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
|
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
|
-
|
54
|
-
document.removeEventListener(name, this.performDrag)
|
55
|
-
|
56
|
-
|
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
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
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
|
+
}
|