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-10-06 06:08:18 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-06 06:08:18 +0300
commit53a3791717e8925078f074b976a561c7a72b1b22 (patch)
tree826aea342691595c3d3cdc716019a81e09c05873 /app
parenta807e50ade2a78add0c13b75575203d7d99e8a4c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb3
-rw-r--r--app/graphql/types/work_items/widgets/labels_update_input_type.rb20
-rw-r--r--app/helpers/appearances_helper.rb8
-rw-r--r--app/helpers/wiki_helper.rb5
-rw-r--r--app/models/wiki.rb116
-rw-r--r--app/models/wiki_page.rb11
-rw-r--r--app/services/concerns/work_items/widgetable_service.rb12
-rw-r--r--app/services/issuable_base_service.rb5
-rw-r--r--app/services/work_items/update_service.rb11
-rw-r--r--app/services/work_items/widgets/base_service.rb5
-rw-r--r--app/services/work_items/widgets/labels_service/update_service.rb15
-rw-r--r--app/views/layouts/devise.html.haml4
-rw-r--r--app/views/shared/wikis/pages.html.haml3
13 files changed, 188 insertions, 30 deletions
diff --git a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
index 1f90f394521..e42e59de78f 100644
--- a/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
+++ b/app/graphql/mutations/concerns/mutations/work_items/update_arguments.rb
@@ -30,6 +30,9 @@ module Mutations
argument :start_and_due_date_widget, ::Types::WorkItems::Widgets::StartAndDueDateUpdateInputType,
required: false,
description: 'Input for start and due date widget.'
+ argument :labels_widget, ::Types::WorkItems::Widgets::LabelsUpdateInputType,
+ required: false,
+ description: 'Input for labels widget.'
end
end
end
diff --git a/app/graphql/types/work_items/widgets/labels_update_input_type.rb b/app/graphql/types/work_items/widgets/labels_update_input_type.rb
new file mode 100644
index 00000000000..d38b8cefa63
--- /dev/null
+++ b/app/graphql/types/work_items/widgets/labels_update_input_type.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ module Widgets
+ class LabelsUpdateInputType < BaseInputObject
+ graphql_name 'WorkItemWidgetLabelsUpdateInput'
+
+ argument :add_label_ids, [Types::GlobalIDType[::Label]],
+ required: false,
+ description: 'Global IDs of labels to be added to the work item.',
+ prepare: ->(label_ids, _ctx) { label_ids.map(&:model_id) }
+ argument :remove_label_ids, [Types::GlobalIDType[::Label]],
+ required: false,
+ description: 'Global IDs of labels to be removed from the work item.',
+ prepare: ->(label_ids, _ctx) { label_ids.map(&:model_id) }
+ end
+ end
+ end
+end
diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb
index 6dbd0f7bd7b..957c2afb6d2 100644
--- a/app/helpers/appearances_helper.rb
+++ b/app/helpers/appearances_helper.rb
@@ -14,7 +14,13 @@ module AppearancesHelper
end
def brand_image
- image_tag(current_appearance.logo_path) if current_appearance&.logo?
+ image_tag(brand_image_path, alt: brand_title, class: 'gl-w-10')
+ end
+
+ def brand_image_path
+ return current_appearance.logo_path if current_appearance&.logo?
+
+ image_path('logo.svg')
end
def brand_text
diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb
index d6ffd3deafe..c42e3a5ff99 100644
--- a/app/helpers/wiki_helper.rb
+++ b/app/helpers/wiki_helper.rb
@@ -65,7 +65,10 @@ module WikiHelper
reversed_direction = direction == 'desc' ? 'asc' : 'desc'
icon_class = direction == 'desc' ? 'highest' : 'lowest'
- link_to(wiki_path(wiki, action: :pages, sort: sort, direction: reversed_direction),
+ link_options = { action: :pages, direction: reversed_direction }
+ link_options[:sort] = sort unless wiki.disable_sorting?
+
+ link_to(wiki_path(wiki, **link_options),
type: 'button', class: link_class, title: _('Sort direction')) do
sprite_icon("sort-#{icon_class}")
end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index afdac86d9c7..11ff4333a07 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -173,7 +173,7 @@ class Wiki
end
def empty?
- !repository_exists? || list_pages(limit: 1).empty?
+ !repository_exists? || list_page_paths.empty?
end
def exists?
@@ -191,13 +191,11 @@ class Wiki
# Returns an Array of GitLab WikiPage instances or an
# empty Array if this Wiki has no pages.
def list_pages(limit: 0, sort: nil, direction: DIRECTION_ASC, load_content: false)
- wiki.list_pages(
- limit: limit,
- sort: sort,
- direction_desc: direction == DIRECTION_DESC,
- load_content: load_content
- ).map do |page|
- WikiPage.new(self, page)
+ if list_pages_with_repository_rpcs?
+ create_wiki_repository unless repository_exists?
+ list_pages_with_repository_rpcs(limit: limit, sort: sort, direction: direction, load_content: load_content)
+ else
+ list_pages_with_legacy_wiki_service(limit: limit, sort: sort, direction: direction, load_content: load_content)
end
end
@@ -383,6 +381,10 @@ class Wiki
false
end
+ def disable_sorting?
+ list_pages_with_repository_rpcs?
+ end
+
private
def multi_commit_options(action, message = nil, title = nil)
@@ -452,14 +454,7 @@ class Wiki
def find_matched_file(title, version)
escaped_path = RE2::Regexp.escape(sluggified_title(title))
- # We could not use ALLOWED_EXTENSIONS_REGEX constant or similar regexp with
- # Regexp.union. The result combination complicated modifiers:
- # /(?i-mx:md|mkdn?|mdown|markdown)|(?i-mx:rdoc).../
- # Regexp used by Gitaly is Go's Regexp package. It does not support those
- # features. So, we have to compose another more-friendly regexp to pass to
- # Gitaly side.
- extension_regexp = Wiki::MARKUPS.map { |_, format| format[:extension_regex].source }.join("|")
- path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)^#{escaped_path}\\.(#{extension_regexp})$")
+ path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)^#{escaped_path}\\.(#{file_extension_regexp})$")
matched_files = repository.search_files_by_regexp(path_regexp, version)
return if matched_files.blank?
@@ -487,7 +482,7 @@ class Wiki
format = find_page_format(path)
page = Gitlab::Git::WikiPage.new(
- url_path: sluggified_title(path.sub(/\.[^.]+\z/, "")),
+ url_path: sluggified_title(strip_extension(path)),
title: canonicalize_filename(path),
format: format,
path: sluggified_title(path),
@@ -509,6 +504,93 @@ class Wiki
Feature.enabled?(:wiki_find_page_with_normal_repository_rpcs, group, type: :development)
end
+
+ def file_extension_regexp
+ # We could not use ALLOWED_EXTENSIONS_REGEX constant or similar regexp with
+ # Regexp.union. The result combination complicated modifiers:
+ # /(?i-mx:md|mkdn?|mdown|markdown)|(?i-mx:rdoc).../
+ # Regexp used by Gitaly is Go's Regexp package. It does not support those
+ # features. So, we have to compose another more-friendly regexp to pass to
+ # Gitaly side.
+ Wiki::MARKUPS.map { |_, format| format[:extension_regex].source }.join("|")
+ end
+
+ def strip_extension(path)
+ path.sub(/\.[^.]+\z/, "")
+ end
+
+ def list_pages_with_repository_rpcs?
+ group =
+ if container.is_a?(::Group)
+ container
+ else
+ container.group
+ end
+
+ Feature.enabled?(:wiki_list_pages_with_normal_repository_rpcs, group, type: :development)
+ end
+
+ def list_page_paths
+ return [] if repository.empty?
+
+ path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)\\.(#{file_extension_regexp})$")
+ repository.search_files_by_regexp(path_regexp, default_branch)
+ end
+
+ def list_pages_with_repository_rpcs(limit:, sort:, direction:, load_content:)
+ paths = list_page_paths
+ return [] if paths.empty?
+
+ pages = paths.map do |path|
+ page = Gitlab::Git::WikiPage.new(
+ url_path: sluggified_title(strip_extension(path)),
+ title: canonicalize_filename(path),
+ format: find_page_format(path),
+ path: sluggified_title(path),
+ raw_data: '',
+ name: canonicalize_filename(path),
+ historical: false
+ )
+ WikiPage.new(self, page)
+ end
+ sort_pages!(pages, sort, direction)
+ pages = pages.take(limit) if limit > 0
+ fetch_pages_content!(pages) if load_content
+
+ pages
+ end
+
+ def list_pages_with_legacy_wiki_service(limit:, sort:, direction:, load_content:)
+ wiki.list_pages(
+ limit: limit,
+ sort: sort,
+ direction_desc: direction == DIRECTION_DESC,
+ load_content: load_content
+ ).map do |page|
+ WikiPage.new(self, page)
+ end
+ end
+
+ # After migrating to normal repository RPCs, it's very expensive to sort the
+ # pages by created_at. We have to either ListLastCommitsForTree RPC call or
+ # N+1 LastCommitForPath. Either are efficient for a large repository.
+ # Therefore, we decide to sort the title only.
+ def sort_pages!(pages, _sort, direction)
+ # Sort by path to ensure the files inside a sub-folder are grouped and sorted together
+ pages.sort_by!(&:path)
+ pages.reverse! if direction == DIRECTION_DESC
+ end
+
+ def fetch_pages_content!(pages)
+ blobs =
+ repository
+ .blobs_at(pages.map { |page| [default_branch, page.path] } )
+ .to_h { |blob| [blob.path, blob.data] }
+
+ pages.each do |page|
+ page.raw_content = blobs[page.path]
+ end
+ end
end
Wiki.prepend_mod_with('Wiki')
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 5cdd1fdadcb..ad07e0269f6 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -99,6 +99,13 @@ class WikiPage
attributes[:content] ||= page&.text_data
end
+ def raw_content=(content)
+ return if page.nil?
+
+ page.raw_data = content
+ attributes[:content] = page.text_data
+ end
+
# The hierarchy of the directory this page is contained in.
def directory
wiki.page_title_and_dir(slug)&.last.to_s
@@ -118,7 +125,7 @@ class WikiPage
def version
return unless persisted?
- @version ||= @page.version
+ @version ||= @page.version || last_version
end
def path
@@ -151,7 +158,7 @@ class WikiPage
end
def last_version
- @last_version ||= versions(limit: 1).first
+ @last_version ||= wiki.repository.last_commit_for_path(wiki.default_branch, page.path) if page
end
def last_commit_sha
diff --git a/app/services/concerns/work_items/widgetable_service.rb b/app/services/concerns/work_items/widgetable_service.rb
index beb614c7b76..24ade9336b2 100644
--- a/app/services/concerns/work_items/widgetable_service.rb
+++ b/app/services/concerns/work_items/widgetable_service.rb
@@ -2,18 +2,22 @@
module WorkItems
module WidgetableService
- def execute_widgets(work_item:, callback:, widget_params: {})
+ def execute_widgets(work_item:, callback:, widget_params: {}, service_params: {})
work_item.widgets.each do |widget|
- widget_service(widget).try(callback, params: widget_params[widget.class.api_symbol])
+ widget_service(widget, service_params).try(callback, params: widget_params[widget.class.api_symbol])
end
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
- def widget_service(widget)
+ def widget_service(widget, service_params)
@widget_services ||= {}
return @widget_services[widget] if @widget_services.has_key?(widget)
- @widget_services[widget] = widget_service_class(widget)&.new(widget: widget, current_user: current_user)
+ @widget_services[widget] = widget_service_class(widget)&.new(
+ widget: widget,
+ current_user: current_user,
+ service_params: service_params
+ )
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index febb2f56e86..40c7742a3aa 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -266,6 +266,10 @@ class IssuableBaseService < ::BaseProjectService
# To be overridden by subclasses
end
+ def prepare_update_params(issuable)
+ # To be overridden by subclasses
+ end
+
def after_update(issuable)
handle_description_updated(issuable)
end
@@ -277,6 +281,7 @@ class IssuableBaseService < ::BaseProjectService
end
def update(issuable)
+ prepare_update_params(issuable)
handle_quick_actions(issuable)
filter_params(issuable)
diff --git a/app/services/work_items/update_service.rb b/app/services/work_items/update_service.rb
index 2deb8c82741..e87a19422cb 100644
--- a/app/services/work_items/update_service.rb
+++ b/app/services/work_items/update_service.rb
@@ -26,6 +26,17 @@ module WorkItems
private
+ def prepare_update_params(work_item)
+ execute_widgets(
+ work_item: work_item,
+ callback: :prepare_update_params,
+ widget_params: @widget_params,
+ service_params: params
+ )
+
+ super
+ end
+
def before_update(work_item, skip_spam_check: false)
execute_widgets(work_item: work_item, callback: :before_update_callback, widget_params: @widget_params)
diff --git a/app/services/work_items/widgets/base_service.rb b/app/services/work_items/widgets/base_service.rb
index 37ed2bf4b05..1ff03a09f9f 100644
--- a/app/services/work_items/widgets/base_service.rb
+++ b/app/services/work_items/widgets/base_service.rb
@@ -5,12 +5,13 @@ module WorkItems
class BaseService < ::BaseService
WidgetError = Class.new(StandardError)
- attr_reader :widget, :work_item, :current_user
+ attr_reader :widget, :work_item, :current_user, :service_params
- def initialize(widget:, current_user:)
+ def initialize(widget:, current_user:, service_params: {})
@widget = widget
@work_item = widget.work_item
@current_user = current_user
+ @service_params = service_params
end
private
diff --git a/app/services/work_items/widgets/labels_service/update_service.rb b/app/services/work_items/widgets/labels_service/update_service.rb
new file mode 100644
index 00000000000..f00ea5c95ca
--- /dev/null
+++ b/app/services/work_items/widgets/labels_service/update_service.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module WorkItems
+ module Widgets
+ module LabelsService
+ class UpdateService < WorkItems::Widgets::BaseService
+ def prepare_update_params(params: {})
+ return if params.blank?
+
+ service_params.merge!(params.slice(:add_label_ids, :remove_label_ids))
+ end
+ end
+ end
+ end
+end
diff --git a/app/views/layouts/devise.html.haml b/app/views/layouts/devise.html.haml
index 6650e07be2a..3532c6638ce 100644
--- a/app/views/layouts/devise.html.haml
+++ b/app/views/layouts/devise.html.haml
@@ -13,9 +13,9 @@
= render "layouts/flash"
.mt-3
.col-sm-12.gl-text-center
- %img.gl-w-10{ :alt => _("GitLab Logo"), :src => image_path('logo.svg') }
+ = brand_image
%h1.mb-3.gl-font-size-h2
- = current_appearance&.title.presence || _('GitLab')
+ = brand_title
- if current_appearance&.description?
= brand_text
= render_if_exists 'layouts/devise_help_text'
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
index 21d63a6db3d..79c5bb62f28 100644
--- a/app/views/shared/wikis/pages.html.haml
+++ b/app/views/shared/wikis/pages.html.haml
@@ -15,7 +15,8 @@
.dropdown.inline.wiki-sort-dropdown
.btn-group{ role: 'group' }
- = gl_redirect_listbox_tag wiki_sort_options, params[:sort], data: { right: true }
+ - unless @wiki.disable_sorting?
+ = gl_redirect_listbox_tag wiki_sort_options, params[:sort], data: { right: true }
= wiki_sort_controls(@wiki, params[:sort], params[:direction])
%ul.wiki-pages-list.content-list