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>2020-10-27 21:08:59 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-27 21:08:59 +0300
commitf3b9e205bb8dc4f0e8ebff79cf364fede886014b (patch)
treece9819fa446271f94e32af2cca1c02d618c3d9aa /app
parent2b1e7f7dac0fa5d7bb3bdf415cec1b3c67ed77b0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/awards_handler.js37
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js3
-rw-r--r--app/controllers/projects/static_site_editor_controller.rb7
-rw-r--r--app/helpers/issuables_helper.rb7
-rw-r--r--app/models/snippet.rb6
-rw-r--r--app/views/projects/incidents/show.html.haml7
-rw-r--r--app/views/projects/issuable/_show.html.haml10
-rw-r--r--app/views/projects/issues/show.html.haml101
-rw-r--r--app/views/shared/issue_type/_details_content.html.haml31
-rw-r--r--app/views/shared/issue_type/_details_header.html.haml52
-rw-r--r--app/views/shared/issue_type/_emoji_block.html.haml9
-rw-r--r--app/views/shared/issue_type/_sentry_stack_trace.html.haml4
12 files changed, 147 insertions, 127 deletions
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 7055cd42978..17e6255700a 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -5,11 +5,11 @@ import { uniq } from 'lodash';
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import Cookies from 'js-cookie';
import { __ } from './locale';
-import { updateTooltipTitle } from './lib/utils/common_utils';
import { isInVueNoteablePage } from './lib/utils/dom_utils';
import { deprecatedCreateFlash as flash } from './flash';
import axios from './lib/utils/axios_utils';
import * as Emoji from '~/emoji';
+import { dispose, fixTitle } from '~/tooltips';
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
@@ -374,7 +374,7 @@ export class AwardsHandler {
counter.text(counterNumber - 1);
this.removeYouFromUserList($emojiButton);
} else if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
- $emojiButton.tooltip('dispose');
+ dispose($emojiButton);
counter.text('0');
this.removeYouFromUserList($emojiButton);
if ($emojiButton.parents('.note').length) {
@@ -387,7 +387,8 @@ export class AwardsHandler {
}
removeEmoji($emojiButton) {
- $emojiButton.tooltip('dispose');
+ dispose($emojiButton);
+
$emojiButton.remove();
const $votesBlock = this.getVotesBlock();
if ($votesBlock.find('.js-emoji-btn').length === 0) {
@@ -415,13 +416,17 @@ export class AwardsHandler {
const originalTitle = this.getAwardTooltip(awardBlock);
const authors = originalTitle.split(FROM_SENTENCE_REGEX);
authors.splice(authors.indexOf('You'), 1);
- return awardBlock
+
+ awardBlock
.closest('.js-emoji-btn')
.removeData('title')
.removeAttr('data-title')
.removeAttr('data-original-title')
- .attr('title', this.toSentence(authors))
- .tooltip('_fixTitle');
+ .attr('title', this.toSentence(authors));
+
+ fixTitle(awardBlock);
+
+ return awardBlock;
}
addYouToUserList(votesBlock, emoji) {
@@ -432,7 +437,12 @@ export class AwardsHandler {
users = origTitle.trim().split(FROM_SENTENCE_REGEX);
}
users.unshift('You');
- return awardBlock.attr('title', this.toSentence(users)).tooltip('_fixTitle');
+
+ awardBlock.attr('title', this.toSentence(users));
+
+ fixTitle(awardBlock);
+
+ return awardBlock;
}
createAwardButtonForVotesBlock(votesBlock, emojiName) {
@@ -448,7 +458,7 @@ export class AwardsHandler {
.find('.emoji-icon')
.data('name', emojiName);
this.animateEmoji($emojiButton);
- $('.award-control').tooltip();
+
votesBlock.removeClass('current');
}
@@ -487,17 +497,6 @@ export class AwardsHandler {
return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`);
}
- userAuthored($emojiButton) {
- const oldTitle = this.getAwardTooltip($emojiButton);
- const newTitle = 'You cannot vote on your own issue, MR and note';
- updateTooltipTitle($emojiButton, newTitle).tooltip('show');
- // Restore tooltip back to award list
- return setTimeout(() => {
- $emojiButton.tooltip('hide');
- updateTooltipTitle($emojiButton, oldTitle);
- }, 2800);
- }
-
scrollToAwards() {
const options = {
scrollTop: $('.awards').offset().top - 110,
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index fe1ac00fd1d..7845f2968db 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -61,9 +61,6 @@ export const rstrip = val => {
return val;
};
-export const updateTooltipTitle = ($tooltipEl, newTitle) =>
- $tooltipEl.attr('title', newTitle).tooltip('_fixTitle');
-
export const disableButtonIfEmptyField = (fieldSelector, buttonSelector, eventName = 'input') => {
const field = $(fieldSelector);
const closestSubmit = field.closest('form').find(buttonSelector);
diff --git a/app/controllers/projects/static_site_editor_controller.rb b/app/controllers/projects/static_site_editor_controller.rb
index 58cda84ebe7..9fb5976e11a 100644
--- a/app/controllers/projects/static_site_editor_controller.rb
+++ b/app/controllers/projects/static_site_editor_controller.rb
@@ -6,6 +6,13 @@ class Projects::StaticSiteEditorController < Projects::ApplicationController
layout 'fullscreen'
+ content_security_policy do |policy|
+ next if policy.directives.blank?
+
+ frame_src_values = Array.wrap(policy.directives['frame-src']) | ['https://www.youtube.com']
+ policy.frame_src(*frame_src_values)
+ end
+
prepend_before_action :authenticate_user!, only: [:show]
before_action :assign_ref_and_path, only: [:show]
before_action :authorize_edit_tree!, only: [:show]
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 6a74b7010b9..577d8d5cb2a 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -377,7 +377,12 @@ module IssuablesHelper
end
def issuable_display_type(issuable)
- issuable.model_name.human.downcase
+ case issuable
+ when Issue
+ issuable.issue_type.downcase
+ when MergeRequest
+ issuable.model_name.human.downcase
+ end
end
def has_filter_bar_param?
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index d71853e11cf..dc370b46bda 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -293,9 +293,7 @@ class Snippet < ApplicationRecord
@storage ||= Storage::Hashed.new(self, prefix: Storage::Hashed::SNIPPET_REPOSITORY_PATH_PREFIX)
end
- # This is the full_path used to identify the
- # the snippet repository. It will be used mostly
- # for logging purposes.
+ # This is the full_path used to identify the the snippet repository.
override :full_path
def full_path
return unless persisted?
@@ -303,7 +301,7 @@ class Snippet < ApplicationRecord
@full_path ||= begin
components = []
components << project.full_path if project_id?
- components << '@snippets'
+ components << 'snippets'
components << self.id
components.join('/')
end
diff --git a/app/views/projects/incidents/show.html.haml b/app/views/projects/incidents/show.html.haml
index b0ddc85df5d..4d4607e8e36 100644
--- a/app/views/projects/incidents/show.html.haml
+++ b/app/views/projects/incidents/show.html.haml
@@ -1 +1,6 @@
-= render template: 'projects/issues/show'
+- @content_class = "limit-container-width" unless fluid_layout
+- add_to_breadcrumbs _("Incidents"), project_incidents_path(@project)
+- breadcrumb_title @issue.to_reference
+- page_title "#{@issue.title} (#{@issue.to_reference})", _("Incidents")
+
+= render 'projects/issuable/show', issuable: @issue
diff --git a/app/views/projects/issuable/_show.html.haml b/app/views/projects/issuable/_show.html.haml
new file mode 100644
index 00000000000..48920c4e342
--- /dev/null
+++ b/app/views/projects/issuable/_show.html.haml
@@ -0,0 +1,10 @@
+- page_description issuable.description_html
+- page_card_attributes issuable.card_attributes
+- if issuable.relocation_target
+ - page_canonical_link issuable.relocation_target.present(current_user: current_user).web_url
+
+= render_if_exists "projects/issues/alert_blocked", issue: issuable, current_user: current_user
+= render "projects/issues/alert_moved_from_service_desk", issue: issuable
+
+= render 'shared/issue_type/details_header', issuable: issuable
+= render 'shared/issue_type/details_content', issuable: issuable
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 4778221335e..c3949a83e3f 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -1,103 +1,6 @@
- @content_class = "limit-container-width" unless fluid_layout
- add_to_breadcrumbs _("Issues"), project_issues_path(@project)
- breadcrumb_title @issue.to_reference
-- page_title "#{@issue.title} (#{@issue.to_reference})", _("Issues")
-- page_description @issue.description_html
-- page_card_attributes @issue.card_attributes
-- if @issue.relocation_target
- - page_canonical_link @issue.relocation_target.present(current_user: current_user).web_url
-- if @issue.sentry_issue.present?
- - add_page_specific_style 'page_bundles/error_tracking_details'
+- page_title "#{@issue.title} (#{@issue.to_reference})", _("Issues")
-- can_update_issue = can?(current_user, :update_issue, @issue)
-- can_reopen_issue = can?(current_user, :reopen_issue, @issue)
-- can_report_spam = @issue.submittable_as_spam_by?(current_user)
-- can_create_issue = show_new_issue_link?(@project)
-- related_branches_path = related_branches_project_issue_path(@project, @issue)
-
-= render_if_exists "projects/issues/alert_blocked", issue: @issue, current_user: current_user
-= render "projects/issues/alert_moved_from_service_desk", issue: @issue
-
-.detail-page-header
- .detail-page-header-body
- .issuable-status-box.status-box.status-box-issue-closed{ class: issue_status_visibility(@issue, status_box: :closed) }
- = sprite_icon('mobile-issue-close', css_class: 'd-block d-sm-none')
- .d-none.d-sm-block
- = issue_closed_text(@issue, current_user)
- .issuable-status-box.status-box.status-box-open{ class: issue_status_visibility(@issue, status_box: :open) }
- = sprite_icon('issue-open-m', css_class: 'd-block d-sm-none')
- %span.d-none.d-sm-block Open
-
- .issuable-meta
- #js-issuable-header-warnings
- = issuable_meta(@issue, @project, "Issue")
-
- %a.btn.btn-default.float-right.d-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
- = sprite_icon('chevron-double-lg-left')
-
- .detail-page-header-actions.js-issuable-actions.js-issuable-buttons{ data: { "action": "close-reopen" } }
- .clearfix.issue-btn-group.dropdown
- %button.btn.btn-default.float-left.d-md-none{ type: "button", data: { toggle: "dropdown" } }
- Options
- = icon('caret-down')
- .dropdown-menu.dropdown-menu-right.d-lg-none
- %ul
- - unless current_user == @issue.author
- %li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue))
- - if can_update_issue
- %li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(@issue, true)}", title: 'Close issue'
- - if can_reopen_issue
- %li= link_to 'Reopen issue', issue_path(@issue, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen js-btn-issue-action #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
- - if can_report_spam
- %li= link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'btn-spam', title: 'Submit as spam'
- - if can_create_issue
- - if can_update_issue || can_report_spam
- %li.divider
- %li= link_to 'New issue', new_project_issue_path(@project), id: 'new_issue_link'
-
- = render 'shared/issuable/close_reopen_button', issuable: @issue, can_update: can_update_issue, can_reopen: can_reopen_issue, warn_before_close: defined?(@issue.blocked?) && @issue.blocked?
-
- - if can_report_spam
- = link_to 'Submit as spam', mark_as_spam_project_issue_path(@project, @issue), method: :post, class: 'd-none d-md-block gl-button btn btn-grouped btn-spam', title: 'Submit as spam'
- - if can_create_issue
- = link_to new_project_issue_path(@project), class: 'd-none d-md-block gl-button btn btn-grouped btn-success btn-inverted', title: 'New issue', id: 'new_issue_link' do
- New issue
-
-.issue-details.issuable-details
- .detail-page-description.content-block
- #js-issuable-app{ data: { initial: issuable_initial_data(@issue).to_json} }
- .title-container
- %h2.title= markdown_field(@issue, :title)
- - if @issue.description.present?
- .description
- .md= markdown_field(@issue, :description)
-
- = edited_time_ago_with_tooltip(@issue, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago')
-
- - if @issue.sentry_issue.present?
- #js-sentry-error-stack-trace{ data: error_details_data(@project, @issue.sentry_issue.sentry_issue_identifier) }
-
- = render 'projects/issues/design_management'
-
- = render_if_exists 'projects/issues/related_issues'
-
- #js-related-merge-requests{ data: { endpoint: expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid)), project_namespace: @project.namespace.path, project_path: @project.path } }
-
- - if can?(current_user, :download_code, @project)
- - add_page_startup_api_call related_branches_path
- #related-branches{ data: { url: related_branches_path } }
- -# This element is filled in using JavaScript.
-
- .content-block.emoji-block.emoji-block-sticky
- .row.gl-m-0.gl-justify-content-space-between
- .js-noteable-awards
- = render 'award_emoji/awards_block', awardable: @issue, inline: true
- .new-branch-col
- = render_if_exists "projects/issues/timeline_toggle", issue: @issue
- #js-vue-sort-issue-discussions
- #js-vue-discussion-filter{ data: { default_filter: current_user&.notes_filter_for(@issue), notes_filters: UserPreference.notes_filters.to_json } }
- = render 'new_branch' if show_new_branch_button?
-
- = render 'projects/issues/discussion'
-
-= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @issue.assignees
+= render 'projects/issuable/show', issuable: @issue
diff --git a/app/views/shared/issue_type/_details_content.html.haml b/app/views/shared/issue_type/_details_content.html.haml
new file mode 100644
index 00000000000..7c1ec332ba4
--- /dev/null
+++ b/app/views/shared/issue_type/_details_content.html.haml
@@ -0,0 +1,31 @@
+- related_branches_path = related_branches_project_issue_path(@project, issuable)
+
+.issue-details.issuable-details
+ .detail-page-description.content-block
+ #js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json} }
+ .title-container
+ %h2.title= markdown_field(issuable, :title)
+ - if issuable.description.present?
+ .description
+ .md= markdown_field(issuable, :description)
+
+ = edited_time_ago_with_tooltip(issuable, placement: 'bottom', html_class: 'issue-edited-ago js-issue-edited-ago')
+
+ = render 'shared/issue_type/sentry_stack_trace', issuable: issuable
+
+ = render 'projects/issues/design_management'
+
+ = render_if_exists 'projects/issues/related_issues'
+
+ #js-related-merge-requests{ data: { endpoint: expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: issuable.iid)), project_namespace: @project.namespace.path, project_path: @project.path } }
+
+ - if can?(current_user, :download_code, @project)
+ - add_page_startup_api_call related_branches_path
+ #related-branches{ data: { url: related_branches_path } }
+ -# This element is filled in using JavaScript.
+
+ = render 'shared/issue_type/emoji_block', issuable: issuable
+
+ = render 'projects/issues/discussion'
+
+= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @issue.assignees
diff --git a/app/views/shared/issue_type/_details_header.html.haml b/app/views/shared/issue_type/_details_header.html.haml
new file mode 100644
index 00000000000..79ad45e0c6a
--- /dev/null
+++ b/app/views/shared/issue_type/_details_header.html.haml
@@ -0,0 +1,52 @@
+- can_update_issue = can?(current_user, :update_issue, issuable)
+- can_reopen_issue = can?(current_user, :reopen_issue, issuable)
+- can_report_spam = issuable.submittable_as_spam_by?(current_user)
+- can_create_issue = show_new_issue_link?(@project)
+- display_issuable_type = issuable_display_type(issuable)
+- new_issuable_params = ({ issuable_template: 'incident', issue: { issue_type: 'incident' } } if issuable.incident?)
+
+.detail-page-header
+ .detail-page-header-body
+ .issuable-status-box.status-box.status-box-issue-closed{ class: issue_status_visibility(issuable, status_box: :closed) }
+ = sprite_icon('mobile-issue-close', css_class: 'gl-display-block gl-display-sm-none!')
+ .gl-display-none.gl-display-sm-block!
+ = issue_closed_text(issuable, current_user)
+ .issuable-status-box.status-box.status-box-open{ class: issue_status_visibility(issuable, status_box: :open) }
+ = sprite_icon('issue-open-m', css_class: 'gl-display-block gl-display-sm-none!')
+ %span.gl-display-none.gl-display-sm-block!
+ = _('Open')
+
+ .issuable-meta
+ #js-issuable-header-warnings
+ = issuable_meta(issuable, @project, display_issuable_type)
+
+ %a.btn.gl-button.btn-default.float-right.gl-display-block.d-sm-none.gutter-toggle.issuable-gutter-toggle.js-sidebar-toggle{ href: "#" }
+ = sprite_icon('chevron-double-lg-left')
+
+ .detail-page-header-actions.js-issuable-actions.js-issuable-buttons{ data: { "action": "close-reopen" } }
+ .clearfix.issue-btn-group.dropdown
+ %button.btn.gl-button.btn-default.float-left.d-md-none.d-lg-none.d-xl-none{ type: "button", data: { toggle: "dropdown" } }
+ = _('Options')
+ = icon('caret-down')
+ .dropdown-menu.dropdown-menu-right.d-lg-none.d-xl-none
+ %ul
+ - unless current_user == issuable.author
+ %li= link_to _('Report abuse'), new_abuse_report_path(user_id: issuable.author.id, ref_url: issue_url(issuable))
+ - if can_update_issue
+ %li= link_to _('Close %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, issue_path(issuable, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(issuable, true)}", title: _('Close %{display_issuable_type}') % { display_issuable_type: display_issuable_type }
+ - if can_reopen_issue
+ %li= link_to _('Reopen %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, issue_path(issuable, issue: { state_event: :reopen }, format: 'json'), class: "btn-reopen js-btn-issue-action #{issue_button_visibility(issuable, false)}", title: _('Reopen %{display_issuable_type}') % { display_issuable_type: display_issuable_type }
+ - if can_report_spam
+ %li= link_to _('Submit as spam'), mark_as_spam_project_issue_path(@project, issuable), method: :post, class: 'btn-spam', title: 'Submit as spam'
+ - if can_create_issue
+ - if can_update_issue || can_report_spam
+ %li.divider
+ %li= link_to _('New %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, new_project_issue_path(@project, new_issuable_params), id: 'new_%{display_issuable_type}_link' % { display_issuable_type: display_issuable_type }
+
+ = render 'shared/issuable/close_reopen_button', issuable: issuable, can_update: can_update_issue, can_reopen: can_reopen_issue, warn_before_close: defined?(issuable.blocked?) && issuable.blocked?
+
+ - if can_report_spam
+ = link_to _('Submit as spam'), mark_as_spam_project_issue_path(@project, issuable), method: :post, class: 'gl-display-none gl-display-sm-none gl-display-md-block gl-button btn btn-grouped btn-spam', title: 'Submit as spam'
+ - if can_create_issue
+ = link_to new_project_issue_path(@project, new_issuable_params), class: 'gl-display-none gl-display-sm-none gl-display-md-block gl-button btn btn-grouped btn-success btn-inverted', title: _('New %{display_issuable_type}') % { display_issuable_type: display_issuable_type }, id: 'new_%{display_issuable_type}_link' % { display_issuable_type: display_issuable_type } do
+ = _('New %{display_issuable_type}') % { display_issuable_type: display_issuable_type }
diff --git a/app/views/shared/issue_type/_emoji_block.html.haml b/app/views/shared/issue_type/_emoji_block.html.haml
new file mode 100644
index 00000000000..42d149b2ab3
--- /dev/null
+++ b/app/views/shared/issue_type/_emoji_block.html.haml
@@ -0,0 +1,9 @@
+.content-block.emoji-block.emoji-block-sticky
+ .row.gl-m-0.gl-justify-content-space-between
+ .js-noteable-awards
+ = render 'award_emoji/awards_block', awardable: issuable, inline: true
+ .new-branch-col
+ = render_if_exists "projects/issues/timeline_toggle", issuable: issuable
+ #js-vue-sort-issue-discussions
+ #js-vue-discussion-filter{ data: { default_filter: current_user&.notes_filter_for(issuable), notes_filters: UserPreference.notes_filters.to_json } }
+ = render 'new_branch' if show_new_branch_button?
diff --git a/app/views/shared/issue_type/_sentry_stack_trace.html.haml b/app/views/shared/issue_type/_sentry_stack_trace.html.haml
new file mode 100644
index 00000000000..40b29a74b53
--- /dev/null
+++ b/app/views/shared/issue_type/_sentry_stack_trace.html.haml
@@ -0,0 +1,4 @@
+- return unless issuable.sentry_issue.present?
+- add_page_specific_style 'page_bundles/error_tracking_details'
+
+#js-sentry-error-stack-trace{ data: error_details_data(@project, issuable.sentry_issue.sentry_issue_identifier) }