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
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 18:07:23 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 18:07:23 +0300
commit0b878def9bad1c36ea2b23380a77f9eedaaa6b83 (patch)
treeeb44c34bf05b2dbb1371d8553a7bb7b3d8a1989d /app
parentbdb1e64a7d620c203e5228717b7c464554b85f55 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue90
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue2
-rw-r--r--app/assets/stylesheets/pages/settings.scss7
-rw-r--r--app/controllers/groups_controller.rb2
-rw-r--r--app/controllers/projects/incidents_controller.rb2
-rw-r--r--app/graphql/mutations/saved_replies/base.rb2
-rw-r--r--app/graphql/mutations/saved_replies/destroy.rb23
-rw-r--r--app/graphql/mutations/saved_replies/update.rb2
-rw-r--r--app/graphql/types/mutation_type.rb1
-rw-r--r--app/helpers/emails_helper.rb17
-rw-r--r--app/mailers/emails/profile.rb11
-rw-r--r--app/mailers/previews/notify_preview.rb4
-rw-r--r--app/policies/user_policy.rb1
-rw-r--r--app/services/concerns/members/bulk_create_users.rb2
-rw-r--r--app/services/emails/base_service.rb4
-rw-r--r--app/services/emails/create_service.rb1
-rw-r--r--app/services/notification_service.rb7
-rw-r--r--app/services/users/saved_replies/destroy_service.rb23
-rw-r--r--app/services/users/saved_replies/update_service.rb5
-rw-r--r--app/views/notify/new_email_address_added_email.erb5
-rw-r--r--app/views/notify/new_email_address_added_email.haml6
21 files changed, 165 insertions, 52 deletions
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
index a532fa5b771..5caac3402c2 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -260,6 +260,9 @@ export default {
showCsvButtons() {
return this.isProject && this.isSignedIn;
},
+ showIssuableByEmail() {
+ return this.initialEmail && this.isSignedIn;
+ },
showNewIssueDropdown() {
return !this.isProject && this.hasAnyProjects;
},
@@ -624,8 +627,9 @@ export default {
</script>
<template>
- <div v-if="hasAnyIssues">
+ <div>
<issuable-list
+ v-if="hasAnyIssues"
:namespace="fullPath"
recent-searches-storage-key="issues"
:search-input-placeholder="$options.i18n.searchPlaceholder"
@@ -768,50 +772,50 @@ export default {
</template>
</issuable-list>
- <issuable-by-email v-if="initialEmail" class="gl-text-center gl-pt-5 gl-pb-7" />
- </div>
+ <template v-else-if="isSignedIn">
+ <gl-empty-state
+ :description="$options.i18n.noIssuesSignedInDescription"
+ :title="$options.i18n.noIssuesSignedInTitle"
+ :svg-path="emptyStateSvgPath"
+ >
+ <template #actions>
+ <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
+ {{ $options.i18n.newIssueLabel }}
+ </gl-button>
+ <csv-import-export-buttons
+ v-if="showCsvButtons"
+ class="gl-mr-3"
+ :export-csv-path="exportCsvPathWithQuery"
+ :issuable-count="currentTabCount"
+ />
+ <new-issue-dropdown v-if="showNewIssueDropdown" />
+ </template>
+ </gl-empty-state>
+ <hr />
+ <p class="gl-text-center gl-font-weight-bold gl-mb-0">
+ {{ $options.i18n.jiraIntegrationTitle }}
+ </p>
+ <p class="gl-text-center gl-mb-0">
+ <gl-sprintf :message="$options.i18n.jiraIntegrationMessage">
+ <template #jiraDocsLink="{ content }">
+ <gl-link :href="jiraIntegrationPath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <p class="gl-text-center gl-text-gray-500">
+ {{ $options.i18n.jiraIntegrationSecondaryMessage }}
+ </p>
+ </template>
- <div v-else-if="isSignedIn">
<gl-empty-state
- :description="$options.i18n.noIssuesSignedInDescription"
- :title="$options.i18n.noIssuesSignedInTitle"
+ v-else
+ :description="$options.i18n.noIssuesSignedOutDescription"
+ :title="$options.i18n.noIssuesSignedOutTitle"
:svg-path="emptyStateSvgPath"
- >
- <template #actions>
- <gl-button v-if="showNewIssueLink" :href="newIssuePath" variant="confirm">
- {{ $options.i18n.newIssueLabel }}
- </gl-button>
- <csv-import-export-buttons
- v-if="showCsvButtons"
- class="gl-mr-3"
- :export-csv-path="exportCsvPathWithQuery"
- :issuable-count="currentTabCount"
- />
- <new-issue-dropdown v-if="showNewIssueDropdown" />
- </template>
- </gl-empty-state>
- <hr />
- <p class="gl-text-center gl-font-weight-bold gl-mb-0">
- {{ $options.i18n.jiraIntegrationTitle }}
- </p>
- <p class="gl-text-center gl-mb-0">
- <gl-sprintf :message="$options.i18n.jiraIntegrationMessage">
- <template #jiraDocsLink="{ content }">
- <gl-link :href="jiraIntegrationPath">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
- <p class="gl-text-center gl-text-gray-500">
- {{ $options.i18n.jiraIntegrationSecondaryMessage }}
- </p>
- </div>
+ :primary-button-text="$options.i18n.noIssuesSignedOutButtonText"
+ :primary-button-link="signInPath"
+ />
- <gl-empty-state
- v-else
- :description="$options.i18n.noIssuesSignedOutDescription"
- :title="$options.i18n.noIssuesSignedOutTitle"
- :svg-path="emptyStateSvgPath"
- :primary-button-text="$options.i18n.noIssuesSignedOutButtonText"
- :primary-button-link="signInPath"
- />
+ <issuable-by-email v-if="showIssuableByEmail" class="gl-text-center gl-pt-5 gl-pb-7" />
+ </div>
</template>
diff --git a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
index 04ddc7f3501..27cd1eadd53 100644
--- a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
@@ -52,7 +52,7 @@ export default {
return this.$apollo.queries.alert.loading;
},
incidentTabEnabled() {
- return this.glFeatures.incidentTimelineEvents && this.glFeatures.incidentTimelineEventTab;
+ return this.glFeatures.incidentTimelineEvents && this.glFeatures.incidentTimeline;
},
},
mounted() {
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss
index 5956368a977..0c7b74684cc 100644
--- a/app/assets/stylesheets/pages/settings.scss
+++ b/app/assets/stylesheets/pages/settings.scss
@@ -110,9 +110,14 @@
.bs-callout,
.form-check:first-child,
- .form-text.text-muted {
+ .form-check .form-text.text-muted,
+ .form-check + .form-text.text-muted {
margin-top: 0;
}
+
+ .form-check .form-text.text-muted {
+ margin-bottom: $grid-size;
+ }
}
.settings-list-icon {
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index b53d9b1be04..2966adc0f23 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -218,6 +218,8 @@ class GroupsController < Groups::ApplicationController
@has_projects = group_projects.exists?
+ set_sort_order
+
respond_to do |format|
format.html
end
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
index 293581a6744..0c2f871a1f0 100644
--- a/app/controllers/projects/incidents_controller.rb
+++ b/app/controllers/projects/incidents_controller.rb
@@ -8,7 +8,7 @@ class Projects::IncidentsController < Projects::ApplicationController
before_action :load_incident, only: [:show]
before_action do
push_frontend_feature_flag(:incident_escalations, @project)
- push_frontend_feature_flag(:incident_timeline_event_tab, @project, default_enabled: :yaml)
+ push_frontend_feature_flag(:incident_timeline, @project, default_enabled: :yaml)
push_licensed_feature(:incident_timeline_events) if @project.licensed_feature_available?(:incident_timeline_events)
end
diff --git a/app/graphql/mutations/saved_replies/base.rb b/app/graphql/mutations/saved_replies/base.rb
index 468263b0f9d..59871df687f 100644
--- a/app/graphql/mutations/saved_replies/base.rb
+++ b/app/graphql/mutations/saved_replies/base.rb
@@ -5,7 +5,7 @@ module Mutations
class Base < BaseMutation
field :saved_reply, Types::SavedReplyType,
null: true,
- description: 'Updated saved reply.'
+ description: 'Saved reply after mutation.'
private
diff --git a/app/graphql/mutations/saved_replies/destroy.rb b/app/graphql/mutations/saved_replies/destroy.rb
new file mode 100644
index 00000000000..7cd0f21ad45
--- /dev/null
+++ b/app/graphql/mutations/saved_replies/destroy.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Mutations
+ module SavedReplies
+ class Destroy < Base
+ graphql_name 'SavedReplyDestroy'
+
+ authorize :destroy_saved_replies
+
+ argument :id, Types::GlobalIDType[::Users::SavedReply],
+ required: true,
+ description: copy_field_description(Types::SavedReplyType, :id)
+
+ def resolve(id:)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless feature_enabled?
+
+ saved_reply = authorized_find!(id)
+ result = ::Users::SavedReplies::DestroyService.new(saved_reply: saved_reply).execute
+ present_result(result)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/saved_replies/update.rb b/app/graphql/mutations/saved_replies/update.rb
index bacc6ceb39e..d9368de7547 100644
--- a/app/graphql/mutations/saved_replies/update.rb
+++ b/app/graphql/mutations/saved_replies/update.rb
@@ -23,7 +23,7 @@ module Mutations
raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless feature_enabled?
saved_reply = authorized_find!(id)
- result = ::Users::SavedReplies::UpdateService.new(current_user: current_user, saved_reply: saved_reply, name: name, content: content).execute
+ result = ::Users::SavedReplies::UpdateService.new(saved_reply: saved_reply, name: name, content: content).execute
present_result(result)
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index e6072820eea..2297912ac35 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -131,6 +131,7 @@ module Types
mount_mutation Mutations::WorkItems::Update
mount_mutation Mutations::SavedReplies::Create
mount_mutation Mutations::SavedReplies::Update
+ mount_mutation Mutations::SavedReplies::Destroy
end
end
diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb
index b804efb9561..79b04ae0e2b 100644
--- a/app/helpers/emails_helper.rb
+++ b/app/helpers/emails_helper.rb
@@ -206,6 +206,23 @@ module EmailsHelper
end
end
+ def new_email_address_added_text(email)
+ _('A new email address has been added to your GitLab account: %{email}') % { email: email }
+ end
+
+ def remove_email_address_text(format: nil)
+ url = profile_emails_url
+
+ case format
+ when :html
+ settings_link_to = generate_link(_('email address settings'), url).html_safe
+ _("If you want to remove this email address, visit the %{settings_link_to} page.").html_safe % { settings_link_to: settings_link_to }
+ else
+ _('If you want to remove this email address, visit %{profile_link}') %
+ { profile_link: url }
+ end
+ end
+
def admin_changed_password_text(format: nil)
url = Gitlab.config.gitlab.url
diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb
index 28e51ba311b..31fcc7c15cb 100644
--- a/app/mailers/emails/profile.rb
+++ b/app/mailers/emails/profile.rb
@@ -141,6 +141,17 @@ module Emails
end
end
+ def new_email_address_added_email(user, email)
+ return unless user
+
+ @user = user
+ @email = email
+
+ Gitlab::I18n.with_locale(@user.preferred_language) do
+ mail(to: @user.notification_email_or_default, subject: subject(_("New email address added")))
+ end
+ end
+
private
def profile_email_with_layout(to:, subject:, layout: 'mailer')
diff --git a/app/mailers/previews/notify_preview.rb b/app/mailers/previews/notify_preview.rb
index 8e30eeee73f..e7c8964a733 100644
--- a/app/mailers/previews/notify_preview.rb
+++ b/app/mailers/previews/notify_preview.rb
@@ -181,6 +181,10 @@ class NotifyPreview < ActionMailer::Preview
Notify.unknown_sign_in_email(user, '127.0.0.1', Time.current).message
end
+ def new_email_address_added_email
+ Notify.new_email_address_added_email(user, 'someone@gitlab.com').message
+ end
+
def service_desk_new_note_email
cleanup do
note = create_note(noteable_type: 'Issue', noteable_id: issue.id, note: 'Issue note content')
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index de99cbffb6f..f62ccef826c 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -25,6 +25,7 @@ class UserPolicy < BasePolicy
enable :update_user_status
enable :create_saved_replies
enable :update_saved_replies
+ enable :destroy_saved_replies
enable :read_user_personal_access_tokens
enable :read_group_count
enable :read_user_groups
diff --git a/app/services/concerns/members/bulk_create_users.rb b/app/services/concerns/members/bulk_create_users.rb
index 3f8971dde74..3c57301cafc 100644
--- a/app/services/concerns/members/bulk_create_users.rb
+++ b/app/services/concerns/members/bulk_create_users.rb
@@ -53,7 +53,7 @@ module Members
if users.present?
# helps not have to perform another query per user id to see if the member exists later on when fetching
- existing_members = source.members_and_requesters.where(user_id: users).index_by(&:user_id) # rubocop:disable CodeReuse/ActiveRecord
+ existing_members = source.members_and_requesters.with_user(users).index_by(&:user_id)
end
[emails, users, existing_members]
diff --git a/app/services/emails/base_service.rb b/app/services/emails/base_service.rb
index 58fc9799673..6f2b1018a6a 100644
--- a/app/services/emails/base_service.rb
+++ b/app/services/emails/base_service.rb
@@ -9,6 +9,10 @@ module Emails
@params = params.dup
@user = params.delete(:user)
end
+
+ def notification_service
+ NotificationService.new
+ end
end
end
diff --git a/app/services/emails/create_service.rb b/app/services/emails/create_service.rb
index 011978ba76a..d2d8b69559a 100644
--- a/app/services/emails/create_service.rb
+++ b/app/services/emails/create_service.rb
@@ -7,6 +7,7 @@ module Emails
user.emails.create(params.merge(extra_params)).tap do |email|
email&.confirm if skip_confirmation && current_user.admin?
+ notification_service.new_email_address_added(user, email.email) if email.persisted? && !email.user_primary_email?
end
end
end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index aa7e636b8a4..aecf7cf99b9 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -109,6 +109,13 @@ class NotificationService
mailer.unknown_sign_in_email(user, ip, time).deliver_later
end
+ # Notify a user when a new email address is added to the their account
+ def new_email_address_added(user, email)
+ return unless user.can?(:receive_notifications)
+
+ mailer.new_email_address_added_email(user, email).deliver_later
+ end
+
# When create an issue we should send an email to:
#
# * issue assignee if their notification level is not Disabled
diff --git a/app/services/users/saved_replies/destroy_service.rb b/app/services/users/saved_replies/destroy_service.rb
new file mode 100644
index 00000000000..ac08cddad0c
--- /dev/null
+++ b/app/services/users/saved_replies/destroy_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Users
+ module SavedReplies
+ class DestroyService
+ def initialize(saved_reply:)
+ @saved_reply = saved_reply
+ end
+
+ def execute
+ if saved_reply.destroy
+ ServiceResponse.success(payload: { saved_reply: saved_reply })
+ else
+ ServiceResponse.error(message: saved_reply.errors.full_messages)
+ end
+ end
+
+ private
+
+ attr_reader :saved_reply
+ end
+ end
+end
diff --git a/app/services/users/saved_replies/update_service.rb b/app/services/users/saved_replies/update_service.rb
index ab0a3eaf87d..80d3da8a0a3 100644
--- a/app/services/users/saved_replies/update_service.rb
+++ b/app/services/users/saved_replies/update_service.rb
@@ -3,8 +3,7 @@
module Users
module SavedReplies
class UpdateService
- def initialize(current_user:, saved_reply:, name:, content:)
- @current_user = current_user
+ def initialize(saved_reply:, name:, content:)
@saved_reply = saved_reply
@name = name
@content = content
@@ -20,7 +19,7 @@ module Users
private
- attr_reader :current_user, :saved_reply, :name, :content
+ attr_reader :saved_reply, :name, :content
end
end
end
diff --git a/app/views/notify/new_email_address_added_email.erb b/app/views/notify/new_email_address_added_email.erb
new file mode 100644
index 00000000000..3af1953c902
--- /dev/null
+++ b/app/views/notify/new_email_address_added_email.erb
@@ -0,0 +1,5 @@
+<%= say_hi(@user) %>
+
+<%= new_email_address_added_text(@email) %>
+
+<%= remove_email_address_text %>
diff --git a/app/views/notify/new_email_address_added_email.haml b/app/views/notify/new_email_address_added_email.haml
new file mode 100644
index 00000000000..6d00aaedfd5
--- /dev/null
+++ b/app/views/notify/new_email_address_added_email.haml
@@ -0,0 +1,6 @@
+%p
+ = say_hi(@user)
+%p
+ = new_email_address_added_text(@email)
+%p
+ = remove_email_address_text(format: :html)