diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-29 12:06:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-29 12:06:31 +0300 |
commit | 6b13a226ddfc49140d58e7e88f8703ae0ed90574 (patch) | |
tree | 9a92431e484354f43230fa87adc00a2edbf6f09c /app/assets | |
parent | 2ac93cb80c4c0a57fde86de8262b569d1e9b9e51 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
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; } |