Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-11-29 12:06:31 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-11-29 12:06:31 +0300
commit6b13a226ddfc49140d58e7e88f8703ae0ed90574 (patch)
tree9a92431e484354f43230fa87adc00a2edbf6f09c /app/assets
parent2ac93cb80c4c0a57fde86de8262b569d1e9b9e51 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue11
-rw-r--r--app/assets/javascripts/error_tracking/components/stacktrace.vue2
-rw-r--r--app/assets/javascripts/error_tracking/components/stacktrace_entry.vue63
-rw-r--r--app/assets/javascripts/error_tracking/store/details/getters.js5
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue5
-rw-r--r--app/assets/javascripts/performance_bar/index.js50
-rw-r--r--app/assets/javascripts/performance_bar/stores/performance_bar_store.js10
-rw-r--r--app/assets/javascripts/user_popovers.js1
-rw-r--r--app/assets/stylesheets/pages/error_details.scss6
9 files changed, 126 insertions, 27 deletions
diff --git a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
index a001b315d4f..9d8e5396dea 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -8,7 +8,6 @@ import {
GlTable,
GlSearchBoxByClick,
} from '@gitlab/ui';
-import { visitUrl } from '~/lib/utils/url_utility';
import Icon from '~/vue_shared/components/icon.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { __ } from '~/locale';
@@ -76,8 +75,8 @@ export default {
this.startPolling(`${this.indexPath}?search_term=${this.errorSearchQuery}`);
},
trackViewInSentryOptions,
- viewDetails(errorId) {
- visitUrl(`error_tracking/${errorId}/details`);
+ getDetailsLink(errorId) {
+ return `error_tracking/${errorId}/details`;
},
},
};
@@ -129,11 +128,7 @@ export default {
</template>
<template slot="error" slot-scope="errors">
<div class="d-flex flex-column">
- <gl-link
- class="d-flex text-dark"
- target="_blank"
- @click="viewDetails(errors.item.id)"
- >
+ <gl-link class="d-flex text-dark" :href="getDetailsLink(errors.item.id)">
<strong class="text-truncate">{{ errors.item.title.trim() }}</strong>
</gl-link>
<span class="text-secondary text-truncate">
diff --git a/app/assets/javascripts/error_tracking/components/stacktrace.vue b/app/assets/javascripts/error_tracking/components/stacktrace.vue
index 6b71967624f..f58d54f2933 100644
--- a/app/assets/javascripts/error_tracking/components/stacktrace.vue
+++ b/app/assets/javascripts/error_tracking/components/stacktrace.vue
@@ -27,6 +27,8 @@ export default {
:lines="entry.context"
:file-path="entry.filename"
:error-line="entry.lineNo"
+ :error-fn="entry.function"
+ :error-column="entry.colNo"
:expanded="isFirstEntry(index)"
/>
</div>
diff --git a/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue b/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue
index ad542c579a9..9ed5b26a1c2 100644
--- a/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue
+++ b/app/assets/javascripts/error_tracking/components/stacktrace_entry.vue
@@ -1,4 +1,5 @@
<script>
+import { __, sprintf } from '~/locale';
import { GlTooltip } from '@gitlab/ui';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -22,9 +23,20 @@ export default {
type: String,
required: true,
},
+ errorFn: {
+ type: String,
+ required: false,
+ default: '',
+ },
errorLine: {
type: Number,
- required: true,
+ required: false,
+ default: 0,
+ },
+ errorColumn: {
+ type: Number,
+ required: false,
+ default: 0,
},
expanded: {
type: Boolean,
@@ -38,12 +50,23 @@ export default {
};
},
computed: {
- linesLength() {
- return this.lines.length;
+ hasCode() {
+ return Boolean(this.lines.length);
},
collapseIcon() {
return this.isExpanded ? 'chevron-down' : 'chevron-right';
},
+ noCodeFn() {
+ return this.errorFn ? sprintf(__('in %{errorFn} '), { errorFn: this.errorFn }) : '';
+ },
+ noCodeLine() {
+ return this.errorLine
+ ? sprintf(__('at line %{errorLine}%{errorColumn}'), {
+ errorLine: this.errorLine,
+ errorColumn: this.errorColumn ? `:${this.errorColumn}` : '',
+ })
+ : '';
+ },
},
methods: {
isHighlighted(lineNum) {
@@ -66,27 +89,31 @@ export default {
<template>
<div class="file-holder">
<div ref="header" class="file-title file-title-flex-parent">
- <div class="file-header-content ">
- <div class="d-inline-block cursor-pointer" @click="toggle()">
+ <div class="file-header-content d-flex align-content-center">
+ <div v-if="hasCode" class="d-inline-block cursor-pointer" @click="toggle()">
<icon :name="collapseIcon" :size="16" aria-hidden="true" class="append-right-5" />
</div>
- <div class="d-inline-block append-right-4">
- <file-icon
- :file-name="filePath"
- :size="18"
- aria-hidden="true"
- css-classes="append-right-5"
- />
- <strong v-gl-tooltip :title="filePath" class="file-title-name" data-container="body">
- {{ filePath }}
- </strong>
- </div>
-
+ <file-icon
+ :file-name="filePath"
+ :size="18"
+ aria-hidden="true"
+ css-classes="append-right-5"
+ />
+ <strong
+ v-gl-tooltip
+ :title="filePath"
+ class="file-title-name d-inline-block overflow-hidden text-truncate"
+ :class="{ 'limited-width': !hasCode }"
+ data-container="body"
+ >
+ {{ filePath }}
+ </strong>
<clipboard-button
:title="__('Copy file path')"
:text="filePath"
- css-class="btn-default btn-transparent btn-clipboard"
+ css-class="btn-default btn-transparent btn-clipboard position-static"
/>
+ <span v-if="!hasCode" class="text-tertiary">{{ noCodeFn }}{{ noCodeLine }}</span>
</div>
</div>
diff --git a/app/assets/javascripts/error_tracking/store/details/getters.js b/app/assets/javascripts/error_tracking/store/details/getters.js
index 7d13439d721..a36c84dc28c 100644
--- a/app/assets/javascripts/error_tracking/store/details/getters.js
+++ b/app/assets/javascripts/error_tracking/store/details/getters.js
@@ -1,3 +1,6 @@
-export const stacktrace = state => state.stacktraceData.stack_trace_entries.reverse();
+export const stacktrace = state =>
+ state.stacktraceData.stack_trace_entries
+ ? state.stacktraceData.stack_trace_entries.reverse()
+ : [];
export default () => {};
diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
index a0272b148e3..d17c2f33adc 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -52,6 +52,11 @@ export default {
header: s__('PerformanceBar|Redis calls'),
keys: ['cmd'],
},
+ {
+ metric: 'total',
+ header: s__('PerformanceBar|Frontend resources'),
+ keys: ['name', 'size'],
+ },
],
data() {
return { currentRequestId: '' };
diff --git a/app/assets/javascripts/performance_bar/index.js b/app/assets/javascripts/performance_bar/index.js
index 735c9d804ee..2ffe07500e0 100644
--- a/app/assets/javascripts/performance_bar/index.js
+++ b/app/assets/javascripts/performance_bar/index.js
@@ -1,3 +1,4 @@
+/* eslint-disable @gitlab/i18n/no-non-i18n-strings */
import Vue from 'vue';
import axios from '~/lib/utils/axios_utils';
@@ -53,12 +54,61 @@ export default ({ container }) =>
PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId)
.then(res => {
this.store.addRequestDetails(requestId, res.data);
+
+ if (this.requestId === requestId) this.collectFrontendPerformanceMetrics();
})
.catch(() =>
// eslint-disable-next-line no-console
console.warn(`Error getting performance bar results for ${requestId}`),
);
},
+ collectFrontendPerformanceMetrics() {
+ if (performance) {
+ const navigationEntries = performance.getEntriesByType('navigation');
+ const paintEntries = performance.getEntriesByType('paint');
+ const resourceEntries = performance.getEntriesByType('resource');
+
+ let durationString = '';
+ if (navigationEntries.length > 0) {
+ durationString = `BE ${this.formatMs(navigationEntries[0].responseEnd)} / `;
+ durationString += `FCP ${this.formatMs(paintEntries[1].startTime)} / `;
+ durationString += `DOM ${this.formatMs(navigationEntries[0].domContentLoadedEventEnd)}`;
+ }
+
+ let newEntries = resourceEntries.map(this.transformResourceEntry);
+
+ this.updateFrontendPerformanceMetrics(durationString, newEntries);
+
+ if ('PerformanceObserver' in window) {
+ // We start observing for more incoming timings
+ const observer = new PerformanceObserver(list => {
+ newEntries = newEntries.concat(list.getEntries().map(this.transformResourceEntry));
+ this.updateFrontendPerformanceMetrics(durationString, newEntries);
+ });
+
+ observer.observe({ entryTypes: ['resource'] });
+ }
+ }
+ },
+ updateFrontendPerformanceMetrics(durationString, requestEntries) {
+ this.store.setRequestDetailsData(this.requestId, 'total', {
+ duration: durationString,
+ calls: requestEntries.length,
+ details: requestEntries,
+ });
+ },
+ transformResourceEntry(entry) {
+ const nf = new Intl.NumberFormat();
+ return {
+ name: entry.name.replace(document.location.origin, ''),
+ duration: Math.round(entry.duration),
+ size: entry.transferSize ? `${nf.format(entry.transferSize)} bytes` : 'cached',
+ };
+ },
+ formatMs(msValue) {
+ const nf = new Intl.NumberFormat();
+ return `${nf.format(Math.round(msValue))}ms`;
+ },
},
render(createElement) {
return createElement('performance-bar-app', {
diff --git a/app/assets/javascripts/performance_bar/stores/performance_bar_store.js b/app/assets/javascripts/performance_bar/stores/performance_bar_store.js
index 12d0ee86218..6f443db47ed 100644
--- a/app/assets/javascripts/performance_bar/stores/performance_bar_store.js
+++ b/app/assets/javascripts/performance_bar/stores/performance_bar_store.js
@@ -32,6 +32,16 @@ export default class PerformanceBarStore {
return request;
}
+ setRequestDetailsData(requestId, metricKey, requestDetailsData) {
+ const selectedRequest = this.findRequest(requestId);
+ if (selectedRequest) {
+ selectedRequest.details = {
+ ...selectedRequest.details,
+ [metricKey]: requestDetailsData,
+ };
+ }
+ }
+
requestsWithDetails() {
return this.requests.filter(request => request.details);
}
diff --git a/app/assets/javascripts/user_popovers.js b/app/assets/javascripts/user_popovers.js
index 7d6a725b30f..157d89a3a40 100644
--- a/app/assets/javascripts/user_popovers.js
+++ b/app/assets/javascripts/user_popovers.js
@@ -17,6 +17,7 @@ const handleUserPopoverMouseOut = event => {
renderedPopover.$destroy();
renderedPopover = null;
}
+ target.removeAttribute('aria-describedby');
};
/**
diff --git a/app/assets/stylesheets/pages/error_details.scss b/app/assets/stylesheets/pages/error_details.scss
index 0515db914e9..dcd25c126c4 100644
--- a/app/assets/stylesheets/pages/error_details.scss
+++ b/app/assets/stylesheets/pages/error_details.scss
@@ -12,6 +12,12 @@
}
}
+ .file-title-name {
+ &.limited-width {
+ max-width: 80%;
+ }
+ }
+
.line_content.old::before {
content: none !important;
}