summaryrefslogtreecommitdiff
path: root/app/helpers/wiki_helper.rb
blob: cf2d2d178e1a7e7b0bb18f2684fa4880d0938860 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# frozen_string_literal: true

module WikiHelper
  include API::Helpers::RelatedResourcesHelpers

  def wiki_page_title(page, action = nil)
    titles = [_('Wiki')]

    if page.persisted?
      titles << page.human_title
      breadcrumb_title(page.human_title)
      wiki_breadcrumb_dropdown_links(page.slug)
    end

    titles << action if action
    page_title(*titles.reverse)
    add_to_breadcrumbs(_('Wiki'), wiki_path(page.wiki))
  end

  def link_to_wiki_page(page, **options)
    link_to page.human_title, wiki_page_path(page.wiki, page), **options
  end

  def wiki_sidebar_toggle_button
    content_tag :button, class: 'btn btn-default sidebar-toggle js-sidebar-wiki-toggle', role: 'button', type: 'button' do
      sprite_icon('chevron-double-lg-left')
    end
  end

  # Produces a pure text breadcrumb for a given page.
  #
  # page_slug - The slug of a WikiPage object.
  #
  # Returns a String composed of the capitalized name of each directory and the
  # capitalized name of the page itself.
  def breadcrumb(page_slug)
    page_slug.split('/')
      .map { |dir_or_page| WikiPage.unhyphenize(dir_or_page).capitalize }
      .join(' / ')
  end

  def wiki_breadcrumb_dropdown_links(page_slug)
    page_slug_split = page_slug.split('/')
    page_slug_split.pop(1)
    current_slug = ""
    page_slug_split
      .map do |dir_or_page|
        current_slug = "#{current_slug}#{dir_or_page}/"
        add_to_breadcrumb_dropdown link_to(WikiPage.unhyphenize(dir_or_page).capitalize, wiki_page_path(@wiki, current_slug)), location: :after
      end
  end

  def wiki_page_errors(error)
    return unless error

    content_tag(:div, class: 'alert alert-danger') do
      case error
      when WikiPage::PageChangedError
        page_link = link_to s_("WikiPageConflictMessage|the page"), wiki_page_path(@wiki, @page), target: "_blank"
        concat(
          (s_("WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{page_link} and make sure your changes will not unintentionally remove theirs.") % { page_link: page_link }).html_safe
        )
      when WikiPage::PageRenameError
        s_("WikiEdit|There is already a page with the same title in that path.")
      else
        error.message
      end
    end
  end

  def wiki_attachment_upload_url
    expose_url(api_v4_projects_wikis_attachments_path(id: @wiki.container.id))
  end

  def wiki_sort_controls(wiki, sort, direction)
    sort ||= Wiki::TITLE_ORDER
    link_class = 'btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort'
    reversed_direction = direction == 'desc' ? 'asc' : 'desc'
    icon_class = direction == 'desc' ? 'highest' : 'lowest'

    link_to(wiki_path(wiki, action: :pages, sort: sort, direction: reversed_direction),
      type: 'button', class: link_class, title: _('Sort direction')) do
      sprite_icon("sort-#{icon_class}", size: 16)
    end
  end

  def wiki_sort_title(key)
    if key == Wiki::CREATED_AT_ORDER
      s_("Wiki|Created date")
    else
      s_("Wiki|Title")
    end
  end

  def wiki_empty_state_messages(wiki)
    case wiki.container
    when Project
      writable_body = s_("WikiEmpty|A wiki is where you can store all the details about your project. This can include why you've created it, its principles, how to use it, and so on.")
      writable_body += s_("WikiEmpty| Have a Confluence wiki already? Use that instead.") if show_enable_confluence_integration?(wiki.container)

      {
        writable: {
          title: s_('WikiEmpty|The wiki lets you write documentation for your project'),
          body: writable_body
        },
        issuable: {
          title: s_('WikiEmpty|This project has no wiki pages'),
          body: s_('WikiEmptyIssueMessage|You must be a project member in order to add wiki pages. If you have suggestions for how to improve the wiki for this project, consider opening an issue in the %{issues_link}.')
        },
        readonly: {
          title: s_('WikiEmpty|This project has no wiki pages'),
          body: s_('WikiEmpty|You must be a project member in order to add wiki pages.')
        }
      }
    when Group
      {
        writable: {
          title: s_('WikiEmpty|The wiki lets you write documentation for your group'),
          body: s_("WikiEmpty|A wiki is where you can store all the details about your group. This can include why you've created it, its principles, how to use it, and so on.")
        },
        issuable: {
          title: s_('WikiEmpty|This group has no wiki pages'),
          body: s_('WikiEmptyIssueMessage|You must be a group member in order to add wiki pages. If you have suggestions for how to improve the wiki for this group, consider opening an issue in the %{issues_link}.')
        },
        readonly: {
          title: s_('WikiEmpty|This group has no wiki pages'),
          body: s_('WikiEmpty|You must be a group member in order to add wiki pages.')
        }
      }
    else
      raise NotImplementedError, "Unknown wiki container type #{wiki.container.class.name}"
    end
  end

  def wiki_page_tracking_context(page)
    {
      'wiki-format'               => page.format,
      'wiki-title-size'           => page.title.bytesize,
      'wiki-content-size'         => page.raw_content.bytesize,
      'wiki-directory-nest-level' => page.path.scan('/').count
    }
  end

  def show_enable_confluence_integration?(container)
    container.is_a?(Project) &&
      current_user&.can?(:admin_project, container) &&
      !container.has_confluence?
  end
end