diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-27 21:08:59 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-27 21:08:59 +0300 |
commit | f3b9e205bb8dc4f0e8ebff79cf364fede886014b (patch) | |
tree | ce9819fa446271f94e32af2cca1c02d618c3d9aa /app | |
parent | 2b1e7f7dac0fa5d7bb3bdf415cec1b3c67ed77b0 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/awards_handler.js | 37 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/common_utils.js | 3 | ||||
-rw-r--r-- | app/controllers/projects/static_site_editor_controller.rb | 7 | ||||
-rw-r--r-- | app/helpers/issuables_helper.rb | 7 | ||||
-rw-r--r-- | app/models/snippet.rb | 6 | ||||
-rw-r--r-- | app/views/projects/incidents/show.html.haml | 7 | ||||
-rw-r--r-- | app/views/projects/issuable/_show.html.haml | 10 | ||||
-rw-r--r-- | app/views/projects/issues/show.html.haml | 101 | ||||
-rw-r--r-- | app/views/shared/issue_type/_details_content.html.haml | 31 | ||||
-rw-r--r-- | app/views/shared/issue_type/_details_header.html.haml | 52 | ||||
-rw-r--r-- | app/views/shared/issue_type/_emoji_block.html.haml | 9 | ||||
-rw-r--r-- | app/views/shared/issue_type/_sentry_stack_trace.html.haml | 4 |
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) } |