Commit e7c7beeb authored by Markus Koller's avatar Markus Koller Committed by Igor Drozdov

Decouple wiki views from projects

- Add generic `wiki_path` / `wiki_page_path` helpers.
- Move views into `app/views/shared`.
- Move JS assets into `app/assets/javascripts/pages/shared`.
- Refer to `@wiki` instead of `@project` in views.
- Use constants on `Wiki` instead of `ProjectWiki`.
parent 1a9ccb74
......@@ -162,7 +162,6 @@ linters:
- "app/views/projects/_home_panel.html.haml"
- "app/views/projects/_import_project_pane.html.haml"
- "app/views/projects/_issuable_by_email.html.haml"
- "app/views/projects/_md_preview.html.haml"
- "app/views/projects/_readme.html.haml"
- "app/views/projects/artifacts/_artifact.html.haml"
- "app/views/projects/artifacts/_tree_file.html.haml"
......@@ -267,7 +266,6 @@ linters:
- "app/views/projects/triggers/_index.html.haml"
- "app/views/projects/triggers/_trigger.html.haml"
- "app/views/projects/triggers/edit.html.haml"
- "app/views/projects/wikis/_pages_wiki_page.html.haml"
- "app/views/search/results/_issue.html.haml"
- "app/views/search/results/_note.html.haml"
- "app/views/search/results/_snippet_blob.html.haml"
......@@ -277,6 +275,7 @@ linters:
- "app/views/shared/_delete_label_modal.html.haml"
- "app/views/shared/_group_form.html.haml"
- "app/views/shared/_group_tips.html.haml"
- "app/views/shared/_md_preview.html.haml"
- "app/views/shared/_milestone_expired.html.haml"
- "app/views/shared/_no_password.html.haml"
- "app/views/shared/_ping_consent.html.haml"
......@@ -313,6 +312,7 @@ linters:
- "app/views/shared/snippets/_snippet.html.haml"
- "app/views/shared/web_hooks/_form.html.haml"
- "app/views/shared/web_hooks/_hook.html.haml"
- "app/views/shared/wikis/_pages_wiki_page.html.haml"
- "app/views/u2f/_authenticate.html.haml"
- "app/views/u2f/_register.html.haml"
- "app/views/users/_deletion_guidance.html.haml"
......
import $ from 'jquery';
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import csrf from '~/lib/utils/csrf';
import ShortcutsWiki from '~/behaviors/shortcuts/shortcuts_wiki';
import Wikis from './wikis';
import ZenMode from '../../../zen_mode';
import GLForm from '../../../gl_form';
import deleteWikiModal from './components/delete_wiki_modal.vue';
import initWikis from '~/pages/shared/wikis';
document.addEventListener('DOMContentLoaded', () => {
new Wikis(); // eslint-disable-line no-new
new ShortcutsWiki(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
new GLForm($('.wiki-form')); // eslint-disable-line no-new
const deleteWikiModalWrapperEl = document.getElementById('delete-wiki-modal-wrapper');
if (deleteWikiModalWrapperEl) {
Vue.use(Translate);
const { deleteWikiUrl, pageTitle } = deleteWikiModalWrapperEl.dataset;
// eslint-disable-next-line no-new
new Vue({
el: deleteWikiModalWrapperEl,
data: {
deleteWikiUrl: '',
},
render(createElement) {
return createElement(deleteWikiModal, {
props: {
pageTitle,
deleteWikiUrl,
csrfToken: csrf.token,
},
});
},
});
}
});
document.addEventListener('DOMContentLoaded', initWikis);
import $ from 'jquery';
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import csrf from '~/lib/utils/csrf';
import ShortcutsWiki from '~/behaviors/shortcuts/shortcuts_wiki';
import Wikis from './wikis';
import ZenMode from '../../../zen_mode';
import GLForm from '../../../gl_form';
import deleteWikiModal from './components/delete_wiki_modal.vue';
export default () => {
new Wikis(); // eslint-disable-line no-new
new ShortcutsWiki(); // eslint-disable-line no-new
new ZenMode(); // eslint-disable-line no-new
new GLForm($('.wiki-form')); // eslint-disable-line no-new
const deleteWikiModalWrapperEl = document.getElementById('delete-wiki-modal-wrapper');
if (deleteWikiModalWrapperEl) {
Vue.use(Translate);
const { deleteWikiUrl, pageTitle } = deleteWikiModalWrapperEl.dataset;
// eslint-disable-next-line no-new
new Vue({
el: deleteWikiModalWrapperEl,
data: {
deleteWikiUrl: '',
},
render(createElement) {
return createElement(deleteWikiModal, {
props: {
pageTitle,
deleteWikiUrl,
csrfToken: csrf.token,
},
});
},
});
}
};
......@@ -34,6 +34,8 @@ module WikiActions
).page(params[:page])
@wiki_entries = WikiPage.group_by_directory(@wiki_pages)
render 'shared/wikis/pages'
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
......@@ -54,7 +56,7 @@ module WikiActions
@ref = params[:version_id]
@path = page.path
render 'show'
render 'shared/wikis/show'
elsif file_blob
send_blob(wiki.repository, file_blob, allow_caching: container.public?)
elsif show_create_form?
......@@ -63,14 +65,15 @@ module WikiActions
@page = build_page(title: title)
render 'edit'
render 'shared/wikis/edit'
else
render 'empty'
render 'shared/wikis/empty'
end
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
def edit
render 'shared/wikis/edit'
end
# rubocop:disable Gitlab/ModuleWithInstanceVariables
......@@ -85,11 +88,11 @@ module WikiActions
notice: _('Wiki was successfully updated.')
)
else
render 'edit'
render 'shared/wikis/edit'
end
rescue WikiPage::PageChangedError, WikiPage::PageRenameError, Gitlab::Git::Wiki::OperationError => e
@error = e
render 'edit'
render 'shared/wikis/edit'
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
......@@ -103,13 +106,12 @@ module WikiActions
notice: _('Wiki was successfully updated.')
)
else
render action: "edit"
render 'shared/wikis/edit'
end
rescue Gitlab::Git::Wiki::OperationError => e
@page = build_page(wiki_params)
@error = e
render 'edit'
render 'shared/wikis/edit'
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
......@@ -119,9 +121,11 @@ module WikiActions
@page_versions = Kaminari.paginate_array(page.versions(page: params[:page].to_i),
total_count: page.count_versions)
.page(params[:page])
render 'shared/wikis/history'
else
redirect_to(
wiki_page_path(wiki, :home),
wiki_path(wiki),
notice: _("Page not found")
)
end
......@@ -132,12 +136,12 @@ module WikiActions
def destroy
WikiPages::DestroyService.new(container: container, current_user: current_user).execute(page)
redirect_to wiki_page_path(wiki, :home),
redirect_to wiki_path(wiki),
status: :found,
notice: _("Page was successfully deleted")
rescue Gitlab::Git::Wiki::OperationError => e
@error = e
render 'edit'
render 'shared/wikis/edit'
end
# rubocop:enable Gitlab/ModuleWithInstanceVariables
......
......@@ -305,8 +305,12 @@ module GitlabRoutingHelper
# Wikis
def wiki_path(wiki, **options)
Gitlab::UrlBuilder.wiki_url(wiki, only_path: true, **options)
end
def wiki_page_path(wiki, page, **options)
Gitlab::UrlBuilder.wiki_page_url(wiki, page, **options, only_path: true)
Gitlab::UrlBuilder.wiki_page_url(wiki, page, only_path: true, **options)
end
private
......
......@@ -544,11 +544,6 @@ module ProjectsHelper
end
end
def project_wiki_path_with_version(proj, page, version, is_newest)
url_params = is_newest ? {} : { version_id: version }
project_wiki_path(proj, page, url_params)
end
def project_status_css_class(status)
case status
when "started"
......
......@@ -22,7 +22,7 @@ module WikiHelper
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, project_wiki_path(@project, current_slug)), location: :after
add_to_breadcrumb_dropdown link_to(WikiPage.unhyphenize(dir_or_page).capitalize, wiki_page_path(@wiki, current_slug)), location: :after
end
end
......@@ -32,7 +32,7 @@ module WikiHelper
content_tag(:div, class: 'alert alert-danger') do
case error
when WikiPage::PageChangedError
page_link = link_to s_("WikiPageConflictMessage|the page"), project_wiki_path(@project, @page), target: "_blank"
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
)
......@@ -45,26 +45,63 @@ module WikiHelper
end
def wiki_attachment_upload_url
expose_url(api_v4_projects_wikis_attachments_path(id: @project.id))
expose_url(api_v4_projects_wikis_attachments_path(id: @wiki.container.id))
end
def wiki_sort_controls(project, sort, direction)
sort ||= ProjectWiki::TITLE_ORDER
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(project_wikis_pages_path(project, sort: sort, direction: reversed_direction),
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 == ProjectWiki::CREATED_AT_ORDER
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: {
title: s_('WikiEmpty|The wiki lets you write documentation for your project'),
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.")
},
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
end
......@@ -15,6 +15,6 @@ class WikiDirectory
# Relative path to the partial to be used when rendering collections
# of this object.
def to_partial_path
'projects/wikis/wiki_directory'
'../shared/wikis/wiki_directory'
end
end
......@@ -261,8 +261,7 @@ class WikiPage
# Relative path to the partial to be used when rendering collections
# of this object.
def to_partial_path
# TODO: Move into shared/ with https://gitlab.com/gitlab-org/gitlab/-/issues/196054
'projects/wikis/wiki_page'
'../shared/wikis/wiki_page'
end
def id
......
......@@ -136,7 +136,7 @@ module Projects
def ensure_wiki_exists
ProjectWiki.new(project, project.owner).wiki
rescue ProjectWiki::CouldNotCreateWikiError
rescue Wiki::CouldNotCreateWikiError
log_error("Could not create wiki for #{project.full_name}")
Gitlab::Metrics.counter(:wiki_can_not_be_created_total, 'Counts the times we failed to create a wiki').increment
end
......
......@@ -11,8 +11,8 @@
.col-form-label.col-sm-2
= f.label :description, "Description"
.col-sm-10
= render layout: 'projects/md_preview', locals: { url: group_preview_markdown_path } do
= render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...', supports_autocomplete: false
= render layout: 'shared/md_preview', locals: { url: group_preview_markdown_path } do
= render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: 'Write milestone description...', supports_autocomplete: false
.clearfix
.error-alert
= render "shared/milestones/form_dates", f: f
......
......@@ -290,7 +290,7 @@
= render 'layouts/nav/sidebar/analytics_links', links: project_analytics_navbar_links(@project, current_user)
- if project_nav_tab? :wiki
- wiki_url = project_wiki_path(@project, :home)
- wiki_url = wiki_path(@project.wiki)
= nav_link(controller: :wikis) do
= link_to wiki_url, class: 'shortcuts-wiki', data: { qa_selector: 'wiki_link' } do
.nav-icon-container
......
......@@ -14,4 +14,4 @@
- if can_create_wiki
%p
= _("Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message.")
= link_to _("Create your first page"), project_wiki_path(@project, :home) + '?view=create', class: "btn btn-primary"
= link_to _("Create your first page"), wiki_path(@project.wiki) + '?view=create', class: "btn btn-primary"
......@@ -28,7 +28,7 @@
.file-buttons
- if is_markdown
= render 'projects/blob/markdown_buttons', show_fullscreen_button: false
= render 'shared/blob/markdown_buttons', show_fullscreen_button: false
= button_tag class: 'soft-wrap-toggle btn', type: 'button', tabindex: '-1' do
%span.no-wrap
= custom_icon('icon_no_wrap')
......
= icon('info-circle fw')
= succeed '.' do
To learn more about this project, read
= link_to "the wiki", project_wiki_path(viewer.project, :home)
= link_to "the wiki", wiki_path(viewer.project.wiki)
......@@ -12,8 +12,8 @@
.col-form-label.col-sm-2
= f.label :description, _('Description')
.col-sm-10
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project) } do
= render 'projects/zen', f: f, attr: :description, classes: 'qa-milestone-description note-textarea', placeholder: _('Write milestone description...')
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project) } do
= render 'shared/zen', f: f, attr: :description, classes: 'qa-milestone-description note-textarea', placeholder: _('Write milestone description...')
= render 'shared/notes/hints'
.clearfix
.error-alert
......
......@@ -46,8 +46,8 @@
- replacements = { releases_page_link_start: releases_page_link_start, docs_link_start: docs_link_start, link_end: link_end }
= s_('TagsPage|Optionally, create a public Release of your project, based on this tag. Release notes are displayed on the %{releases_page_link_start}Releases%{link_end} page. %{docs_link_start}More information%{link_end}').html_safe % replacements
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'projects/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'shared/zen', attr: :release_description, classes: 'note-textarea', placeholder: s_('TagsPage|Write your release notes or drag files here…'), current_text: @release_description
= render 'shared/notes/hints'
.form-actions
= button_tag s_('TagsPage|Create tag'), class: 'btn btn-success'
......
......@@ -10,8 +10,8 @@
= form_for(@release, method: :put, url: project_tag_release_path(@project, @tag.name),
html: { class: 'common-note-form release-form js-quick-submit' }) do |f|
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here…"
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: "Write your release notes or drag files here…"
= render 'shared/notes/hints'
.error-alert
.prepend-top-default
......
- if (@page && @page.persisted?)
- if can?(current_user, :create_wiki, @project)
= link_to project_wikis_new_path(@project), class: "add-new-wiki btn btn-success", role: "button", data: { qa_selector: 'new_page_button' } do
= s_("Wiki|New page")
= link_to project_wiki_history_path(@project, @page), class: "btn", role: "button", data: { qa_selector: 'page_history_button' } do
= s_("Wiki|Page history")
- if can?(current_user, :create_wiki, @project) && @page.latest? && @valid_encoding
= link_to project_wiki_edit_path(@project, @page), class: "btn js-wiki-edit", role: "button", data: { qa_selector: 'edit_page_button' } do
= _("Edit")
= render "#{context}_wiki_page", wiki_page: wiki_page
......@@ -34,4 +34,4 @@
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop
= render 'sidebar'
= render 'shared/wikis/sidebar'
......@@ -18,7 +18,7 @@
= _("Preview")
%li.md-header-toolbar.active
= render 'projects/blob/markdown_buttons', show_fullscreen_button: true
= render 'shared/blob/markdown_buttons', show_fullscreen_button: true
.md-write-holder
= yield
......
- layout_path = 'shared/empty_states/wikis_layout'
- messages = wiki_empty_state_messages(@wiki)
- if can?(current_user, :create_wiki, @project)
- create_path = project_wiki_path(@project, params[:id], { view: 'create' })
- if can?(current_user, :create_wiki, @wiki.container)
- create_path = wiki_page_path(@wiki, params[:id], view: 'create')
- create_link = link_to s_('WikiEmpty|Create your first page'), create_path, class: 'btn btn-success qa-create-first-page-link', title: s_('WikiEmpty|Create your first page')
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_login_empty.svg' } do
%h4.text-left
= s_('WikiEmpty|The wiki lets you write documentation for your project')
= messages.dig(:writable, :title)
%p.text-left
= 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.")
= messages.dig(:writable, :body)
= create_link
- elsif can?(current_user, :read_issue, @project)
- elsif @project && can?(current_user, :read_issue, @project)
- issues_link = link_to s_('WikiEmptyIssueMessage|issue tracker'), project_issues_path(@project)
- new_issue_link = link_to s_('WikiEmpty|Suggest wiki improvement'), new_project_issue_path(@project), class: 'btn btn-success', title: s_('WikiEmptyIssueMessage|Suggest wiki improvement')
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_logout_empty.svg' } do
%h4
= s_('WikiEmpty|This project has no wiki pages')
= messages.dig(:issuable, :title)
%p.text-left
= 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}.').html_safe % { issues_link: issues_link }
= messages.dig(:issuable, :body).html_safe % { issues_link: issues_link }
= new_issue_link
- else
= render layout: layout_path, locals: { image_path: 'illustrations/wiki_logout_empty.svg' } do
%h4
= s_('WikiEmpty|This project has no wiki pages')
= messages.dig(:readonly, :title)
%p
= s_('WikiEmpty|You must be a project member in order to add wiki pages.')
= messages.dig(:readonly, :body)
......@@ -18,8 +18,8 @@
- if model.is_a?(Issuable)
= render 'shared/issuable/form/template_selector', issuable: model
= render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'projects/zen', f: form, attr: :description,
= render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'shared/zen', f: form, attr: :description,
classes: 'note-textarea qa-issuable-form-description rspec-issuable-form-description',
placeholder: placeholder,
supports_quick_actions: supports_quick_actions
......
......@@ -2,8 +2,8 @@
= form_tag '#', method: :put, class: 'edit-note common-note-form js-quick-submit' do
= hidden_field_tag :target_id, '', class: 'js-form-target-id'
= hidden_field_tag :target_type, '', class: 'js-form-target-type'
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(project), referenced_users: true } do
= render 'projects/zen', attr: 'note[note]', classes: 'note-textarea js-note-text js-task-list-field', placeholder: _("Write a comment or drag your files here…")
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(project), referenced_users: true } do
= render 'shared/zen', attr: 'note[note]', classes: 'note-textarea js-note-text js-task-list-field', placeholder: _("Write a comment or drag your files here…")
= render 'shared/notes/hints'
.note-form-actions.clearfix
......
......@@ -25,8 +25,8 @@
= f.hidden_field :position
.discussion-form-container.discussion-with-resolve-btn.flex-column.p-0
= render layout: 'projects/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'projects/zen', f: f,
= render layout: 'shared/md_preview', locals: { url: preview_url, referenced_users: true } do
= render 'shared/zen', f: f,
attr: :note,
classes: 'note-textarea js-note-text',
placeholder: _("Write a comment or drag your files here…"),
......
......@@ -19,8 +19,8 @@
.js-collapsed{ class: ('d-none' if is_expanded) }
= text_field_tag nil, nil, class: 'form-control', placeholder: description_placeholder, data: { qa_selector: 'description_placeholder' }
.js-expanded{ class: ('d-none' if !is_expanded) }
= render layout: 'projects/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'projects/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: description_placeholder, qa_selector: 'snippet_description_field'
= render layout: 'shared/md_preview', locals: { url: preview_markdown_path(@project), referenced_users: true } do
= render 'shared/zen', f: f, attr: :description, classes: 'note-textarea', placeholder: description_placeholder, qa_selector: 'snippet_description_field'
= render 'shared/notes/hints'
.form-group.file-editor
......
- form_classes = 'wiki-form common-note-form prepend-top-default js-quick-submit'
- form_classes += ' js-new-wiki-page' unless @page.persisted?
- form_classes = %w[wiki-form common-note-form prepend-top-default js-quick-submit]
= form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post,
- if @page.persisted?
- form_action = wiki_page_path(@wiki, @page)
- form_method = :put
- else
- form_action = wiki_path(@wiki, action: :create)
- form_method = :post
- form_classes << 'js-new-wiki-page'
= form_for @page, url: form_action, method: form_method,
html: { class: form_classes },
data: { uploads_path: uploads_path } do |f|
= form_errors(@page, truncate: :title)
......@@ -28,14 +35,14 @@
.col-sm-12= f.label :format, class: 'control-label-full-width'
.col-sm-12
.select-wrapper
= f.select :format, options_for_select(ProjectWiki::MARKUPS, {selected: @page.format}), {}, class: 'form-control select-control'
= f.select :format, options_for_select(Wiki::MARKUPS, {selected: @page.format}), {}, class: 'form-control select-control'
= icon('chevron-down')
.form-group.row
.col-sm-12= f.label :content, class: 'control-label-full-width'
.col-sm-12
= render layout: 'projects/md_preview', locals: { url: project_wiki_preview_markdown_path(@project, @page.slug) } do
= render 'projects/zen', f: f, attr: :content, classes: 'note-textarea qa-wiki-content-textarea', placeholder: s_("WikiPage|Write your content or drag files here…")
= render layout: 'shared/md_preview', locals: { url: wiki_page_path(@wiki, @page, action: :preview_markdown) } do
= render 'shared/zen', f: f, attr: :content, classes: 'note-textarea qa-wiki-content-textarea', placeholder: s_("WikiPage|Write your content or drag files here…")
= render 'shared/notes/hints'
.clearfix
......@@ -65,8 +72,8 @@
- if @page && @page.persisted?
= f.submit _("Save changes"), class: 'btn-success btn qa-save-changes-button'
.float-right
= link_to _("Cancel"), project_wiki_path(@project, @page), class: 'btn btn-cancel btn-grouped'
= link_to _("Cancel"), wiki_page_path(@wiki, @page), class: 'btn btn-cancel btn-grouped'
- else
= f.submit s_("Wiki|Create page"), class: 'btn-success btn qa-create-page-button rspec-create-page-button'
.float-right
= link_to _("Cancel"), project_wiki_path(@project, :home), class: 'btn btn-cancel'
= link_to _("Cancel"), wiki_path(@wiki), class: 'btn btn-cancel'
- if @page&.persisted?
- if can?(current_user, :create_wiki, @wiki.container)
= link_to wiki_path(@wiki, action: :new), class: "btn btn-success", role: "button", data: { qa_selector: 'new_page_button' } do
= s_("Wiki|New page")
= link_to wiki_page_path(@wiki, @page, action: :history), class: "btn", role: "button", data: { qa_selector: 'page_history_button' } do
= s_("Wiki|Page history")
- if can?(current_user, :create_wiki, @wiki.container) && @page.latest? && @valid_encoding
= link_to wiki_page_path(@wiki, @page, action: :edit), class: "btn js-wiki-edit", role: "button", data: { qa_selector: 'edit_page_button' } do
= _("Edit")
%li
= link_to wiki_page.title, project_wiki_path(@project, wiki_page)
= link_to wiki_page.title, wiki_page_path(@wiki, wiki_page)
%small (#{wiki_page.format})
.float-right
- if wiki_page.last_version
......
......@@ -4,7 +4,7 @@
%a.gutter-toggle.float-right.d-block.d-sm-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
= icon('angle-double-right')
- git_access_url = project_wikis_git_access_path(@project)
- git_access_url = wiki_path(@wiki, action: :git_access)
= link_to git_access_url, class: active_nav_link?(path: 'wikis#git_access') ? 'active' : '', data: { qa_selector: 'clone_repository_link' } do
= icon('cloud-download', class: 'append-right-5')
%span= _("Clone repository")
......@@ -18,5 +18,5 @@
= render @sidebar_wiki_entries, context: 'sidebar'
.block.w-100
- if @sidebar_limited
= link_to project_wikis_pages_path(@project), class: 'btn btn-block' do
= link_to wiki_path(@wiki, action: :pages), class: 'btn btn-block' do
= s_("Wiki|View All Pages")
%li{ class: active_when(params[:id] == wiki_page.slug) }
= link_to project_wiki_path(@project, wiki_page) do
= link_to wiki_page_path(@wiki, wiki_page) do
= wiki_page.human_title
= render "shared/wikis/#{context}_wiki_page", wiki_page: wiki_page
- @content_class = "limit-container-width" unless fluid_layout
- add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, @page)
- add_to_breadcrumbs _("Wiki"), wiki_page_path(@wiki, @page)
- breadcrumb_title @page.persisted? ? _("Edit") : _("New")
- page_title @page.persisted? ? _("Edit") : _("New"), @page.human_title, _("Wiki")
......@@ -12,7 +12,7 @@
.nav-text
%h2.wiki-page-title
- if @page.persisted?
= link_to @page.human_title, project_wiki_path(@project, @page)
= link_to @page.human_title, wiki_page_path(@wiki, @page)
%span.light
&middot;
= s_("Wiki|Edit Page")
......@@ -21,11 +21,11 @@
.nav-controls.pb-md-3.pb-lg-0
- if @page.persisted?
= link_to project_wiki_history_path(@project, @page), class: "btn" do
= link_to wiki_page_path(@wiki, @page, action: :history), class: "btn" do
= s_("Wiki|Page history")
- if can?(current_user, :admin_wiki, @project)
#delete-wiki-modal-wrapper{ data: { delete_wiki_url: project_wiki_path(@project, @page), page_title: @page.human_title } }
- if can?(current_user, :admin_wiki, @wiki.container)
#delete-wiki-modal-wrapper{ data: { delete_wiki_url: wiki_page_path(@wiki, @page), page_title: @page.human_title } }
= render 'form', uploads_path: wiki_attachment_upload_url
= render 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
= render 'sidebar'
= render 'shared/wikis/sidebar'
......@@ -6,7 +6,7 @@
.nav-text
%h2.wiki-page-title
= link_to @page.human_title, project_wiki_path(@project, @page)
= link_to @page.human_title, wiki_page_path(@wiki, @page)
%span.light
&middot;
= _("History")
......@@ -25,8 +25,7 @@
- commit = version
%tr
%td
= link_to project_wiki_path_with_version(@project, @page,
commit.id, index == 0) do
= link_to wiki_page_path(@wiki, @page, version_id: index == 0 ? nil : commit.id) do
= truncate_sha(commit.id)
%td
= commit.author_name
......@@ -39,4 +38,4 @@
= version.format
= paginate @page_versions, theme: 'gitlab'
= render 'sidebar'
= render 'shared/wikis/sidebar'
- add_to_breadcrumbs "Wiki", project_wiki_path(@project, :home)
- add_to_breadcrumbs "Wiki", wiki_path(@wiki)
- breadcrumb_title s_("Wiki|Pages")
- page_title s_("Wiki|Pages"), _("Wiki")
- sort_title = wiki_sort_title(params[:sort])
......@@ -10,7 +10,7 @@
= s_("Wiki|Wiki Pages")
.nav-controls.pb-md-3.pb-lg-0
= link_to project_wikis_git_access_path(@project), class: 'btn' do
= link_to wiki_path(@wiki, action: :git_access), class: 'btn' do
= icon('cloud-download')
= _("Clone repository")
......@@ -22,9 +22,9 @@
= icon('chevron-down')
%ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
%li
= sortable_item(s_("Wiki|Title"), project_wikis_pages_path(@project, sort: ProjectWiki::TITLE_ORDER), sort_title)
= sortable_item(s_("Wiki|Created date"), project_wikis_pages_path(@project, sort: ProjectWiki::CREATED_AT_ORDER), sort_title)
= wiki_sort_controls(@project, params[:sort], params[:direction])
= sortable_item(s_("Wiki|Title"), wiki_path(@wiki, action: :pages, sort: Wiki::TITLE_ORDER), sort_title)
= sortable_item(s_("Wiki|Created date"), wiki_path(@wiki, action: :pages, sort: Wiki::CREATED_AT_ORDER), sort_title)
= wiki_sort_controls(@wiki, params[:sort], params[:direction])
%ul.wiki-pages-list.content-list
= render @wiki_entries, context: 'pages'
......
......@@ -2,7 +2,7 @@
- breadcrumb_title @page.human_title
- wiki_breadcrumb_dropdown_links(@page.slug)
- page_title @page.human_title, _("Wiki")
- add_to_breadcrumbs _("Wiki"), project_wiki_path(@project, :home)
- add_to_breadcrumbs _("Wiki"), wiki_path(@wiki)
.wiki-page-header.top-area.has-sidebar-toggle.flex-column.flex-lg-row
%button.btn.btn-default.sidebar-toggle.js-sidebar-wiki-toggle{ role: "button", type: "button" }
......@@ -16,17 +16,17 @@
#{time_ago_with_tooltip(@page.last_version.authored_date)}
.nav-controls.pb-md-3.pb-lg-0
= render 'main_links'
= render 'shared/wikis/main_links'
- if @page.historical?
.warning_message
= s_("WikiHistoricalPage|This is an old version of this page.")
- most_recent_link = link_to s_("WikiHistoricalPage|most recent version"), project_wiki_path(@project, @page)
- history_link = link_to s_("WikiHistoricalPage|history"), project_wiki_history_path(@project, @page)
- most_recent_link = link_to s_("WikiHistoricalPage|most recent version"), wiki_page_path(@wiki, @page)
- history_link = link_to s_("WikiHistoricalPage|history"), wiki_page_path(@wiki, @page, action: :history)
= (s_("WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}.") % { most_recent_link: most_recent_link, history_link: history_link }).html_safe
.prepend-top-default.append-bottom-default
.md{ data: { qa_selector: 'wiki_page_content' } }
= render_wiki_content(@page)
= render 'sidebar'
= render 'shared/wikis/sidebar'
......@@ -10,7 +10,7 @@ module Geo
start_registry_sync!
fetch_repository
mark_sync_as_successful
rescue Gitlab::Shell::Error, Gitlab::Git::BaseError, ProjectWiki::CouldNotCreateWikiError => e
rescue Gitlab::Shell::Error, Gitlab::Git::BaseError, Wiki::CouldNotCreateWikiError => e
# In some cases repository does not exist, the only way to know about this is to parse the error text.
# If it does not exist we should consider it as successfully downloaded.
if e.message.include? Gitlab::GitAccess::ERROR_MESSAGES[:no_repo]
......
......@@ -24,7 +24,7 @@ module API
params :common_wiki_page_params do
optional :format,
type: String,
values: ProjectWiki::MARKUPS.values.map(&:to_s),
values: Wiki::MARKUPS.values.map(&:to_s),
default: 'markdown',
desc: 'Format of a wiki page. Available formats are markdown, rdoc, asciidoc and org'
end
......
......@@ -39,7 +39,7 @@ module Gitlab
when User
instance.user_url(object, **options)
when Wiki
wiki_page_url(object, Wiki::HOMEPAGE, **options)
wiki_url(object, **options)
when WikiPage
wiki_page_url(object.wiki, object, **options)
when ::DesignManagement::Design
......@@ -78,12 +78,21 @@ module Gitlab
end
end
def wiki_url(wiki, **options)
return wiki_page_url(wiki, Wiki::HOMEPAGE, **options) unless options[:action]
options[:controller] = 'projects/wikis'
options[:namespace_id] = wiki.container.namespace
options[:project_id] = wiki.container
instance.url_for(**options)
end
def wiki_page_url(wiki, page, **options)
if wiki.container.is_a?(Project)
instance.project_wiki_url(wiki.container, page, **options)
else
raise NotImplementedError.new("No URL builder defined for #{wiki.container.inspect} wikis")
end
options[:action] ||= :show
options[:id] = page
wiki_url(wiki, **options)
end
def design_url(design, **options)
......
......@@ -25286,12 +25286,18 @@ msgstr ""
msgid "WikiEmptyIssueMessage|Suggest wiki improvement"
msgstr ""
msgid "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}."
msgstr ""
msgid "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}."
msgstr ""
msgid "WikiEmptyIssueMessage|issue tracker"
msgstr ""
msgid "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."
msgstr ""
msgid "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."
msgstr ""
......@@ -25301,12 +25307,21 @@ msgstr ""
msgid "WikiEmpty|Suggest wiki improvement"
msgstr ""
msgid "WikiEmpty|The wiki lets you write documentation for your group"
msgstr ""
msgid "WikiEmpty|The wiki lets you write documentation for your project"
msgstr ""
msgid "WikiEmpty|This group has no wiki pages"
msgstr ""
msgid "WikiEmpty|This project has no wiki pages"
msgstr ""
msgid "WikiEmpty|You must be a group member in order to add wiki pages."
msgstr ""
msgid "WikiEmpty|You must be a project member in order to add wiki pages."
msgstr ""
......
......@@ -31,7 +31,7 @@ module QA
element :submit_button
end
view 'app/views/projects/_zen.html.haml' do
view 'app/views/shared/_zen.html.haml' do
# This 'element' is here only to ensure the changes in the view source aren't mistakenly changed
element :_, "qa_selector = local_assigns.fetch(:qa_selector, '')" # rubocop:disable QA/ElementWithPattern
end
......
......@@ -14,7 +14,7 @@ module QA
end
view 'app/views/shared/form_elements/_description.html.haml' do
element :issue_description_textarea, "render 'projects/zen', f: form, attr: :description" # rubocop:disable QA/ElementWithPattern
element :issue_description_textarea, "render 'shared/zen', f: form, attr: :description" # rubocop:disable QA/ElementWithPattern
end
def add_title(title)
......
......@@ -5,7 +5,7 @@ module QA
module Project
module Wiki
class Edit < Page::Base
view 'app/views/projects/wikis/_form.html.haml' do
view 'app/views/shared/wikis/_form.html.haml' do
element :wiki_title_textbox
element :wiki_content_textarea
element :wiki_message_textbox
......
......@@ -7,16 +7,16 @@ module QA
class Show < Page::Base
include Component::LazyLoader
view 'app/views/projects/wikis/_sidebar.html.haml' do
view 'app/views/shared/wikis/_sidebar.html.haml' do
element :clone_repository_link
end
view 'app/views/projects/wikis/show.html.haml' do
view 'app/views/shared/wikis/show.html.haml' do
element :wiki_page_title
element :wiki_page_content
end
view 'app/views/projects/wikis/_main_links.html.haml' do
view 'app/views/shared/wikis/_main_links.html.haml' do
element :new_page_button
element :page_history_button
element :edit_page_button
......
......@@ -84,7 +84,7 @@ describe 'Project active tab' do
context 'on project Wiki' do
before do
visit project_wiki_path(project, :home)
visit wiki_path(project.wiki)
end
it_behaves_like 'page has active tab', 'Wiki'
......
......@@ -94,7 +94,7 @@ describe 'Edit Project Settings' do
{
builds: project_job_path(project, job),
issues: project_issues_path(project),
wiki: project_wiki_path(project, :home),
wiki: wiki_path(project.wiki),
snippets: project_snippets_path(project),
merge_requests: project_merge_requests_path(project)
}
......
......@@ -29,7 +29,7 @@ RSpec.describe 'User updates wiki page' do
click_on('Cancel')
end
expect(current_path).to eq project_wiki_path(project, :home)
expect(current_path).to eq wiki_path(project.wiki)
end
it 'updates a page that has a path', :js do
......
......@@ -12,6 +12,8 @@ RSpec.describe 'User views empty wiki' do
element = page.find('.row.empty-state')
expect(element).to have_content('This project has no wiki pages')
expect(element).to have_content('You must be a project member')
expect(element).to have_content('improve the wiki for this project')
expect(element).to have_link("issue tracker", href: project_issues_path(project))
expect(element).to have_link("Suggest wiki improvement", href: new_project_issue_path(project))
end
......@@ -24,6 +26,7 @@ RSpec.describe 'User views empty wiki' do
element = page.find('.row.empty-state')
expect(element).to have_content('This project has no wiki pages')
expect(element).to have_content('You must be a project member')
expect(element).to have_no_link('Suggest wiki improvement')
end
end
......@@ -66,9 +69,10 @@ RSpec.describe 'User views empty wiki' do
it 'show "create first page" message' do
visit(project_wikis_path(project))
element = page.find('.row.empty-state')
expect(element).to have_content('your project', count: 2)
element.click_link 'Create your first page'
expect(page).to have_button('Create page')
......
import Wikis from '~/pages/projects/wikis/wikis';
import Wikis from '~/pages/shared/wikis/wikis';
import { setHTMLFixture } from './helpers/fixtures';
describe('Wikis', () => {
......
......@@ -22,12 +22,12 @@ describe WikiHelper do
end
describe '#wiki_sort_controls' do
let(:project) { create(:project) }
let(:wiki_link) { helper.wiki_sort_controls(project, sort, direction) }
let(:wiki) { create(:project_wiki) }
let(:wiki_link) { helper.wiki_sort_controls(wiki, sort, direction) }
let(:classes) { "btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" }
def expected_link(sort, direction, icon_class)
path = "/#{project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}"
path = "/#{wiki.project.full_path}/-/wikis/pages?direction=#{direction}&sort=#{sort}"
helper.link_to(path, type: 'button', class: classes, title: 'Sort direction') do
helper.sprite_icon("sort-#{icon_class}", size: 16)
......
......@@ -96,6 +96,38 @@ describe Gitlab::UrlBuilder do
end
end
context 'when passing a Wiki' do
let(:wiki) { build_stubbed(:project_wiki) }
describe '#wiki_url' do
it 'uses the default collection action' do
url = subject.wiki_url(wiki)
expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/home"
end
it 'supports a custom collection action' do
url = subject.wiki_url(wiki, action: :pages)
expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/pages"
end
end
describe '#wiki_page_url' do
it 'uses the default member action' do
url = subject.wiki_page_url(wiki, 'foo')
expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/foo"
end
it 'supports a custom member action' do
url = subject.wiki_page_url(wiki, 'foo', action: :edit)
expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki.project.full_path}/-/wikis/foo/edit"
end
end
end
context 'when passing a DesignManagement::Design' do
let(:design) { build_stubbed(:design) }
......
......@@ -40,7 +40,7 @@ RSpec.describe WikiDirectory do
it 'returns the relative path to the partial to be used' do
directory = build(:wiki_directory)
expect(directory.to_partial_path).to eq('projects/wikis/wiki_directory')
expect(directory.to_partial_path).to eq('../shared/wikis/wiki_directory')
end
end
end
......@@ -781,7 +781,7 @@ describe WikiPage do
describe '#to_partial_path' do
it 'returns the relative path to the partial to be used' do
expect(subject.to_partial_path).to eq('projects/wikis/wiki_page')
expect(subject.to_partial_path).to eq('../shared/wikis/wiki_page')
end
end
......
......@@ -254,7 +254,7 @@ describe Projects::UpdateService do
it 'logs an error and creates a metric when wiki can not be created' do
project.project_feature.update(wiki_access_level: ProjectFeature::DISABLED)
expect_any_instance_of(ProjectWiki).to receive(:wiki).and_raise(ProjectWiki::CouldNotCreateWikiError)
expect_any_instance_of(ProjectWiki).to receive(:wiki).and_raise(Wiki::CouldNotCreateWikiError)
expect_any_instance_of(described_class).to receive(:log_error).with("Could not create wiki for #{project.full_name}")
counter = double(:counter)
......
......@@ -66,7 +66,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'shows the wiki tab with the wiki internal link' do
render
expect(rendered).to have_link('Wiki', href: project_wiki_path(project, :home))
expect(rendered).to have_link('Wiki', href: wiki_path(project.wiki))
end
end
......@@ -76,7 +76,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'does not show the wiki tab' do
render
expect(rendered).not_to have_link('Wiki', href: project_wiki_path(project, :home))
expect(rendered).not_to have_link('Wiki', href: wiki_path(project.wiki))
end
end
end
......@@ -104,7 +104,7 @@ describe 'layouts/nav/sidebar/_project' do
it 'does not show the external wiki tab' do
render
expect(rendered).not_to have_link('External Wiki', href: project_wiki_path(project, :home))
expect(rendered).not_to have_link('External Wiki')
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment