Commit 7cdd9dcf authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 51a19eb33cee
......@@ -209,7 +209,7 @@ review-qa-all:
when: manual
parallel: 5
script:
- export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/review-qa-all_master_report.json
- export KNAPSACK_REPORT_PATH=knapsack/master_report.json
- export KNAPSACK_TEST_FILE_PATTERN=qa/specs/features/**/*_spec.rb
- gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}" -- --format RspecJunitFormatter --out tmp/rspec-${CI_JOB_ID}.xml --format html --out tmp/rspec.htm --color --format documentation
......
......@@ -2,9 +2,9 @@
## Canonical source
The canonical source of GitLab where development takes place is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab).
The canonical source of GitLab where all development takes place is [hosted on GitLab.com](https://gitlab.com/gitlab-org/gitlab).
A FOSS source of GitLab is hosted on a [mirrored, read-only project on GitLab.com](https://gitlab.com/gitlab-org/gitlab-foss/).
If you wish to clone a copy of GitLab without proprietary code, you can use the read-only mirror of GitLab located at https://gitlab.com/gitlab-org/gitlab-foss/. Please do not submit any issues and/or merge requests to this project.
## Free trial
......
export default {
data() {
return {
isCustomStageForm: false,
};
},
methods: {
showAddStageForm: () => {},
hideAddStageForm: () => {},
},
};
......@@ -3,7 +3,6 @@ import Vue from 'vue';
import Cookies from 'js-cookie';
import { GlEmptyState } from '@gitlab/ui';
import filterMixins from 'ee_else_ce/analytics/cycle_analytics/mixins/filter_mixins';
import addStageMixin from 'ee_else_ce/analytics/cycle_analytics/mixins/add_stage_mixin';
import Flash from '../flash';
import { __ } from '~/locale';
import Translate from '../vue_shared/translate';
......@@ -44,14 +43,8 @@ export default () => {
DateRangeDropdown: () =>
import('ee_component/analytics/shared/components/date_range_dropdown.vue'),
'stage-nav-item': stageNavItem,
CustomStageForm: () =>
import('ee_component/analytics/cycle_analytics/components/custom_stage_form.vue'),
AddStageButton: () =>
import('ee_component/analytics/cycle_analytics/components/add_stage_button.vue'),
CustomStageFormContainer: () =>
import('ee_component/analytics/cycle_analytics/components/custom_stage_form_container.vue'),
},
mixins: [filterMixins, addStageMixin],
mixins: [filterMixins],
data() {
return {
store: CycleAnalyticsStore,
......@@ -131,7 +124,6 @@ export default () => {
return;
}
this.hideAddStageForm();
this.isLoadingStage = true;
this.store.setStageEvents([], stage);
this.store.setActiveStage(stage);
......
......@@ -152,6 +152,14 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
branch: getters.branchName,
})
.then(() => {
commit(rootTypes.CLEAR_STAGED_CHANGES, null, { root: true });
commit(rootTypes.CLEAR_REPLACED_FILES, null, { root: true });
setTimeout(() => {
commit(rootTypes.SET_LAST_COMMIT_MSG, '', { root: true });
}, 5000);
if (state.shouldCreateMR) {
const { currentProject } = rootGetters;
const targetBranch = getters.isCreatingNewBranch
......@@ -164,14 +172,6 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
{ root: true },
);
}
commit(rootTypes.CLEAR_STAGED_CHANGES, null, { root: true });
commit(rootTypes.CLEAR_REPLACED_FILES, null, { root: true });
setTimeout(() => {
commit(rootTypes.SET_LAST_COMMIT_MSG, '', { root: true });
}, 5000);
})
.then(() => {
if (rootGetters.lastOpenedFile) {
......
<script>
import { __ } from '~/locale';
import { s__, __ } from '~/locale';
import { GlLink, GlButton } from '@gitlab/ui';
import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat';
......@@ -52,6 +52,16 @@ export default {
required: false,
default: () => [],
},
legendAverageText: {
type: String,
required: false,
default: s__('Metrics|Avg'),
},
legendMaxText: {
type: String,
required: false,
default: s__('Metrics|Max'),
},
},
data() {
return {
......@@ -260,7 +270,6 @@ export default {
<slot></slot>
</div>
</div>
<component
:is="glChartComponent"
ref="chart"
......@@ -271,6 +280,8 @@ export default {
:thresholds="thresholds"
:width="width"
:height="height"
:average-text="legendAverageText"
:max-text="legendMaxText"
@updated="onChartUpdated"
>
<template v-if="tooltip.isDeployment">
......
......@@ -81,7 +81,7 @@ def standard_links(host, namespace, project, commit)
end
def relative_self_links(relative_path, commit, project)
relative_path.rstrip!
relative_path = relative_path.rstrip
absolute_project_path = "/" + project.full_path
# Resolve `relative_path` to target path
......
......@@ -85,7 +85,7 @@ def import_issues_csv_email(user_id, project_id, results)
@project = Project.find(project_id)
@results = results
mail(to: recipient(@user.id, @project.group), subject: subject('Imported issues')) do |format|
mail(to: @user.notification_email_for(@project.group), subject: subject('Imported issues')) do |format|
format.html { render layout: 'mailer' }
format.text { render layout: 'mailer' }
end
......@@ -105,7 +105,7 @@ def setup_issue_mail(issue_id, recipient_id, closed_via: nil)
def issue_thread_options(sender_id, recipient_id, reason)
{
from: sender(sender_id),
to: recipient(recipient_id, @project.group),
to: User.find(recipient_id).notification_email_for(@project.group),
subject: subject("#{@issue.title} (##{@issue.iid})"),
'X-GitLab-NotificationReason' => reason
}
......
......@@ -13,7 +13,9 @@ def member_access_requested_email(member_source_type, member_id, recipient_id)
@member_source_type = member_source_type
@member_id = member_id
mail(to: recipient(recipient_id, notification_group),
user = User.find(recipient_id)
mail(to: user.notification_email_for(notification_group),
subject: subject("Request to join the #{member_source.human_name} #{member_source.model_name.singular}"))
end
......@@ -21,7 +23,7 @@ def member_access_granted_email(member_source_type, member_id)
@member_source_type = member_source_type
@member_id = member_id
mail(to: recipient(member.user, notification_group),
mail(to: member.user.notification_email_for(notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was granted"))
end
......@@ -29,7 +31,9 @@ def member_access_denied_email(member_source_type, source_id, user_id)
@member_source_type = member_source_type
@member_source = member_source_class.find(source_id)
mail(to: recipient(user_id, notification_group),
user = User.find(user_id)
mail(to: user.notification_email_for(notification_group),
subject: subject("Access to the #{member_source.human_name} #{member_source.model_name.singular} was denied"))
end
......@@ -47,7 +51,7 @@ def member_invite_accepted_email(member_source_type, member_id)
@member_id = member_id
return unless member.created_by
mail(to: recipient(member.created_by, notification_group),
mail(to: member.created_by.notification_email_for(notification_group),
subject: subject('Invitation accepted'))
end
......@@ -58,7 +62,9 @@ def member_invite_declined_email(member_source_type, source_id, invite_email, cr
@member_source = member_source_class.find(source_id)
@invite_email = invite_email
mail(to: recipient(created_by_id, notification_group),
user = User.find(created_by_id)
mail(to: user.notification_email_for(notification_group),
subject: subject('Invitation declined'))
end
......
......@@ -110,7 +110,7 @@ def setup_merge_request_mail(merge_request_id, recipient_id, present: false)
def merge_request_thread_options(sender_id, recipient_id, reason = nil)
{
from: sender(sender_id),
to: recipient(recipient_id, @project.group),
to: User.find(recipient_id).notification_email_for(@project.group),
subject: subject("#{@merge_request.title} (#{@merge_request.to_reference})"),
'X-GitLab-NotificationReason' => reason
}
......
......@@ -55,7 +55,7 @@ def note_target_url_query_params
def note_thread_options(recipient_id, reason)
{
from: sender(@note.author_id),
to: recipient(recipient_id, @project&.group || @group),
to: User.find(recipient_id).notification_email_for(@project&.group || @group),
subject: subject("#{@note.noteable.title} (#{@note.noteable.reference_link_text})"),
'X-GitLab-NotificationReason' => reason
}
......
......@@ -7,7 +7,7 @@ def pages_domain_enabled_email(domain, recipient)
@project = domain.project
mail(
to: recipient(recipient.id, @project.group),
to: recipient.notification_email_for(@project.group),
subject: subject("GitLab Pages domain '#{domain.domain}' has been enabled")
)
end
......@@ -17,7 +17,7 @@ def pages_domain_disabled_email(domain, recipient)
@project = domain.project
mail(
to: recipient(recipient.id, @project.group),
to: recipient.notification_email_for(@project.group),
subject: subject("GitLab Pages domain '#{domain.domain}' has been disabled")
)
end
......@@ -27,7 +27,7 @@ def pages_domain_verification_succeeded_email(domain, recipient)
@project = domain.project
mail(
to: recipient(recipient.id, @project.group),
to: recipient.notification_email_for(@project.group),
subject: subject("Verification succeeded for GitLab Pages domain '#{domain.domain}'")
)
end
......@@ -37,7 +37,7 @@ def pages_domain_verification_failed_email(domain, recipient)
@project = domain.project
mail(
to: recipient(recipient.id, @project.group),
to: recipient.notification_email_for(@project.group),
subject: subject("ACTION REQUIRED: Verification failed for GitLab Pages domain '#{domain.domain}'")
)
end
......
......@@ -7,20 +7,20 @@ def project_was_moved_email(project_id, user_id, old_path_with_namespace)
@project = Project.find project_id
@target_url = project_url(@project)
@old_path_with_namespace = old_path_with_namespace
mail(to: recipient(user_id, @project.group),
mail(to: @user.notification_email_for(@project.group),
subject: subject("Project was moved"))
end
def project_was_exported_email(current_user, project)
@project = project
mail(to: recipient(current_user.id, project.group),
mail(to: current_user.notification_email_for(project.group),
subject: subject("Project was exported"))
end
def project_was_not_exported_email(current_user, project, errors)
@project = project
@errors = errors
mail(to: recipient(current_user.id, @project.group),
mail(to: current_user.notification_email_for(@project.group),
subject: subject("Project export error"))
end
......@@ -28,7 +28,7 @@ def repository_cleanup_success_email(project, user)
@project = project
@user = user
mail(to: recipient(user.id, project.group), subject: subject("Project cleanup has completed"))
mail(to: user.notification_email_for(project.group), subject: subject("Project cleanup has completed"))
end
def repository_cleanup_failure_email(project, user, error)
......@@ -36,7 +36,7 @@ def repository_cleanup_failure_email(project, user, error)
@user = user
@error = error
mail(to: recipient(user.id, project.group), subject: subject("Project cleanup failure"))
mail(to: user.notification_email_for(project.group), subject: subject("Project cleanup failure"))
end
def repository_push_email(project_id, opts = {})
......
......@@ -5,8 +5,9 @@ module RemoteMirrors
def remote_mirror_update_failed_email(remote_mirror_id, recipient_id)
@remote_mirror = RemoteMirror.find_by_id(remote_mirror_id)
@project = @remote_mirror.project
user = User.find(recipient_id)
mail(to: recipient(recipient_id, @project.group), subject: subject('Remote mirror update failed'))
mail(to: user.notification_email_for(@project.group), subject: subject('Remote mirror update failed'))
end
end
end
......@@ -71,20 +71,6 @@ def sender(sender_id, send_from_user_email = false)
address.format
end
# Look up a User's notification email for a particular context.
# Can look up by their ID or can accept a User object.
#
# recipient - User object OR a User ID
# notification_group - The parent group of the notification
#
# Returns a String containing the User's email address.
def recipient(recipient, notification_group = nil)
user = recipient if recipient.is_a?(User)
user ||= User.find(recipient)
user.notification_email_for(notification_group)
end
# Formats arguments into a String suitable for use as an email subject
#
# extra - Extra Strings to be inserted into the subject
......
......@@ -245,7 +245,6 @@ class Project < ApplicationRecord
has_one :cluster_project, class_name: 'Clusters::Project'
has_many :clusters, through: :cluster_project, class_name: 'Clusters::Cluster'
has_many :cluster_ingresses, through: :clusters, source: :application_ingress, class_name: 'Clusters::Applications::Ingress'
has_many :kubernetes_namespaces, class_name: 'Clusters::KubernetesNamespace'
has_many :prometheus_metrics
......
......@@ -17,7 +17,7 @@ def add_link(link)
end
def can_add_link?
available? && !link_in_issue_description?
can? && !link_in_issue_description?
end
def remove_link
......@@ -29,7 +29,7 @@ def remove_link
end
def can_remove_link?
available? && link_in_issue_description?
can? && link_in_issue_description?
end
def parse_link(link)
......@@ -75,14 +75,6 @@ def extract_link_from_issue_description
issue_description[/(\S+)\z/, 1]
end
def available?
feature_enabled? && can?
end
def feature_enabled?
Feature.enabled?(:issue_zoom_integration, project)
end
def can?
current_user.can?(:update_issue, project)
end
......
......@@ -43,6 +43,7 @@ def fork_new_project
shared_runners_enabled: @project.shared_runners_enabled,
namespace_id: target_namespace.id,
fork_network: fork_network,
ci_config_path: @project.ci_config_path,
# We need to set ci_default_git_depth to 0 for the forked project when
# @project.ci_default_git_depth is nil in order to keep the same behaviour
# and not get ProjectCiCdSetting::DEFAULT_GIT_DEPTH set on create
......
......@@ -21,7 +21,7 @@
- if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
%li.header-more.dropdown
%a{ href: "#", data: { toggle: "dropdown" } }
%a{ href: "#", data: { toggle: "dropdown", qa_selector: 'more_dropdown' } }
= _('More')
= sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu
......@@ -42,7 +42,7 @@
- if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets') do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets qa-snippets-link' do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets', data: { qa_selector: 'snippets_link' } do
= _('Snippets')
= render_if_exists 'layouts/nav/sidebar/analytics_more_link'
......
---
title: Refactor email notification code
merge_request: 17741
author: briankabiro
type: other
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment