summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/environments/components/environments_table.vue9
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_bundle.js22
-rw-r--r--app/assets/javascripts/environments/folder/environments_folder_view.vue3
-rw-r--r--app/assets/javascripts/environments/index.js21
-rw-r--r--app/assets/javascripts/environments/mixins/canary_callout_mixin.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue49
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js1
-rw-r--r--app/controllers/invites_controller.rb6
-rw-r--r--app/models/concerns/issuable.rb4
-rw-r--r--app/models/member.rb4
-rw-r--r--app/services/snippets/base_service.rb2
-rw-r--r--app/views/projects/environments/folder.html.haml2
-rw-r--r--app/views/projects/environments/index.html.haml3
-rw-r--r--app/views/shared/issuable/form/_metadata.html.haml2
15 files changed, 105 insertions, 26 deletions
diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue
index 1bf705dcda2..c06ab265915 100644
--- a/app/assets/javascripts/environments/components/environments_table.vue
+++ b/app/assets/javascripts/environments/components/environments_table.vue
@@ -14,6 +14,7 @@ export default {
DeployBoard: () => import('ee_component/environments/components/deploy_board_component.vue'),
CanaryDeploymentCallout: () =>
import('ee_component/environments/components/canary_deployment_callout.vue'),
+ EnvironmentAlert: () => import('ee_component/environments/components/environment_alert.vue'),
},
props: {
environments: {
@@ -111,6 +112,9 @@ export default {
shouldShowCanaryCallout(env) {
return env.showCanaryCallout && this.showCanaryDeploymentCallout;
},
+ shouldRenderAlert(env) {
+ return env?.has_opened_alert;
+ },
sortEnvironments(environments) {
/*
* The sorting algorithm should sort in the following priorities:
@@ -185,6 +189,11 @@ export default {
/>
</div>
</div>
+ <environment-alert
+ v-if="shouldRenderAlert(model)"
+ :key="`alert-row-${i}`"
+ :environment="model"
+ />
<template v-if="shouldRenderFolderContent(model)">
<div v-if="model.isLoadingFolderContent" :key="`loading-item-${i}`">
diff --git a/app/assets/javascripts/environments/folder/environments_folder_bundle.js b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
index 56896ac4d43..6c547c3713a 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_bundle.js
+++ b/app/assets/javascripts/environments/folder/environments_folder_bundle.js
@@ -1,20 +1,33 @@
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
import canaryCalloutMixin from '../mixins/canary_callout_mixin';
import environmentsFolderApp from './environments_folder_view.vue';
import { parseBoolean } from '../../lib/utils/common_utils';
import Translate from '../../vue_shared/translate';
+import createDefaultClient from '~/lib/graphql';
Vue.use(Translate);
+Vue.use(VueApollo);
-export default () =>
- new Vue({
- el: '#environments-folder-list-view',
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
+
+export default () => {
+ const el = document.getElementById('environments-folder-list-view');
+
+ return new Vue({
+ el,
components: {
environmentsFolderApp,
},
mixins: [canaryCalloutMixin],
+ apolloProvider,
+ provide: {
+ projectPath: el.dataset.projectPath,
+ },
data() {
- const environmentsData = document.querySelector(this.$options.el).dataset;
+ const environmentsData = el.dataset;
return {
endpoint: environmentsData.environmentsDataEndpoint,
@@ -35,3 +48,4 @@ export default () =>
});
},
});
+};
diff --git a/app/assets/javascripts/environments/folder/environments_folder_view.vue b/app/assets/javascripts/environments/folder/environments_folder_view.vue
index e1e356a977f..16d25615779 100644
--- a/app/assets/javascripts/environments/folder/environments_folder_view.vue
+++ b/app/assets/javascripts/environments/folder/environments_folder_view.vue
@@ -23,7 +23,8 @@ export default {
},
cssContainerClass: {
type: String,
- required: true,
+ required: false,
+ default: '',
},
canReadEnvironment: {
type: Boolean,
diff --git a/app/assets/javascripts/environments/index.js b/app/assets/javascripts/environments/index.js
index 4848cb0f13d..8e8af3f32f7 100644
--- a/app/assets/javascripts/environments/index.js
+++ b/app/assets/javascripts/environments/index.js
@@ -1,20 +1,32 @@
import Vue from 'vue';
+import VueApollo from 'vue-apollo';
import canaryCalloutMixin from './mixins/canary_callout_mixin';
import environmentsComponent from './components/environments_app.vue';
import { parseBoolean } from '../lib/utils/common_utils';
import Translate from '../vue_shared/translate';
+import createDefaultClient from '~/lib/graphql';
Vue.use(Translate);
+Vue.use(VueApollo);
-export default () =>
- new Vue({
- el: '#environments-list-view',
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
+
+export default () => {
+ const el = document.getElementById('environments-list-view');
+ return new Vue({
+ el,
components: {
environmentsComponent,
},
mixins: [canaryCalloutMixin],
+ apolloProvider,
+ provide: {
+ projectPath: el.dataset.projectPath,
+ },
data() {
- const environmentsData = document.querySelector(this.$options.el).dataset;
+ const environmentsData = el.dataset;
return {
endpoint: environmentsData.environmentsDataEndpoint,
@@ -39,3 +51,4 @@ export default () =>
});
},
});
+};
diff --git a/app/assets/javascripts/environments/mixins/canary_callout_mixin.js b/app/assets/javascripts/environments/mixins/canary_callout_mixin.js
index 398576a31cb..e9f1a144cb3 100644
--- a/app/assets/javascripts/environments/mixins/canary_callout_mixin.js
+++ b/app/assets/javascripts/environments/mixins/canary_callout_mixin.js
@@ -2,7 +2,7 @@ import { parseBoolean } from '~/lib/utils/common_utils';
export default {
data() {
- const data = document.querySelector(this.$options.el).dataset;
+ const data = this.$options.el.dataset;
return {
canaryDeploymentFeatureId: data.environmentsDataCanaryDeploymentFeatureId,
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
index 3e2c119fa7c..5066a88b52b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline.vue
@@ -1,8 +1,15 @@
<script>
/* eslint-disable vue/require-default-prop, vue/no-v-html */
-import { GlIcon, GlLink, GlLoadingIcon, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
+import {
+ GlIcon,
+ GlLink,
+ GlLoadingIcon,
+ GlSprintf,
+ GlTooltip,
+ GlTooltipDirective,
+} from '@gitlab/ui';
import mrWidgetPipelineMixin from 'ee_else_ce/vue_merge_request_widget/mixins/mr_widget_pipeline';
-import { s__ } from '~/locale';
+import { s__, n__ } from '~/locale';
import PipelineStage from '~/pipelines/components/pipelines_list/stage.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue';
@@ -15,6 +22,7 @@ export default {
GlLoadingIcon,
GlIcon,
GlSprintf,
+ GlTooltip,
PipelineStage,
TooltipOnTruncate,
LinkedPipelinesMiniList: () =>
@@ -33,6 +41,11 @@ export default {
type: String,
required: false,
},
+ buildsWithCoverage: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
// This prop needs to be camelCase, html attributes are case insensive
// https://vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case
hasCi: {
@@ -100,6 +113,16 @@ export default {
}
return '';
},
+ pipelineCoverageJobNumberText() {
+ return n__('from %d job', 'from %d jobs', this.buildsWithCoverage.length);
+ },
+ pipelineCoverageTooltipDescription() {
+ return n__(
+ 'Coverage value for this pipeline was calculated by the coverage value of %d job.',
+ 'Coverage value for this pipeline was calculated by averaging the resulting coverage values of %d jobs.',
+ this.buildsWithCoverage.length,
+ );
+ },
},
errorText: s__(
'Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}.',
@@ -139,7 +162,7 @@ export default {
>
<gl-icon
name="question"
- :small="12"
+ :size="12"
tabindex="0"
role="text"
:aria-label="__('Link to go to GitLab pipeline documentation')"
@@ -189,14 +212,30 @@ export default {
</div>
<div v-if="pipeline.coverage" class="coverage" data-testid="pipeline-coverage">
{{ s__('Pipeline|Coverage') }} {{ pipeline.coverage }}%
-
<span
v-if="pipelineCoverageDelta"
:class="coverageDeltaClass"
data-testid="pipeline-coverage-delta"
+ >({{ pipelineCoverageDelta }}%)</span
>
- ({{ pipelineCoverageDelta }}%)
+
+ {{ pipelineCoverageJobNumberText }}
+ <span ref="pipelineCoverageQuestion">
+ <gl-icon name="question" :size="12" />
</span>
+ <gl-tooltip
+ :target="() => $refs.pipelineCoverageQuestion"
+ data-testid="pipeline-coverage-tooltip"
+ >
+ {{ pipelineCoverageTooltipDescription }}
+ <div
+ v-for="(build, index) in buildsWithCoverage"
+ :key="`${build.name}-${index}`"
+ class="gl-mt-3 gl-text-left gl-px-4"
+ >
+ {{ build.name }} ({{ build.coverage }}%)
+ </div>
+ </gl-tooltip>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue
index 5c307b5ff0c..55efd7e7d3b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_pipeline_container.vue
@@ -77,6 +77,7 @@ export default {
<mr-widget-pipeline
:pipeline="pipeline"
:pipeline-coverage-delta="mr.pipelineCoverageDelta"
+ :builds-with-coverage="mr.buildsWithCoverage"
:ci-status="mr.ciStatus"
:has-ci="mr.hasCI"
:pipeline-must-succeed="mr.onlyAllowMergeIfPipelineSucceeds"
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 8c98ba1b023..5695e02bbab 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -52,6 +52,7 @@ export default class MergeRequestStore {
this.divergedCommitsCount = data.diverged_commits_count;
this.pipeline = data.pipeline || {};
this.pipelineCoverageDelta = data.pipeline_coverage_delta;
+ this.buildsWithCoverage = data.builds_with_coverage;
this.mergePipeline = data.merge_pipeline || {};
this.deployments = this.deployments || data.deployments || [];
this.postMergeDeployments = this.postMergeDeployments || [];
diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb
index aa02bc132f9..e65b27db3ae 100644
--- a/app/controllers/invites_controller.rb
+++ b/app/controllers/invites_controller.rb
@@ -76,8 +76,12 @@ class InvitesController < ApplicationController
notice << "or create an account" if Gitlab::CurrentSettings.allow_signup?
notice = notice.join(' ') + "."
+ initial_member = Member.find_by_invite_token(params[:id])
+ redirect_params = initial_member ? { invite_email: member.invite_email } : {}
+
store_location_for :user, request.fullpath
- redirect_to new_user_session_path(invite_email: member.invite_email), notice: notice
+
+ redirect_to new_user_session_path(redirect_params), notice: notice
end
def invite_details
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index a6986029f0d..78161a3b446 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -177,10 +177,6 @@ module Issuable
assignees.count > 1
end
- def supports_weight?
- false
- end
-
def supports_time_tracking?
is_a?(TimeTrackable) && !incident?
end
diff --git a/app/models/member.rb b/app/models/member.rb
index 1913df61614..55bb78b7f94 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -161,8 +161,8 @@ class Member < ApplicationRecord
where(user_id: user_ids).has_access.pluck(:user_id, :access_level).to_h
end
- def find_by_invite_token(invite_token)
- invite_token = Devise.token_generator.digest(self, :invite_token, invite_token)
+ def find_by_invite_token(raw_invite_token)
+ invite_token = Devise.token_generator.digest(self, :invite_token, raw_invite_token)
find_by(invite_token: invite_token)
end
diff --git a/app/services/snippets/base_service.rb b/app/services/snippets/base_service.rb
index d9e8326f159..53a04e5a398 100644
--- a/app/services/snippets/base_service.rb
+++ b/app/services/snippets/base_service.rb
@@ -46,7 +46,7 @@ module Snippets
snippet.errors.add(:snippet_actions, 'have invalid data')
end
- snippet_error_response(snippet, 403)
+ snippet_error_response(snippet, 422)
end
def snippet_error_response(snippet, http_status)
diff --git a/app/views/projects/environments/folder.html.haml b/app/views/projects/environments/folder.html.haml
index cd24c30e46f..554cb4323f7 100644
--- a/app/views/projects/environments/folder.html.haml
+++ b/app/views/projects/environments/folder.html.haml
@@ -2,4 +2,4 @@
- breadcrumb_title _("Folder/%{name}") % { name: @folder }
- page_title _("Environments in %{name}") % { name: @folder }
-#environments-folder-list-view{ data: { environments_data: environments_folder_list_view_data } }
+#environments-folder-list-view{ data: { environments_data: environments_folder_list_view_data, project_path: @project.full_path } }
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index 445196ed449..9abc1a5a925 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -5,4 +5,5 @@
"can-create-environment" => can?(current_user, :create_environment, @project).to_s,
"new-environment-path" => new_project_environment_path(@project),
"help-page-path" => help_page_path("ci/environments/index.md"),
- "deploy-boards-help-path" => help_page_path("user/project/deploy_boards", anchor: "enabling-deploy-boards") } }
+ "deploy-boards-help-path" => help_page_path("user/project/deploy_boards", anchor: "enabling-deploy-boards"),
+ "project-path" => @project.full_path } }
diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml
index 82e435fe0d3..79e6f043b64 100644
--- a/app/views/shared/issuable/form/_metadata.html.haml
+++ b/app/views/shared/issuable/form/_metadata.html.haml
@@ -30,7 +30,7 @@
= render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form
- - if has_due_date || issuable.supports_weight?
+ - if has_due_date
.col-lg-6
- if @issue[:issue_type] != 'incident'
= render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form