diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-23 06:06:01 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-23 06:06:01 +0300 |
commit | 8c7eab92cd0009f55cb999bbade43e0f969c137e (patch) | |
tree | 180cac6632448a211ddbe555191574c98e8dc385 /app/models | |
parent | dffeff5520e861dc6e7319b690c573186bbbd22e (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/project_wiki.rb | 42 | ||||
-rw-r--r-- | app/models/wiki_directory.rb | 63 | ||||
-rw-r--r-- | app/models/wiki_page.rb | 43 |
3 files changed, 114 insertions, 34 deletions
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb index bb222ac7629..e0fcebf2642 100644 --- a/app/models/project_wiki.rb +++ b/app/models/project_wiki.rb @@ -17,6 +17,13 @@ class ProjectWiki CREATED_AT_ORDER = 'created_at' DIRECTION_DESC = 'desc' DIRECTION_ASC = 'asc' + SORT_ORDERS = [TITLE_ORDER, CREATED_AT_ORDER].freeze + SORT_DIRECTIONS = [DIRECTION_ASC, DIRECTION_DESC].freeze + + NESTING_FLAT = 'flat' + NESTING_TREE = 'tree' + NESTING_CLOSED = 'hidden' + NESTINGS = [NESTING_TREE, NESTING_CLOSED, NESTING_FLAT].freeze # Returns a string describing what went wrong after # an operation fails. @@ -58,7 +65,11 @@ class ProjectWiki end def wiki_base_path - [Gitlab.config.gitlab.relative_url_root, '/', @project.full_path, '/wikis'].join('') + ::File.join(project_base_path, 'wikis') + end + + def wiki_page_path + ::File.join(project_base_path, '-', 'wiki_pages') end # Returns the Gitlab::Git::Wiki object. @@ -125,6 +136,23 @@ class ProjectWiki end end + # Finds directory within the repository based on a slug + # + # dir_name - The directory prefix. + # + # Returns an initialized WikiDirectory instance or nil + def find_dir(dir_name, sort = nil, direction = DIRECTION_ASC) + descending = direction == DIRECTION_DESC + # WikiListPagesRequest currently does not support server-side + # filtering. Ideally this logic should be moved to the gitaly + # side. + pages = wiki + .list_pages(sort: sort, direction_desc: descending) + .map { |page| WikiPage.new(self, page, true) } + .select { |wp| wp.directory == dir_name } + WikiDirectory.new(dir_name, pages) if pages.present? + end + def find_sidebar(version = nil) find_page(SIDEBAR, version) end @@ -144,6 +172,12 @@ class ProjectWiki false end + def build_page(attrs) + WikiPage.new(self).tap do |page| + page.update_attributes(attrs) # rubocop:disable Rails/ActiveRecordAliases + end + end + def update_page(page, content:, title: nil, format: :markdown, message: nil) commit = commit_details(:updated, message, page.title) @@ -171,7 +205,7 @@ class ProjectWiki title_array = title.split("/") title = title_array.pop - [title, title_array.join("/")] + [title, ::File.join(title_array)] end def repository @@ -198,6 +232,10 @@ class ProjectWiki private + def project_base_path + ::File.join(Gitlab.config.gitlab.relative_url_root, @project.full_path) + end + def create_repo!(raw_repository) gitlab_shell.create_wiki_repository(project) diff --git a/app/models/wiki_directory.rb b/app/models/wiki_directory.rb index 712ba79bbd2..6c86c11e7fb 100644 --- a/app/models/wiki_directory.rb +++ b/app/models/wiki_directory.rb @@ -1,20 +1,75 @@ # frozen_string_literal: true class WikiDirectory + include StaticModel include ActiveModel::Validations attr_accessor :slug, :pages validates :slug, presence: true + # StaticModel overrides and configuration: + + def self.primary_key + 'slug' + end + + def id + "#{slug}@#{last_version&.sha}" + end + + def self.model_name + ActiveModel::Name.new(self, nil, 'wiki_dir') + end + + alias_method :to_param, :slug + alias_method :title, :slug + + # Sorts and groups pages by directory. + # + # pages - an array of WikiPage objects. + # + # Returns an array of WikiPage and WikiDirectory objects. + # The entries are sorted in the order of the input array, where + # directories appear in the position of their first member. + def self.group_by_directory(pages) + grouped = [] + dirs = Hash.new do |h, k| + new(k).tap { |dir| grouped << (h[k] = dir) } + end + + Array.wrap(pages).each_with_object(grouped) do |page, top_level| + group = page.directory.present? ? dirs[page.directory] : top_level + + group << page + end + end + def initialize(slug, pages = []) @slug = slug @pages = pages end - # Relative path to the partial to be used when rendering collections - # of this object. - def to_partial_path - 'projects/wikis/wiki_directory' + def <<(page) + @pages << page + @last_version = nil + end + + def last_version + @last_version ||= @pages.map(&:last_version).max_by(&:authored_date) + end + + def page_count + @pages.size + end + + def empty? + page_count.zero? + end + + def to_partial_path(context = nil) + name = [context, 'wiki_directory'].compact.join('_') + + "projects/wiki_directories/#{name}" end end diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index 1fa29e5b933..6b3cb0b39d8 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -15,30 +15,7 @@ class WikiPage end def self.model_name - ActiveModel::Name.new(self, nil, 'wiki') - end - - # Sorts and groups pages by directory. - # - # pages - an array of WikiPage objects. - # - # Returns an array of WikiPage and WikiDirectory objects. The entries are - # sorted by alphabetical order (directories and pages inside each directory). - # Pages at the root level come before everything. - def self.group_by_directory(pages) - return [] if pages.blank? - - pages.each_with_object([]) do |page, grouped_pages| - next grouped_pages << page unless page.directory.present? - - directory = grouped_pages.find do |obj| - obj.is_a?(WikiDirectory) && obj.slug == page.directory - end - - next directory.pages << page if directory - - grouped_pages << WikiDirectory.new(page.directory, [page]) - end + ActiveModel::Name.new(self, nil, 'wiki_page') end def self.unhyphenize(name) @@ -66,6 +43,16 @@ class WikiPage Gitlab::HookData::WikiPageBuilder.new(self).build end + # Create a new WikiPage + # + # == Parameters: + # wiki:: + # A `ProjectWiki` model object + # page:: + # A `Gitlab::Git::WikiPage` business object, to which this class provides a facade + # persisted:: + # Is this page fully saved on disk? + # def initialize(wiki, page = nil, persisted = false) @wiki = wiki @page = page @@ -250,10 +237,10 @@ class WikiPage end end - # Relative path to the partial to be used when rendering collections - # of this object. - def to_partial_path - 'projects/wikis/wiki_page' + def to_partial_path(context = nil) + name = [context, 'wiki_page'].compact.join('_') + + "projects/wiki_pages/#{name}" end def id |