diff options
Diffstat (limited to 'app')
24 files changed, 357 insertions, 101 deletions
diff --git a/app/assets/javascripts/milestone.js b/app/assets/javascripts/milestone.js index 38c673e8907..841b24a60a3 100644 --- a/app/assets/javascripts/milestone.js +++ b/app/assets/javascripts/milestone.js @@ -19,12 +19,10 @@ }); }; - Milestone.sortIssues = function(data) { - var sort_issues_url; - sort_issues_url = location.href + "/sort_issues"; + Milestone.sortIssues = function(url, data) { return $.ajax({ type: "PUT", - url: sort_issues_url, + url, data: data, success: function(_data) { return Milestone.successCallback(_data); @@ -36,12 +34,10 @@ }); }; - Milestone.sortMergeRequests = function(data) { - var sort_mr_url; - sort_mr_url = location.href + "/sort_merge_requests"; + Milestone.sortMergeRequests = function(url, data) { return $.ajax({ type: "PUT", - url: sort_mr_url, + url, data: data, success: function(_data) { return Milestone.successCallback(_data); @@ -81,42 +77,55 @@ }; function Milestone() { - var oldMouseStart; + this.issuesSortEndpoint = $('#tab-issues').data('sort-endpoint'); + this.mergeRequestsSortEndpoint = $('#tab-merge-requests').data('sort-endpoint'); + this.bindIssuesSorting(); - this.bindMergeRequestSorting(); this.bindTabsSwitching(); + + // Load merge request tab if it is active + // merge request tab is active based on different conditions in the backend + this.loadTab($('.js-milestone-tabs .active a')); + + this.loadInitialTab(); } Milestone.prototype.bindIssuesSorting = function() { + if (!this.issuesSortEndpoint) return; + $('#issues-list-unassigned, #issues-list-ongoing, #issues-list-closed').each(function (i, el) { this.createSortable(el, { group: 'issue-list', listEls: $('.issues-sortable-list'), fieldName: 'issue', - sortCallback: Milestone.sortIssues, + sortCallback: (data) => { + Milestone.sortIssues(this.issuesSortEndpoint, data); + }, updateCallback: Milestone.updateIssue, }); }.bind(this)); }; Milestone.prototype.bindTabsSwitching = function() { - return $('a[data-toggle="tab"]').on('show.bs.tab', function(e) { - var currentTabClass, previousTabClass; - currentTabClass = $(e.target).data('show'); - previousTabClass = $(e.relatedTarget).data('show'); - $(previousTabClass).hide(); - $(currentTabClass).removeClass('hidden'); - return $(currentTabClass).show(); + return $('a[data-toggle="tab"]').on('show.bs.tab', (e) => { + const $target = $(e.target); + + location.hash = $target.attr('href'); + this.loadTab($target); }); }; Milestone.prototype.bindMergeRequestSorting = function() { + if (!this.mergeRequestsSortEndpoint) return; + $("#merge_requests-list-unassigned, #merge_requests-list-ongoing, #merge_requests-list-closed").each(function (i, el) { this.createSortable(el, { group: 'merge-request-list', listEls: $(".merge_requests-sortable-list:not(#merge_requests-list-merged)"), fieldName: 'merge_request', - sortCallback: Milestone.sortMergeRequests, + sortCallback: (data) => { + Milestone.sortMergeRequests(this.mergeRequestsSortEndpoint, data); + }, updateCallback: Milestone.updateMergeRequest, }); }.bind(this)); @@ -169,6 +178,35 @@ }); }; + Milestone.prototype.loadInitialTab = function() { + const $target = $(`.js-milestone-tabs a[href="${location.hash}"]`); + + if ($target.length) { + $target.tab('show'); + } + }; + + Milestone.prototype.loadTab = function($target) { + const endpoint = $target.data('endpoint'); + const tabElId = $target.attr('href'); + + if (endpoint && !$target.hasClass('is-loaded')) { + $.ajax({ + url: endpoint, + dataType: 'JSON', + }) + .fail(() => new Flash('Error loading milestone tab')) + .done((data) => { + $(tabElId).html(data.html); + $target.addClass('is-loaded'); + + if (tabElId === '#tab-merge-requests') { + this.bindMergeRequestSorting(); + } + }); + } + }; + return Milestone; })(); }).call(window); diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 97fab513b01..ad6eb9f6fe0 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -6,7 +6,13 @@ } .limit-container-width { - .detail-page-header { + .detail-page-header, + .page-content-header, + .commit-box, + .info-well, + .notes, + .commit-ci-menu, + .files-changed { @extend .fixed-width-container; } @@ -36,8 +42,7 @@ } .diffs { - .mr-version-controls, - .files-changed { + .mr-version-controls { @extend .fixed-width-container; } } diff --git a/app/assets/stylesheets/pages/members.scss b/app/assets/stylesheets/pages/members.scss index be7193bae04..8dbac76e30a 100644 --- a/app/assets/stylesheets/pages/members.scss +++ b/app/assets/stylesheets/pages/members.scss @@ -133,3 +133,55 @@ right: 160px; } } + +.flex-project-members-panel { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + + @media (max-width: $screen-sm-min) { + display: block; + + .flex-project-title { + vertical-align: top; + display: inline-block; + max-width: 90%; + } + } + + .flex-project-title { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + .badge { + height: 17px; + line-height: 16px; + margin-right: 5px; + padding-top: 1px; + padding-bottom: 1px; + } + + .flex-project-members-form { + flex-wrap: nowrap; + white-space: nowrap; + margin-left: auto; + } +} + +.panel { + .panel-heading { + .badge { + margin-top: 0; + } + + @media (max-width: $screen-sm-min) { + .badge { + margin-right: 0; + margin-left: 0; + } + } + } +}
\ No newline at end of file diff --git a/app/assets/stylesheets/pages/wiki.scss b/app/assets/stylesheets/pages/wiki.scss index 04ff2d52b91..b64b89485f7 100644 --- a/app/assets/stylesheets/pages/wiki.scss +++ b/app/assets/stylesheets/pages/wiki.scss @@ -71,7 +71,6 @@ .nav-controls { width: auto; min-width: 50%; - white-space: nowrap; } } diff --git a/app/controllers/concerns/milestone_actions.rb b/app/controllers/concerns/milestone_actions.rb new file mode 100644 index 00000000000..3e2a0fe4f8b --- /dev/null +++ b/app/controllers/concerns/milestone_actions.rb @@ -0,0 +1,53 @@ +module MilestoneActions + extend ActiveSupport::Concern + + def merge_requests + respond_to do |format| + format.html { redirect_to milestone_redirect_path } + format.json do + render json: tabs_json("shared/milestones/_merge_requests_tab", { + merge_requests: @milestone.merge_requests, + show_project_name: true + }) + end + end + end + + def participants + respond_to do |format| + format.html { redirect_to milestone_redirect_path } + format.json do + render json: tabs_json("shared/milestones/_participants_tab", { + users: @milestone.participants + }) + end + end + end + + def labels + respond_to do |format| + format.html { redirect_to milestone_redirect_path } + format.json do + render json: tabs_json("shared/milestones/_labels_tab", { + labels: @milestone.labels + }) + end + end + end + + private + + def tabs_json(partial, data = {}) + { + html: view_to_html_string(partial, data) + } + end + + def milestone_redirect_path + if @project + namespace_project_milestone_path(@project.namespace, @project, @milestone) + else + group_milestone_path(@group, @milestone.safe_title, title: @milestone.title) + end + end +end diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 43102596201..e52fa766044 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -1,6 +1,8 @@ class Groups::MilestonesController < Groups::ApplicationController + include MilestoneActions + before_action :group_projects - before_action :milestone, only: [:show, :update] + before_action :milestone, only: [:show, :update, :merge_requests, :participants, :labels] before_action :authorize_admin_milestones!, only: [:new, :create, :update] def index diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index d0dd524c484..c56bce19eee 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -1,12 +1,14 @@ class Projects::MilestonesController < Projects::ApplicationController + include MilestoneActions + before_action :module_enabled - before_action :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests] + before_action :milestone, only: [:edit, :update, :destroy, :show, :sort_issues, :sort_merge_requests, :merge_requests, :participants, :labels] # Allow read any milestone before_action :authorize_read_milestone! # Allow admin milestone - before_action :authorize_admin_milestone!, except: [:index, :show] + before_action :authorize_admin_milestone!, except: [:index, :show, :merge_requests, :participants, :labels] respond_to :html diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index 1780cc0233c..454b8ee17af 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -9,19 +9,19 @@ class Projects::PipelinesController < Projects::ApplicationController def index @scope = params[:scope] @pipelines = PipelinesFinder - .new(project) - .execute(scope: @scope) + .new(project, scope: @scope) + .execute .page(params[:page]) .per(30) @running_count = PipelinesFinder - .new(project).execute(scope: 'running').count + .new(project, scope: 'running').execute.count @pending_count = PipelinesFinder - .new(project).execute(scope: 'pending').count + .new(project, scope: 'pending').execute.count @finished_count = PipelinesFinder - .new(project).execute(scope: 'finished').count + .new(project, scope: 'finished').execute.count @pipelines_count = PipelinesFinder .new(project).execute.count diff --git a/app/finders/pipelines_finder.rb b/app/finders/pipelines_finder.rb index a9172f6767f..f187a3b61fe 100644 --- a/app/finders/pipelines_finder.rb +++ b/app/finders/pipelines_finder.rb @@ -1,29 +1,23 @@ class PipelinesFinder - attr_reader :project, :pipelines + attr_reader :project, :pipelines, :params - def initialize(project) + ALLOWED_INDEXED_COLUMNS = %w[id status ref user_id].freeze + + def initialize(project, params = {}) @project = project @pipelines = project.pipelines + @params = params end - def execute(scope: nil) - scoped_pipelines = - case scope - when 'running' - pipelines.running - when 'pending' - pipelines.pending - when 'finished' - pipelines.finished - when 'branches' - from_ids(ids_for_ref(branches)) - when 'tags' - from_ids(ids_for_ref(tags)) - else - pipelines - end - - scoped_pipelines.order(id: :desc) + def execute + items = pipelines + items = by_scope(items) + items = by_status(items) + items = by_ref(items) + items = by_name(items) + items = by_username(items) + items = by_yaml_errors(items) + sort_items(items) end private @@ -43,4 +37,78 @@ class PipelinesFinder def tags project.repository.tag_names end + + def by_scope(items) + case params[:scope] + when 'running' + items.running + when 'pending' + items.pending + when 'finished' + items.finished + when 'branches' + from_ids(ids_for_ref(branches)) + when 'tags' + from_ids(ids_for_ref(tags)) + else + items + end + end + + def by_status(items) + return items unless HasStatus::AVAILABLE_STATUSES.include?(params[:status]) + + items.where(status: params[:status]) + end + + def by_ref(items) + if params[:ref].present? + items.where(ref: params[:ref]) + else + items + end + end + + def by_name(items) + if params[:name].present? + items.joins(:user).where(users: { name: params[:name] }) + else + items + end + end + + def by_username(items) + if params[:username].present? + items.joins(:user).where(users: { username: params[:username] }) + else + items + end + end + + def by_yaml_errors(items) + case Gitlab::Utils.to_boolean(params[:yaml_errors]) + when true + items.where("yaml_errors IS NOT NULL") + when false + items.where("yaml_errors IS NULL") + else + items + end + end + + def sort_items(items) + order_by = if ALLOWED_INDEXED_COLUMNS.include?(params[:order_by]) + params[:order_by] + else + :id + end + + sort = if params[:sort] =~ /\A(ASC|DESC)\z/i + params[:sort] + else + :desc + end + + items.order(order_by => sort) + end end diff --git a/app/helpers/milestones_helper.rb b/app/helpers/milestones_helper.rb index c9e70faa52e..c515774140c 100644 --- a/app/helpers/milestones_helper.rb +++ b/app/helpers/milestones_helper.rb @@ -115,4 +115,28 @@ module MilestonesHelper end end end + + def milestone_merge_request_tab_path(milestone) + if @project + merge_requests_namespace_project_milestone_path(@project.namespace, @project, milestone, format: :json) + elsif @group + merge_requests_group_milestone_path(@group, milestone.safe_title, title: milestone.title, format: :json) + end + end + + def milestone_participants_tab_path(milestone) + if @project + participants_namespace_project_milestone_path(@project.namespace, @project, milestone, format: :json) + elsif @group + participants_group_milestone_path(@group, milestone.safe_title, title: milestone.title, format: :json) + end + end + + def milestone_labels_tab_path(milestone) + if @project + labels_namespace_project_milestone_path(@project.namespace, @project, milestone, format: :json) + elsif @group + labels_group_milestone_path(@group, milestone.safe_title, title: milestone.title, format: :json) + end + end end diff --git a/app/services/projects/enable_deploy_key_service.rb b/app/services/projects/enable_deploy_key_service.rb index 3cf4264ce9b..121385afca3 100644 --- a/app/services/projects/enable_deploy_key_service.rb +++ b/app/services/projects/enable_deploy_key_service.rb @@ -4,7 +4,10 @@ module Projects key = accessible_keys.find_by(id: params[:key_id] || params[:id]) return unless key - project.deploy_keys << key + unless project.deploy_keys.include?(key) + project.deploy_keys << key + end + key end diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 840d843f069..89d0bbb7126 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -175,11 +175,7 @@ .panel-body - if @user.can_be_removed? && can?(current_user, :destroy_user, @user) %p Deleting a user has the following effects: - %ul - %li All user content like authored issues, snippets, comments will be removed - - rp = @user.personal_projects.count - - unless rp.zero? - %li #{pluralize rp, 'personal project'} will be removed and cannot be restored + = render 'users/deletion_guidance', user: @user %br = link_to 'Remove user', [:admin, @user], data: { confirm: "USER #{@user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-remove" - else diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml index d843cacd52d..73f33e69d68 100644 --- a/app/views/profiles/accounts/show.html.haml +++ b/app/views/profiles/accounts/show.html.haml @@ -118,11 +118,7 @@ - if @user.can_be_removed? && can?(current_user, :destroy_user, @user) %p Deleting an account has the following effects: - %ul - %li All user content like authored issues, snippets, comments will be removed - - rp = current_user.personal_projects.count - - unless rp.zero? - %li #{pluralize rp, 'personal project'} will be removed and cannot be restored + = render 'users/deletion_guidance', user: current_user = link_to 'Delete account', user_registration_path, data: { confirm: "REMOVE #{current_user.name}? Are you sure?" }, method: :delete, class: "btn btn-remove" - else - if @user.solo_owned_groups.present? diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml index 219dc14645b..cd098acda81 100644 --- a/app/views/projects/blob/_header.html.haml +++ b/app/views/projects/blob/_header.html.haml @@ -1,15 +1,6 @@ - blame = local_assigns.fetch(:blame, false) .js-file-title.file-title-flex-parent - .file-header-content - = blob_icon blob.mode, blob.name - - %strong.file-title-name - = blob.name - - = copy_file_path_button(blob.path) - - %small - = number_to_human_size(blob.raw_size) + = render 'projects/blob/header_content', blob: blob .file-actions.hidden-xs = render 'projects/blob/viewer_switcher', blob: blob unless blame diff --git a/app/views/projects/blob/_header_content.html.haml b/app/views/projects/blob/_header_content.html.haml new file mode 100644 index 00000000000..98bedae650a --- /dev/null +++ b/app/views/projects/blob/_header_content.html.haml @@ -0,0 +1,10 @@ +.file-header-content + = blob_icon blob.mode, blob.name + + %strong.file-title-name + = blob.name + + = copy_file_path_button(blob.path) + + %small + = number_to_human_size(blob.raw_size) diff --git a/app/views/projects/builds/_sidebar.html.haml b/app/views/projects/builds/_sidebar.html.haml index c4159ce1a36..43191fae9e6 100644 --- a/app/views/projects/builds/_sidebar.html.haml +++ b/app/views/projects/builds/_sidebar.html.haml @@ -48,7 +48,7 @@ - if @build.merge_request %p.build-detail-row %span.build-light-text Merge Request: - = link_to "#{@build.merge_request.to_reference}", merge_request_path(@build.merge_request) + = link_to "#{@build.merge_request.to_reference}", merge_request_path(@build.merge_request), class: 'bold' - if @build.duration %p.build-detail-row %span.build-light-text Duration: diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index 0d11da2451a..16d2646cb4e 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -1,9 +1,11 @@ - @no_container = true +- container_class = !fluid_layout && diff_view == :inline ? 'container-limited' : '' +- limited_container_width = fluid_layout || diff_view == :inline ? '' : 'limit-container-width' - page_title "#{@commit.title} (#{@commit.short_id})", "Commits" - page_description @commit.description = render "projects/commits/head" -%div{ class: container_class } +.container-fluid{ class: [limited_container_width, container_class] } = render "commit_box" - if @commit.status = render "ci_menu" diff --git a/app/views/projects/project_members/_index.html.haml b/app/views/projects/project_members/_index.html.haml index ab0771b5751..f83521052ed 100644 --- a/app/views/projects/project_members/_index.html.haml +++ b/app/views/projects/project_members/_index.html.haml @@ -6,6 +6,12 @@ %p Add a new member to %strong= @project.name + - else + %p + Members can be added by project + %i Masters + or + %i Owners .col-lg-9 .light.prepend-top-default - if can?(current_user, :admin_project_member, @project) diff --git a/app/views/projects/project_members/_team.html.haml b/app/views/projects/project_members/_team.html.haml index 81d57c77edf..7b1a26043e1 100644 --- a/app/views/projects/project_members/_team.html.haml +++ b/app/views/projects/project_members/_team.html.haml @@ -1,9 +1,11 @@ .panel.panel-default - .panel-heading - Members with access to - %strong= @project.name + .panel-heading.flex-project-members-panel + %span.flex-project-title + Members of + %strong + #{@project.name} %span.badge= @project_members.total_count - = form_tag namespace_project_settings_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form' do + = form_tag namespace_project_settings_members_path(@project.namespace, @project), method: :get, class: 'form-inline member-search-form flex-project-members-form' do .form-group = search_field_tag :search, params[:search], { placeholder: 'Find existing members by name', class: 'form-control', spellcheck: false } %button.member-search-btn{ type: "submit", "aria-label" => "Submit search" } diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 45065ac5920..bc638e994f3 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -136,7 +136,7 @@ - selected_labels.each do |label| = hidden_field_tag "#{issuable.to_ability_name}[label_names][]", label.id, id: nil .dropdown - %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: {toggle: "dropdown", default_label: "Labels", field_name: "#{issuable.to_ability_name}[label_names][]", ability_name: issuable.to_ability_name, show_no: "true", show_any: "true", namespace_path: @project.try(:namespace).try(:path), project_path: @project.try(:path), issue_update: issuable_json_path(issuable), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project) } } + %button.dropdown-menu-toggle.js-label-select.js-multiselect.js-label-sidebar-dropdown{ type: "button", data: {toggle: "dropdown", default_label: "Labels", field_name: "#{issuable.to_ability_name}[label_names][]", ability_name: issuable.to_ability_name, show_no: "true", show_any: "true", namespace_path: @project.try(:namespace).try(:full_path), project_path: @project.try(:path), issue_update: issuable_json_path(issuable), labels: (namespace_project_labels_path(@project.namespace, @project, :json) if @project) } } %span.dropdown-toggle-text{ class: ("is-default" if selected_labels.empty?) } = multi_label_name(selected_labels, "Labels") = icon('chevron-down', 'aria-hidden': 'true') diff --git a/app/views/shared/milestones/_tab_loading.html.haml b/app/views/shared/milestones/_tab_loading.html.haml new file mode 100644 index 00000000000..68458c2d0aa --- /dev/null +++ b/app/views/shared/milestones/_tab_loading.html.haml @@ -0,0 +1,2 @@ +.text-center.prepend-top-default + = icon('spin spinner 2x', 'aria-hidden': 'true', 'aria-label': 'Loading tab content') diff --git a/app/views/shared/milestones/_tabs.html.haml b/app/views/shared/milestones/_tabs.html.haml index 9a4502873ef..6a6d817b344 100644 --- a/app/views/shared/milestones/_tabs.html.haml +++ b/app/views/shared/milestones/_tabs.html.haml @@ -1,27 +1,27 @@ .scrolling-tabs-container.inner-page-scroll-tabs.is-smaller .fade-left= icon('angle-left') .fade-right= icon('angle-right') - %ul.nav-links.scrolling-tabs + %ul.nav-links.scrolling-tabs.js-milestone-tabs - if milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project) %li.active = link_to '#tab-issues', 'data-toggle' => 'tab', 'data-show' => '.tab-issues-buttons' do Issues %span.badge= milestone.issues_visible_to_user(current_user).size %li - = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do + = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do Merge Requests %span.badge= milestone.merge_requests.size - else %li.active - = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-show' => '.tab-merge-requests-buttons' do + = link_to '#tab-merge-requests', 'data-toggle' => 'tab', 'data-endpoint': milestone_merge_request_tab_path(milestone) do Merge Requests %span.badge= milestone.merge_requests.size %li - = link_to '#tab-participants', 'data-toggle' => 'tab' do + = link_to '#tab-participants', 'data-toggle' => 'tab', 'data-endpoint': milestone_participants_tab_path(milestone) do Participants %span.badge= milestone.participants.count %li - = link_to '#tab-labels', 'data-toggle' => 'tab' do + = link_to '#tab-labels', 'data-toggle' => 'tab', 'data-endpoint': milestone_labels_tab_path(milestone) do Labels %span.badge= milestone.labels.count @@ -30,14 +30,18 @@ .tab-content.milestone-content - if milestone.is_a?(GlobalMilestone) || can?(current_user, :read_issue, @project) - .tab-pane.active#tab-issues + .tab-pane.active#tab-issues{ data: { sort_endpoint: (sort_issues_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } } = render 'shared/milestones/issues_tab', issues: milestone.issues_visible_to_user(current_user).include_associations, show_project_name: show_project_name, show_full_project_name: show_full_project_name - .tab-pane#tab-merge-requests - = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name + .tab-pane#tab-merge-requests{ data: { sort_endpoint: (sort_merge_requests_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } } + -# loaded async + = render "shared/milestones/tab_loading" - else - .tab-pane.active#tab-merge-requests - = render 'shared/milestones/merge_requests_tab', merge_requests: milestone.merge_requests, show_project_name: show_project_name, show_full_project_name: show_full_project_name + .tab-pane.active#tab-merge-requests{ data: { sort_endpoint: (sort_merge_requests_namespace_project_milestone_path(@project.namespace, @project, @milestone) if @project && current_user) } } + -# loaded async + = render "shared/milestones/tab_loading" .tab-pane#tab-participants - = render 'shared/milestones/participants_tab', users: milestone.participants + -# loaded async + = render "shared/milestones/tab_loading" .tab-pane#tab-labels - = render 'shared/milestones/labels_tab', labels: milestone.labels + -# loaded async + = render "shared/milestones/tab_loading" diff --git a/app/views/shared/snippets/_blob.html.haml b/app/views/shared/snippets/_blob.html.haml index 9bcb4544b97..11f0fa7c49f 100644 --- a/app/views/shared/snippets/_blob.html.haml +++ b/app/views/shared/snippets/_blob.html.haml @@ -1,15 +1,6 @@ - blob = @snippet.blob .js-file-title.file-title-flex-parent - .file-header-content - = blob_icon blob.mode, blob.path - - %strong.file-title-name - = blob.path - - = copy_file_path_button(blob.path) - - %small - = number_to_human_size(blob.raw_size) + = render 'projects/blob/header_content', blob: blob .file-actions.hidden-xs = render 'projects/blob/viewer_switcher', blob: blob diff --git a/app/views/users/_deletion_guidance.html.haml b/app/views/users/_deletion_guidance.html.haml new file mode 100644 index 00000000000..0545cab538c --- /dev/null +++ b/app/views/users/_deletion_guidance.html.haml @@ -0,0 +1,10 @@ +- user = local_assigns.fetch(:user) + +%ul + %li + %p + Certain user content will be moved to a system-wide "Ghost User" in order to maintain content for posterity. For further information, please refer to the + = link_to 'user account deletion documentation.', help_page_path("user/profile/account/delete_account", anchor: "associated-records") + - personal_projects_count = user.personal_projects.count + - unless personal_projects_count.zero? + %li #{pluralize(personal_projects_count, 'personal project')} will be removed and cannot be restored |