diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-09 21:09:19 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-09 21:09:19 +0000 |
commit | 254ec28f5448f6f353cd98f637985de3d1405854 (patch) | |
tree | 1c84ed7b7dd32db96454af034cd6c7e90699e76d /app | |
parent | 141902c04943d5fb43c014b8cf42af60a3bc0cdf (diff) | |
download | gitlab-ce-254ec28f5448f6f353cd98f637985de3d1405854.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
15 files changed, 203 insertions, 243 deletions
diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 3ea2a2fbaee..072bcaaad97 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -112,7 +112,6 @@ export default { mergeRequestDiffs: state => state.diffs.mergeRequestDiffs, mergeRequestDiff: state => state.diffs.mergeRequestDiff, commit: state => state.diffs.commit, - targetBranchName: state => state.diffs.targetBranchName, renderOverflowWarning: state => state.diffs.renderOverflowWarning, numTotalFiles: state => state.diffs.realSize, numVisibleFiles: state => state.diffs.size, @@ -123,19 +122,9 @@ export default { ...mapState('diffs', ['showTreeList', 'isLoading', 'startVersion']), ...mapGetters('diffs', ['isParallelView', 'currentDiffIndex']), ...mapGetters(['isNotesFetched', 'getNoteableData']), - targetBranch() { - return { - branchName: this.targetBranchName, - versionIndex: -1, - path: '', - }; - }, canCurrentUserFork() { return this.currentUser.can_fork === true && this.currentUser.can_create_merge_request; }, - showCompareVersions() { - return this.mergeRequestDiffs && this.mergeRequestDiff; - }, renderDiffFiles() { return ( this.diffFiles.length > 0 || @@ -369,8 +358,6 @@ export default { <div v-else id="diffs" :class="{ active: shouldShow }" class="diffs tab-pane"> <compare-versions :merge-request-diffs="mergeRequestDiffs" - :merge-request-diff="mergeRequestDiff" - :target-branch="targetBranch" :is-limited-container="isLimitedContainer" :diff-files-length="diffFilesLength" /> diff --git a/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue b/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue new file mode 100644 index 00000000000..ed4edabd81c --- /dev/null +++ b/app/assets/javascripts/diffs/components/compare_dropdown_layout.vue @@ -0,0 +1,78 @@ +<script> +import Icon from '~/vue_shared/components/icon.vue'; +import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; + +export default { + components: { + Icon, + TimeAgo, + }, + props: { + versions: { + type: Array, + required: true, + }, + }, + computed: { + selectedVersionName() { + return this.versions.find(x => x.selected)?.versionName || ''; + }, + }, +}; +</script> + +<template> + <span class="dropdown inline"> + <a + class="dropdown-menu-toggle btn btn-default w-100" + data-toggle="dropdown" + aria-expanded="false" + > + <span> {{ selectedVersionName }} </span> + <icon :size="12" name="angle-down" class="position-absolute" /> + </a> + <div class="dropdown-menu dropdown-select dropdown-menu-selectable"> + <div class="dropdown-content"> + <ul> + <li v-for="version in versions" :key="version.id"> + <a :class="{ 'is-active': version.selected }" :href="version.href"> + <div> + <strong> + {{ version.versionName }} + <template v-if="version.isHead">{{ + s__('DiffsCompareBaseBranch|(HEAD)') + }}</template> + <template v-else-if="version.isBase">{{ + s__('DiffsCompareBaseBranch|(base)') + }}</template> + </strong> + </div> + <div> + <small class="commit-sha"> {{ version.short_commit_sha }} </small> + </div> + <div> + <small> + <template v-if="version.commitsText"> + {{ version.commitsText }} + </template> + <time-ago + v-if="version.created_at" + :time="version.created_at" + class="js-timeago" + /> + </small> + </div> + </a> + </li> + </ul> + </div> + </div> + </span> +</template> + +<style> +.dropdown { + min-width: 0; + max-height: 170px; +} +</style> diff --git a/app/assets/javascripts/diffs/components/compare_versions.vue b/app/assets/javascripts/diffs/components/compare_versions.vue index 34716c214c6..c680c3f4600 100644 --- a/app/assets/javascripts/diffs/components/compare_versions.vue +++ b/app/assets/javascripts/diffs/components/compare_versions.vue @@ -4,14 +4,14 @@ import { GlTooltipDirective, GlLink, GlDeprecatedButton, GlSprintf } from '@gitl import { __ } from '~/locale'; import { polyfillSticky } from '~/lib/utils/sticky'; import Icon from '~/vue_shared/components/icon.vue'; -import CompareVersionsDropdown from './compare_versions_dropdown.vue'; +import CompareDropdownLayout from './compare_dropdown_layout.vue'; import SettingsDropdown from './settings_dropdown.vue'; import DiffStats from './diff_stats.vue'; import { CENTERED_LIMITED_CONTAINER_CLASSES } from '../constants'; export default { components: { - CompareVersionsDropdown, + CompareDropdownLayout, Icon, GlLink, GlDeprecatedButton, @@ -27,16 +27,6 @@ export default { type: Array, required: true, }, - mergeRequestDiff: { - type: Object, - required: false, - default: () => ({}), - }, - targetBranch: { - type: Object, - required: false, - default: null, - }, isLimitedContainer: { type: Boolean, required: false, @@ -48,7 +38,11 @@ export default { }, }, computed: { - ...mapGetters('diffs', ['hasCollapsedFile']), + ...mapGetters('diffs', [ + 'hasCollapsedFile', + 'diffCompareDropdownTargetVersions', + 'diffCompareDropdownSourceVersions', + ]), ...mapState('diffs', [ 'commit', 'showTreeList', @@ -57,18 +51,12 @@ export default { 'addedLines', 'removedLines', ]), - comparableDiffs() { - return this.mergeRequestDiffs.slice(1); - }, showDropdowns() { return !this.commit && this.mergeRequestDiffs.length; }, toggleFileBrowserTitle() { return this.showTreeList ? __('Hide file browser') : __('Show file browser'); }, - baseVersionPath() { - return this.mergeRequestDiff.base_version_path; - }, }, created() { this.CENTERED_LIMITED_CONTAINER_CLASSES = CENTERED_LIMITED_CONTAINER_CLASSES; @@ -113,19 +101,14 @@ export default { :message="s__('MergeRequest|Compare %{source} and %{target}')" > <template #source> - <compare-versions-dropdown - :other-versions="mergeRequestDiffs" - :merge-request-version="mergeRequestDiff" - :show-commit-count="true" + <compare-dropdown-layout + :versions="diffCompareDropdownSourceVersions" class="mr-version-dropdown" /> </template> <template #target> - <compare-versions-dropdown - :other-versions="comparableDiffs" - :base-version-path="baseVersionPath" - :start-version="startVersion" - :target-branch="targetBranch" + <compare-dropdown-layout + :versions="diffCompareDropdownTargetVersions" class="mr-version-compare-dropdown" /> </template> diff --git a/app/assets/javascripts/diffs/components/compare_versions_dropdown.vue b/app/assets/javascripts/diffs/components/compare_versions_dropdown.vue deleted file mode 100644 index cc4b2dacab3..00000000000 --- a/app/assets/javascripts/diffs/components/compare_versions_dropdown.vue +++ /dev/null @@ -1,162 +0,0 @@ -<script> -import Icon from '~/vue_shared/components/icon.vue'; -import { n__, __, sprintf } from '~/locale'; -import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils'; -import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; - -export default { - components: { - Icon, - TimeAgo, - }, - props: { - otherVersions: { - type: Array, - required: false, - default: () => [], - }, - mergeRequestVersion: { - type: Object, - required: false, - default: null, - }, - startVersion: { - type: Object, - required: false, - default: null, - }, - targetBranch: { - type: Object, - required: false, - default: null, - }, - showCommitCount: { - type: Boolean, - required: false, - default: false, - }, - baseVersionPath: { - type: String, - required: false, - default: null, - }, - }, - computed: { - targetVersions() { - if (this.mergeRequestVersion) { - return this.otherVersions; - } - return [...this.otherVersions, this.targetBranch]; - }, - selectedVersionName() { - const selectedVersion = this.startVersion || this.targetBranch || this.mergeRequestVersion; - return this.versionName(selectedVersion); - }, - }, - methods: { - commitsText(version) { - return n__(`%d commit,`, `%d commits,`, version.commits_count); - }, - href(version) { - if (this.isBase(version)) { - return this.baseVersionPath; - } - if (this.showCommitCount) { - return version.version_path; - } - return version.compare_path; - }, - versionName(version) { - if (this.isLatest(version)) { - return __('latest version'); - } - if (this.targetBranch && (this.isBase(version) || !version)) { - return this.targetBranch.branchName; - } - return sprintf(__(`version %{versionIndex}`), { versionIndex: version.version_index }); - }, - isActive(version) { - if (!version) { - return false; - } - - if (this.targetBranch) { - return ( - (this.isBase(version) && !this.startVersion) || - (this.startVersion && this.startVersion.version_index === version.version_index) - ); - } - - return version.version_index === this.mergeRequestVersion.version_index; - }, - isBase(version) { - if (!version || !this.targetBranch) { - return false; - } - return version.versionIndex === -1; - }, - isHead() { - return parseBoolean(getParameterByName('diff_head')); - }, - isLatest(version) { - return ( - this.mergeRequestVersion && version.version_index === this.targetVersions[0].version_index - ); - }, - }, -}; -</script> - -<template> - <span class="dropdown inline"> - <a - class="dropdown-menu-toggle btn btn-default w-100" - data-toggle="dropdown" - aria-expanded="false" - > - <span> {{ selectedVersionName }} </span> - <icon :size="12" name="angle-down" class="position-absolute" /> - </a> - <div class="dropdown-menu dropdown-select dropdown-menu-selectable"> - <div class="dropdown-content"> - <ul> - <li v-for="version in targetVersions" :key="version.id"> - <a :class="{ 'is-active': isActive(version) }" :href="href(version)"> - <div> - <strong> - {{ versionName(version) }} - <template v-if="isHead()">{{ s__('DiffsCompareBaseBranch|(HEAD)') }}</template> - <template v-else-if="isBase(version)">{{ - s__('DiffsCompareBaseBranch|(base)') - }}</template> - </strong> - </div> - <div> - <small class="commit-sha"> {{ version.short_commit_sha }} </small> - </div> - <div> - <small> - <template v-if="showCommitCount"> - {{ commitsText(version) }} - </template> - <time-ago - v-if="version.created_at" - :time="version.created_at" - class="js-timeago" - /> - </small> - </div> - </a> - </li> - </ul> - </div> - </div> - </span> -</template> - -<style> -.dropdown { - min-width: 0; - max-height: 170px; -} -</style> diff --git a/app/assets/javascripts/diffs/constants.js b/app/assets/javascripts/diffs/constants.js index 7521f3c950a..b07dfe5f33d 100644 --- a/app/assets/javascripts/diffs/constants.js +++ b/app/assets/javascripts/diffs/constants.js @@ -58,3 +58,5 @@ export const START_RENDERING_INDEX = 200; export const INLINE_DIFF_LINES_KEY = 'highlighted_diff_lines'; export const PARALLEL_DIFF_LINES_KEY = 'parallel_diff_lines'; export const DIFFS_PER_PAGE = 20; + +export const DIFF_COMPARE_BASE_VERSION_INDEX = -1; diff --git a/app/assets/javascripts/diffs/store/getters.js b/app/assets/javascripts/diffs/store/getters.js index 3898974638f..047caed1e63 100644 --- a/app/assets/javascripts/diffs/store/getters.js +++ b/app/assets/javascripts/diffs/store/getters.js @@ -1,6 +1,8 @@ import { __, n__ } from '~/locale'; import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '../constants'; +export * from './getters_versions_dropdowns'; + export const isParallelView = state => state.diffViewType === PARALLEL_DIFF_VIEW_TYPE; export const isInlineView = state => state.diffViewType === INLINE_DIFF_VIEW_TYPE; diff --git a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js new file mode 100644 index 00000000000..14c51602f28 --- /dev/null +++ b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js @@ -0,0 +1,43 @@ +import { __, n__, sprintf } from '~/locale'; +import { DIFF_COMPARE_BASE_VERSION_INDEX } from '../constants'; + +export const selectedTargetIndex = state => + state.startVersion?.version_index || DIFF_COMPARE_BASE_VERSION_INDEX; + +export const selectedSourceIndex = state => state.mergeRequestDiff.version_index; + +export const diffCompareDropdownTargetVersions = (state, getters) => { + // startVersion only exists if the user has selected a version other + // than "base" so if startVersion is null then base must be selected + const baseVersion = { + versionName: state.targetBranchName, + version_index: DIFF_COMPARE_BASE_VERSION_INDEX, + href: state.mergeRequestDiff.base_version_path, + isBase: true, + selected: !state.startVersion, + }; + // Appended properties here are to make the compare_dropdown_layout easier to reason about + const formatVersion = v => { + return { + href: v.compare_path, + versionName: sprintf(__(`version %{versionIndex}`), { versionIndex: v.version_index }), + selected: v.version_index === getters.selectedTargetIndex, + ...v, + }; + }; + return [...state.mergeRequestDiffs.slice(1).map(formatVersion), baseVersion]; +}; + +export const diffCompareDropdownSourceVersions = (state, getters) => { + // Appended properties here are to make the compare_dropdown_layout easier to reason about + return state.mergeRequestDiffs.map((v, i) => ({ + ...v, + href: v.version_path, + commitsText: n__(`%d commit,`, `%d commits,`, v.commits_count), + versionName: + i === 0 + ? __('latest version') + : sprintf(__(`version %{versionIndex}`), { versionIndex: v.version_index }), + selected: v.version_index === getters.selectedSourceIndex, + })); +}; diff --git a/app/assets/javascripts/diffs/store/modules/diff_state.js b/app/assets/javascripts/diffs/store/modules/diff_state.js index 81f1506260c..87938ababed 100644 --- a/app/assets/javascripts/diffs/store/modules/diff_state.js +++ b/app/assets/javascripts/diffs/store/modules/diff_state.js @@ -15,7 +15,7 @@ export default () => ({ endpoint: '', basePath: '', commit: null, - startVersion: null, + startVersion: null, // Null unless a target diff is selected for comparison that is not the "base" diff diffFiles: [], coverageFiles: {}, mergeRequestDiffs: [], diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index 16351baedb7..9cb592ceedb 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -1,10 +1,12 @@ <script> import { mapActions } from 'vuex'; -import timeAgoTooltip from '../../vue_shared/components/time_ago_tooltip.vue'; +import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; +import GitlabTeamMemberBadge from '~/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue'; export default { components: { timeAgoTooltip, + GitlabTeamMemberBadge, }, props: { author: { @@ -48,6 +50,9 @@ export default { hasAuthor() { return this.author && Object.keys(this.author).length; }, + showGitlabTeamMemberBadge() { + return this.author?.is_gitlab_employee; + }, }, methods: { ...mapActions(['setTargetNoteHash']), @@ -73,19 +78,21 @@ export default { {{ __('Toggle thread') }} </button> </div> - <a - v-if="hasAuthor" - v-once - :href="author.path" - class="js-user-link" - :data-user-id="author.id" - :data-username="author.username" - > - <slot name="note-header-info"></slot> - <span class="note-header-author-name bold">{{ author.name }}</span> - <span v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span> - <span class="note-headline-light">@{{ author.username }}</span> - </a> + <template v-if="hasAuthor"> + <a + v-once + :href="author.path" + class="js-user-link" + :data-user-id="author.id" + :data-username="author.username" + > + <slot name="note-header-info"></slot> + <span class="note-header-author-name bold">{{ author.name }}</span> + <span v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span> + <span class="note-headline-light">@{{ author.username }}</span> + </a> + <gitlab-team-member-badge v-if="showGitlabTeamMemberBadge" /> + </template> <span v-else>{{ __('A deleted user') }}</span> <span class="note-headline-light note-headline-meta"> <span class="system-note-message"> <slot></slot> </span> diff --git a/app/assets/javascripts/pages/projects/services/edit/index.js b/app/assets/javascripts/pages/projects/services/edit/index.js index 56016cb980c..49862b64c27 100644 --- a/app/assets/javascripts/pages/projects/services/edit/index.js +++ b/app/assets/javascripts/pages/projects/services/edit/index.js @@ -1,16 +1,17 @@ import IntegrationSettingsForm from '~/integrations/integration_settings_form'; -import PrometheusMetrics from '~/prometheus_metrics/prometheus_metrics'; +import PrometheusMetrics from 'ee_else_ce/prometheus_metrics/prometheus_metrics'; import PrometheusAlerts from '~/prometheus_alerts'; import initAlertsSettings from '~/alerts_service_settings'; document.addEventListener('DOMContentLoaded', () => { - const prometheusSettingsWrapper = document.querySelector('.js-prometheus-metrics-monitoring'); const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); integrationSettingsForm.init(); + const prometheusSettingsSelector = '.js-prometheus-metrics-monitoring'; + const prometheusSettingsWrapper = document.querySelector(prometheusSettingsSelector); if (prometheusSettingsWrapper) { - const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring'); - prometheusMetrics.loadActiveMetrics(); + const prometheusMetrics = new PrometheusMetrics(prometheusSettingsSelector); + prometheusMetrics.init(); } PrometheusAlerts(); diff --git a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js index 8d779e04673..59d47ae4155 100644 --- a/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js +++ b/app/assets/javascripts/prometheus_metrics/prometheus_metrics.js @@ -28,6 +28,10 @@ export default class PrometheusMetrics { this.$panelToggle.on('click', e => this.handlePanelToggle(e)); } + init() { + this.loadActiveMetrics(); + } + /* eslint-disable class-methods-use-this */ handlePanelToggle(e) { const $toggleBtn = $(e.currentTarget); diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue b/app/assets/javascripts/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue new file mode 100644 index 00000000000..527cbd458e2 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue @@ -0,0 +1,27 @@ +<script> +import { GlTooltipDirective, GlIcon } from '@gitlab/ui'; +import { __ } from '~/locale'; + +const GITLAB_TEAM_MEMBER_LABEL = __('GitLab Team Member'); + +export default { + name: 'GitlabTeamMemberBadge', + directives: { + GlTooltip: GlTooltipDirective, + }, + components: { GlIcon }, + gitlabTeamMemberLabel: GITLAB_TEAM_MEMBER_LABEL, +}; +</script> + +<template> + <span + v-gl-tooltip.hover + :title="$options.gitlabTeamMemberLabel" + role="img" + :aria-label="$options.gitlabTeamMemberLabel" + class="d-inline-block align-middle" + > + <gl-icon name="tanuki-verified" class="gl-text-purple d-block" /> + </span> +</template> diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index af512ac6f07..726ce8974c7 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -180,7 +180,7 @@ class Projects::PipelinesController < Projects::ApplicationController render json: TestReportSerializer .new(current_user: @current_user) - .represent(test_reports) + .represent(test_reports, project: project) end end end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 75cd6c78a52..c96599f9958 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -3,11 +3,6 @@ class SearchService include Gitlab::Allowable - REDACTABLE_RESULTS = [ - ActiveRecord::Relation, - Gitlab::Search::FoundBlob - ].freeze - SEARCH_TERM_LIMIT = 64 SEARCH_CHAR_LIMIT = 4096 @@ -68,10 +63,6 @@ class SearchService @search_objects ||= redact_unauthorized_results(search_results.objects(scope, params[:page])) end - def redactable_results - REDACTABLE_RESULTS - end - private def visible_result?(object) @@ -80,12 +71,9 @@ class SearchService Ability.allowed?(current_user, :"read_#{object.to_ability_name}", object) end - def redact_unauthorized_results(results) - return results unless redactable_results.any? { |redactable| results.is_a?(redactable) } - - permitted_results = results.select do |object| - visible_result?(object) - end + def redact_unauthorized_results(results_collection) + results = results_collection.to_a + permitted_results = results.select { |object| visible_result?(object) } filtered_results = (results - permitted_results).each_with_object({}) do |object, memo| memo[object.id] = { ability: :"read_#{object.to_ability_name}", id: object.id, class_name: object.class.name } @@ -93,13 +81,13 @@ class SearchService log_redacted_search_results(filtered_results.values) if filtered_results.any? - return results.id_not_in(filtered_results.keys) if results.is_a?(ActiveRecord::Relation) + return results_collection.id_not_in(filtered_results.keys) if results_collection.is_a?(ActiveRecord::Relation) Kaminari.paginate_array( permitted_results, - total_count: results.total_count, - limit: results.limit_value, - offset: results.offset_value + total_count: results_collection.total_count, + limit: results_collection.limit_value, + offset: results_collection.offset_value ) end diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml index e47967ef622..60c9c076a70 100644 --- a/app/views/shared/groups/_group.html.haml +++ b/app/views/shared/groups/_group.html.haml @@ -16,7 +16,7 @@ .avatar-container.rect-avatar.s40 = link_to group do - = group_icon(group, class: "avatar s40 d-none d-sm-block") + = group_icon(group, class: "avatar s40") .title = link_to group.full_name, group, class: 'group-name' |