summaryrefslogtreecommitdiff
path: root/app/views/shared
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-18 11:18:50 +0000
commit8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 (patch)
treea77e7fe7a93de11213032ed4ab1f33a3db51b738 /app/views/shared
parent00b35af3db1abfe813a778f643dad221aad51fca (diff)
downloadgitlab-ce-8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781.tar.gz
Add latest changes from gitlab-org/gitlab@13-1-stable-ee
Diffstat (limited to 'app/views/shared')
-rw-r--r--app/views/shared/_broadcast_message.html.haml4
-rw-r--r--app/views/shared/_choose_avatar_button.html.haml5
-rw-r--r--app/views/shared/_custom_attributes.html.haml12
-rw-r--r--app/views/shared/_field.html.haml5
-rw-r--r--app/views/shared/_file_highlight.html.haml2
-rw-r--r--app/views/shared/_file_picker_button.html.haml6
-rw-r--r--app/views/shared/_group_form.html.haml4
-rw-r--r--app/views/shared/_md_preview.html.haml36
-rw-r--r--app/views/shared/_namespace_storage_limit_alert.html.haml26
-rw-r--r--app/views/shared/_new_merge_request_checkbox.html.haml2
-rw-r--r--app/views/shared/_promo.html.haml6
-rw-r--r--app/views/shared/_service_settings.html.haml10
-rw-r--r--app/views/shared/_visibility_level.html.haml2
-rw-r--r--app/views/shared/_visibility_radios.html.haml7
-rw-r--r--app/views/shared/_zen.html.haml19
-rw-r--r--app/views/shared/access_tokens/_created_container.html.haml2
-rw-r--r--app/views/shared/access_tokens/_form.html.haml2
-rw-r--r--app/views/shared/blob/_markdown_buttons.html.haml13
-rw-r--r--app/views/shared/boards/_show.html.haml29
-rw-r--r--app/views/shared/deploy_keys/_form.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_index.html.haml2
-rw-r--r--app/views/shared/deploy_keys/_project_group_form.html.haml4
-rw-r--r--app/views/shared/deploy_tokens/_index.html.haml2
-rw-r--r--app/views/shared/deploy_tokens/_new_deploy_token.html.haml2
-rw-r--r--app/views/shared/empty_states/_snippets.html.haml4
-rw-r--r--app/views/shared/empty_states/_wikis.html.haml19
-rw-r--r--app/views/shared/file_hooks/_index.html.haml2
-rw-r--r--app/views/shared/form_elements/_description.html.haml4
-rw-r--r--app/views/shared/groups/_group.html.haml37
-rw-r--r--app/views/shared/issuable/_form.html.haml2
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml3
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml15
-rw-r--r--app/views/shared/issuable/form/_metadata.html.haml8
-rw-r--r--app/views/shared/milestones/_deprecation_message.html.haml4
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml12
-rw-r--r--app/views/shared/milestones/_header.html.haml6
-rw-r--r--app/views/shared/milestones/_milestone.html.haml92
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml56
-rw-r--r--app/views/shared/milestones/_top.html.haml27
-rw-r--r--app/views/shared/notes/_edit_form.html.haml4
-rw-r--r--app/views/shared/notes/_form.html.haml4
-rw-r--r--app/views/shared/notifications/_custom_notifications.html.haml4
-rw-r--r--app/views/shared/notifications/_new_button.html.haml2
-rw-r--r--app/views/shared/projects/_project.html.haml12
-rw-r--r--app/views/shared/snippets/_form.html.haml8
-rw-r--r--app/views/shared/snippets/_header.html.haml6
-rw-r--r--app/views/shared/tokens/_scopes_list.html.haml2
-rw-r--r--app/views/shared/web_hooks/_hook.html.haml4
-rw-r--r--app/views/shared/web_hooks/_title_and_docs.html.haml13
-rw-r--r--app/views/shared/wikis/_form.html.haml79
-rw-r--r--app/views/shared/wikis/_main_links.html.haml9
-rw-r--r--app/views/shared/wikis/_pages_wiki_page.html.haml6
-rw-r--r--app/views/shared/wikis/_sidebar.html.haml22
-rw-r--r--app/views/shared/wikis/_sidebar_wiki_page.html.haml3
-rw-r--r--app/views/shared/wikis/_wiki_directory.html.haml4
-rw-r--r--app/views/shared/wikis/_wiki_page.html.haml1
-rw-r--r--app/views/shared/wikis/edit.html.haml31
-rw-r--r--app/views/shared/wikis/empty.html.haml4
-rw-r--r--app/views/shared/wikis/history.html.haml41
-rw-r--r--app/views/shared/wikis/pages.html.haml32
-rw-r--r--app/views/shared/wikis/show.html.haml32
62 files changed, 598 insertions, 222 deletions
diff --git a/app/views/shared/_broadcast_message.html.haml b/app/views/shared/_broadcast_message.html.haml
index b809696cccb..3e889900981 100644
--- a/app/views/shared/_broadcast_message.html.haml
+++ b/app/views/shared/_broadcast_message.html.haml
@@ -1,4 +1,6 @@
-%div{ class: "broadcast-#{message.broadcast_type}-message #{opts[:preview] && 'preview'} js-broadcast-notification-#{message.id} d-flex",
+- is_banner = message.broadcast_type == 'banner'
+
+%div{ class: "broadcast-message #{'alert-warning' if is_banner} broadcast-#{message.broadcast_type}-message #{opts[:preview] && 'preview'} js-broadcast-notification-#{message.id} gl-display-flex",
style: broadcast_message_style(message), dir: 'auto' }
.flex-grow-1.text-right.pr-2
= sprite_icon('bullhorn', size: 16, css_class: 'vertical-align-text-top')
diff --git a/app/views/shared/_choose_avatar_button.html.haml b/app/views/shared/_choose_avatar_button.html.haml
index 0d46d047134..caf2bdce899 100644
--- a/app/views/shared/_choose_avatar_button.html.haml
+++ b/app/views/shared/_choose_avatar_button.html.haml
@@ -1,4 +1 @@
-%button.btn.js-choose-avatar-button{ type: 'button' }= _("Choose file…")
-%span.file_name.js-avatar-filename= _("No file chosen")
-= f.file_field :avatar, class: "js-avatar-input hidden"
-.form-text.text-muted= _("The maximum file size allowed is 200KB.")
+= render 'shared/file_picker_button', f: f, field: :avatar, help_text: _("The maximum file size allowed is 200KB.")
diff --git a/app/views/shared/_custom_attributes.html.haml b/app/views/shared/_custom_attributes.html.haml
new file mode 100644
index 00000000000..966ab8e3cb1
--- /dev/null
+++ b/app/views/shared/_custom_attributes.html.haml
@@ -0,0 +1,12 @@
+- return unless custom_attributes.present?
+
+.card
+ .card-header
+ = link_to(_('Custom Attributes'), help_page_path('api/custom_attributes.md'))
+ %ul.content-list
+ - custom_attributes.each do |custom_attribute|
+ %li
+ %span.light
+ = custom_attribute.key
+ %strong
+ = custom_attribute.value
diff --git a/app/views/shared/_field.html.haml b/app/views/shared/_field.html.haml
index 4f416c483f2..2480014ea42 100644
--- a/app/views/shared/_field.html.haml
+++ b/app/views/shared/_field.html.haml
@@ -3,6 +3,7 @@
- value = @service.send(name)
- type = field[:type]
- placeholder = field[:placeholder]
+- autocomplete = field[:autocomplete]
- required = field[:required]
- choices = field[:choices]
- default_choice = field[:default_choice]
@@ -15,13 +16,13 @@
= form.label name, title, class: "col-form-label col-sm-2"
.col-sm-10
- if type == 'text'
- = form.text_field name, class: "form-control", placeholder: placeholder, required: required, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
+ = form.text_field name, class: "form-control", autocomplete: autocomplete, placeholder: placeholder, required: required, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
- elsif type == 'textarea'
= form.text_area name, rows: 5, class: "form-control", placeholder: placeholder, required: required
- elsif type == 'checkbox'
= form.check_box name
- elsif type == 'select'
- = form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control"}
+ = form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control"} # rubocop:disable Style/RedundantCondition
- elsif type == 'password'
= form.password_field name, autocomplete: "new-password", placeholder: placeholder, class: "form-control", required: value.blank? && required, data: { qa_selector: "#{name.downcase.gsub('\s', '')}_field" }
- if help
diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml
index 18f51f0c0c8..b9952d6832f 100644
--- a/app/views/shared/_file_highlight.html.haml
+++ b/app/views/shared/_file_highlight.html.haml
@@ -1,4 +1,4 @@
-.file-content.code.js-syntax-highlight.qa-file-content
+.file-content.code.js-syntax-highlight
.line-numbers
- if blob.data.present?
- link_icon = icon('link')
diff --git a/app/views/shared/_file_picker_button.html.haml b/app/views/shared/_file_picker_button.html.haml
new file mode 100644
index 00000000000..7c9a3bd3d31
--- /dev/null
+++ b/app/views/shared/_file_picker_button.html.haml
@@ -0,0 +1,6 @@
+%span.js-filepicker
+ %button.btn.js-filepicker-button{ type: 'button' }= _("Choose file…")
+ %span.file_name.js-filepicker-filename= _("No file chosen")
+ = f.file_field field, class: "js-filepicker-input hidden"
+ - if help_text.present?
+ .form-text.text-muted= help_text
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index 019b2ef89a4..09b9cd448bb 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -6,7 +6,7 @@
.form-group.group-name-holder.col-sm-12
= f.label :name, class: 'label-bold' do
= _("Group name")
- = f.text_field :name, placeholder: _('My Awesome Group'), class: 'form-control input-lg',
+ = f.text_field :name, placeholder: _('My Awesome Group'), class: 'js-autofill-group-name form-control input-lg',
required: true,
title: _('Please fill in a descriptive name for your group.'),
autofocus: true
@@ -22,7 +22,7 @@
- if parent
%strong= parent.full_path + '/'
= f.hidden_field :parent_id
- = f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path',
+ = f.text_field :path, placeholder: _('my-awesome-group'), class: 'form-control js-validate-group-path js-autofill-group-path',
autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
title: _('Please choose a group URL with no special characters.'),
diff --git a/app/views/shared/_md_preview.html.haml b/app/views/shared/_md_preview.html.haml
new file mode 100644
index 00000000000..f5f24b2f0ce
--- /dev/null
+++ b/app/views/shared/_md_preview.html.haml
@@ -0,0 +1,36 @@
+- referenced_users = local_assigns.fetch(:referenced_users, nil)
+
+- if defined?(@merge_request) && @merge_request.discussion_locked?
+ .issuable-note-warning
+ = sprite_icon('lock', size: 16, css_class: 'icon')
+ %span
+ = _('This merge request is locked.')
+ = _('Only project members can comment.')
+
+.md-area.position-relative
+ .md-header
+ %ul.nav.nav-tabs.nav-links.clearfix
+ %li.md-header-tab.active
+ %button.js-md-write-button{ tabindex: -1 }
+ = _("Write")
+ %li.md-header-tab
+ %button.js-md-preview-button{ tabindex: -1 }
+ = _("Preview")
+
+ %li.md-header-toolbar.active
+ = render 'shared/blob/markdown_buttons', show_fullscreen_button: true
+
+ .md-write-holder
+ = yield
+ .md.md-preview-holder.js-md-preview.hide{ data: { url: url } }
+ .referenced-commands.hide
+
+ - if referenced_users
+ .referenced-users.hide
+ %span
+ = icon("exclamation-triangle")
+ You are about to add
+ %strong
+ %span.js-referenced-users-count 0
+ people
+ to the discussion. Proceed with caution.
diff --git a/app/views/shared/_namespace_storage_limit_alert.html.haml b/app/views/shared/_namespace_storage_limit_alert.html.haml
new file mode 100644
index 00000000000..95f27cde15b
--- /dev/null
+++ b/app/views/shared/_namespace_storage_limit_alert.html.haml
@@ -0,0 +1,26 @@
+- return unless current_user
+
+- payload = namespace_storage_alert(namespace)
+- return if payload.empty?
+
+- alert_level = payload[:alert_level]
+- root_namespace = payload[:root_namespace]
+
+- style = namespace_storage_alert_style(alert_level)
+- icon = namespace_storage_alert_icon(alert_level)
+- link = namespace_storage_usage_link(root_namespace)
+
+%div{ class: [classes, 'js-namespace-storage-alert'] }
+ .gl-pt-5.gl-pb-3
+ .gl-alert{ class: "gl-alert-#{style}", role: 'alert' }
+ = sprite_icon(icon, css_class: "gl-icon gl-alert-icon")
+ .gl-alert-title
+ %h4.gl-alert-title= payload[:usage_message]
+ - if alert_level != :error
+ %button.js-namespace-storage-alert-dismiss.gl-alert-dismiss.gl-cursor-pointer{ type: 'button', 'aria-label' => _('Dismiss'), data: { id: root_namespace.id, level: alert_level } }
+ = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ .gl-alert-body
+ = payload[:explanation_message]
+ - if link
+ .gl-alert-actions
+ = link_to(_('Manage storage usage'), link, class: "btn gl-alert-action btn-md gl-button btn-#{style}")
diff --git a/app/views/shared/_new_merge_request_checkbox.html.haml b/app/views/shared/_new_merge_request_checkbox.html.haml
index 24c0dfe247f..6bc6d0943c9 100644
--- a/app/views/shared/_new_merge_request_checkbox.html.haml
+++ b/app/views/shared/_new_merge_request_checkbox.html.haml
@@ -1,4 +1,4 @@
-.form-check.prepend-top-8
+.form-check.gl-mt-3
- nonce = SecureRandom.hex
= check_box_tag 'create_merge_request', 1, true, class: 'js-create-merge-request form-check-input', id: "create_merge_request-#{nonce}"
= label_tag "create_merge_request-#{nonce}", class: 'form-check-label' do
diff --git a/app/views/shared/_promo.html.haml b/app/views/shared/_promo.html.haml
index 0f31b60d8d3..855f6b9c1f4 100644
--- a/app/views/shared/_promo.html.haml
+++ b/app/views/shared/_promo.html.haml
@@ -1,5 +1,5 @@
.gitlab-promo
- = link_to 'Homepage', promo_url
- = link_to 'Blog', promo_url + '/blog/'
+ = link_to _('Homepage'), promo_url
+ = link_to _('Blog'), promo_url + '/blog/'
= link_to '@gitlab', 'https://twitter.com/gitlab'
- = link_to 'Requests', 'https://gitlab.com/gitlab-org/gitlab-foss/blob/master/CONTRIBUTING.md#feature-proposals'
+ = link_to _('Requests'), 'https://gitlab.com/gitlab-org/gitlab-foss/blob/master/CONTRIBUTING.md#feature-proposals'
diff --git a/app/views/shared/_service_settings.html.haml b/app/views/shared/_service_settings.html.haml
index a9203459914..92b86c6fec1 100644
--- a/app/views/shared/_service_settings.html.haml
+++ b/app/views/shared/_service_settings.html.haml
@@ -1,5 +1,4 @@
= form_errors(@service)
-- trigger_events = Feature.enabled?(:integration_form_refactor) ? ServiceEventSerializer.new(service: @service).represent(@service.configurable_events).to_json : []
- if lookup_context.template_exists?('help', "projects/services/#{@service.to_param}", true)
= render "projects/services/#{@service.to_param}/help", subject: @service
@@ -10,9 +9,9 @@
.service-settings
.js-vue-integration-settings{ data: { show_active: @service.show_active_box?.to_s, activated: (@service.active || @service.new_record?).to_s, type: @service.to_param, merge_request_events: @service.merge_requests_events.to_s,
-commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on_event_enabled.to_s, comment_detail: @service.comment_detail, trigger_events: trigger_events } }
+commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on_event_enabled.to_s, comment_detail: @service.comment_detail, trigger_events: trigger_events_for_service, fields: fields_for_service } }
- - if @service.configurable_events.present? && !@service.is_a?(JiraService) && Feature.disabled?(:integration_form_refactor)
+ - if show_service_trigger_events?
.form-group.row
%label.col-form-label.col-sm-2= _('Trigger')
@@ -33,5 +32,6 @@ commit_events: @service.commit_events.to_s, enable_comments: @service.comment_on
%p.text-muted
= @service.class.event_description(event)
- - @service.global_fields.each do |field|
- = render 'shared/field', form: form, field: field
+ - unless integration_form_refactor?
+ - @service.global_fields.each do |field|
+ = render 'shared/field', form: form, field: field
diff --git a/app/views/shared/_visibility_level.html.haml b/app/views/shared/_visibility_level.html.haml
index 2f42a877beb..84ce40e240c 100644
--- a/app/views/shared/_visibility_level.html.haml
+++ b/app/views/shared/_visibility_level.html.haml
@@ -2,7 +2,7 @@
.form-group.visibility-level-setting
- if with_label
- = f.label :visibility_level, _('Visibility level'), class: 'label-bold append-bottom-0'
+ = f.label :visibility_level, _('Visibility level'), class: 'label-bold gl-mb-0'
%p
= _('Who can see this group?')
- visibility_docs_path = help_page_path('public_access/public_access')
diff --git a/app/views/shared/_visibility_radios.html.haml b/app/views/shared/_visibility_radios.html.haml
index 80532c9187b..90b12557bc8 100644
--- a/app/views/shared/_visibility_radios.html.haml
+++ b/app/views/shared/_visibility_radios.html.haml
@@ -1,8 +1,7 @@
-- Gitlab::VisibilityLevel.values.each do |level|
- - disallowed = disallowed_visibility_level?(form_model, level)
- - restricted = restricted_visibility_levels.include?(level)
- - next if disallowed || restricted
+- available_visibility_levels = available_visibility_levels(form_model)
+- selected_level = snippets_selected_visibility_level(available_visibility_levels, selected_level)
+- available_visibility_levels.each do |level|
.form-check
= form.radio_button model_method, level, checked: (selected_level == level), class: 'form-check-input', data: { track_label: "blank_project", track_event: "activate_form_input", track_property: "#{model_method}_#{level}", track_value: "", qa_selector: "#{visibility_level_label(level).downcase}_radio" }
= form.label "#{model_method}_#{level}", class: 'form-check-label' do
diff --git a/app/views/shared/_zen.html.haml b/app/views/shared/_zen.html.haml
new file mode 100644
index 00000000000..8dd0e5a92a7
--- /dev/null
+++ b/app/views/shared/_zen.html.haml
@@ -0,0 +1,19 @@
+- @gfm_form = true
+- current_text ||= nil
+- supports_autocomplete = local_assigns.fetch(:supports_autocomplete, true)
+- supports_quick_actions = local_assigns.fetch(:supports_quick_actions, false)
+- qa_selector = local_assigns.fetch(:qa_selector, '')
+.zen-backdrop
+ - classes << ' js-gfm-input js-autosize markdown-area'
+ - if defined?(f) && f
+ = f.text_area attr,
+ class: classes,
+ placeholder: placeholder,
+ dir: 'auto',
+ data: { supports_quick_actions: supports_quick_actions,
+ supports_autocomplete: supports_autocomplete,
+ qa_selector: qa_selector }
+ - else
+ = text_area_tag attr, current_text, class: classes, placeholder: placeholder
+ %a.zen-control.zen-control-leave.js-zen-leave.gl-text-gray-700{ href: "#" }
+ = sprite_icon('compress', size: 16)
diff --git a/app/views/shared/access_tokens/_created_container.html.haml b/app/views/shared/access_tokens/_created_container.html.haml
index f11ef1e01de..c5a18d98b89 100644
--- a/app/views/shared/access_tokens/_created_container.html.haml
+++ b/app/views/shared/access_tokens/_created_container.html.haml
@@ -1,5 +1,5 @@
.created-personal-access-token-container
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Your new %{type}') % { type: type }
.form-group
.input-group
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index cb7f907308f..680626f7880 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -1,7 +1,7 @@
- title = local_assigns.fetch(:title, _('Add a %{type}') % { type: type })
- prefix = local_assigns.fetch(:prefix, :personal_access_token)
-%h5.prepend-top-0
+%h5.gl-mt-0
= title
%p.profile-settings-content
= _("Enter the name of your application, and we'll return a unique %{type}.") % { type: type }
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
new file mode 100644
index 00000000000..c1ffdc7184a
--- /dev/null
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -0,0 +1,13 @@
+.md-header-toolbar.active
+ = markdown_toolbar_button({ icon: "bold", data: { "md-tag" => "**" }, title: _("Add bold text") })
+ = markdown_toolbar_button({ icon: "italic", data: { "md-tag" => "*" }, title: _("Add italic text") })
+ = markdown_toolbar_button({ icon: "quote", data: { "md-tag" => "> ", "md-prepend" => true }, title: _("Insert a quote") })
+ = markdown_toolbar_button({ icon: "code", data: { "md-tag" => "`", "md-block" => "```" }, title: _("Insert code") })
+ = markdown_toolbar_button({ icon: "link", data: { "md-tag" => "[{text}](url)", "md-select" => "url" }, title: _("Add a link") })
+ = markdown_toolbar_button({ icon: "list-bulleted", data: { "md-tag" => "- ", "md-prepend" => true }, title: _("Add a bullet list") })
+ = markdown_toolbar_button({ icon: "list-numbered", data: { "md-tag" => "1. ", "md-prepend" => true }, title: _("Add a numbered list") })
+ = markdown_toolbar_button({ icon: "list-task", data: { "md-tag" => "- [ ] ", "md-prepend" => true }, title: _("Add a task list") })
+ = markdown_toolbar_button({ icon: "table", data: { "md-tag" => "| header | header |\n| ------ | ------ |\n| cell | cell |\n| cell | cell |", "md-prepend" => true }, title: _("Add a table") })
+ - if show_fullscreen_button
+ %button.toolbar-btn.toolbar-fullscreen-btn.js-zen-enter.has-tooltip{ type: "button", tabindex: -1, "aria-label": "Go full screen", title: _("Go full screen"), data: { container: "body" } }
+ = sprite_icon("screen-full")
diff --git a/app/views/shared/boards/_show.html.haml b/app/views/shared/boards/_show.html.haml
index cf42ac3dd37..902b6d19f82 100644
--- a/app/views/shared/boards/_show.html.haml
+++ b/app/views/shared/boards/_show.html.haml
@@ -20,20 +20,31 @@
#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
= render 'shared/issuable/search_bar', type: :boards, board: board
- .boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } }
- .boards-app-loading.w-100.text-center{ "v-if" => "loading" }
- = icon("spinner spin 2x")
- %board{ "v-cloak" => "true",
- "v-for" => "list in state.lists",
- "ref" => "board",
+ - if Feature.enabled?(:boards_with_swimlanes, current_board_parent)
+ %board-content{ "v-cloak" => "true",
+ "ref" => "board_content",
+ ":lists" => "state.lists",
":can-admin-list" => can_admin_list,
":group-id" => group_id,
- ":list" => "list",
":disabled" => "disabled",
":issue-link-base" => "issueLinkBase",
":root-path" => "rootPath",
- ":board-id" => "boardId",
- ":key" => "list.id" }
+ ":board-id" => "boardId" }
+ - else
+ .boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } }
+ .boards-app-loading.w-100.text-center{ "v-if" => "loading" }
+ = icon("spinner spin 2x")
+ %board{ "v-cloak" => "true",
+ "v-for" => "list in state.lists",
+ "ref" => "board",
+ ":can-admin-list" => can_admin_list,
+ ":group-id" => group_id,
+ ":list" => "list",
+ ":disabled" => "disabled",
+ ":issue-link-base" => "issueLinkBase",
+ ":root-path" => "rootPath",
+ ":board-id" => "boardId",
+ ":key" => "list.id" }
= render "shared/boards/components/sidebar", group: group
= render_if_exists 'shared/boards/components/board_settings_sidebar'
- if @project
diff --git a/app/views/shared/deploy_keys/_form.html.haml b/app/views/shared/deploy_keys/_form.html.haml
index 1944c293be1..94742d96af7 100644
--- a/app/views/shared/deploy_keys/_form.html.haml
+++ b/app/views/shared/deploy_keys/_form.html.haml
@@ -30,5 +30,5 @@
= deploy_keys_project_form.label :can_push do
= deploy_keys_project_form.check_box :can_push
%strong= _('Write access allowed')
- %p.light.append-bottom-0
+ %p.light.gl-mb-0
= _('Allow this key to push to repository as well? (Default only allows pull access.)')
diff --git a/app/views/shared/deploy_keys/_index.html.haml b/app/views/shared/deploy_keys/_index.html.haml
index f28e745f4c5..358075b9e44 100644
--- a/app/views/shared/deploy_keys/_index.html.haml
+++ b/app/views/shared/deploy_keys/_index.html.haml
@@ -7,7 +7,7 @@
%p
= _('Deploy keys allow read-only or read-write (if enabled) access to your repository. Deploy keys can be used for CI, staging or production servers. You can create a deploy key or add an existing one.')
.settings-content
- %h5.prepend-top-0
+ %h5.gl-mt-0
= _('Create a new deploy key for this project')
= render @deploy_keys.form_partial_path
%hr
diff --git a/app/views/shared/deploy_keys/_project_group_form.html.haml b/app/views/shared/deploy_keys/_project_group_form.html.haml
index 8edd1d9deb8..4e569050827 100644
--- a/app/views/shared/deploy_keys/_project_group_form.html.haml
+++ b/app/views/shared/deploy_keys/_project_group_form.html.haml
@@ -7,7 +7,7 @@
= f.label :key, class: "label-bold"
= f.text_area :key, class: "form-control", rows: 5, required: true
.form-group.row
- %p.light.append-bottom-0
+ %p.light.gl-mb-0
= _('Paste a machine public key here. Read more about how to generate it')
= link_to "here", help_page_path("ssh/README")
@@ -17,7 +17,7 @@
= deploy_keys_project_form.check_box :can_push
%strong= _('Write access allowed')
.form-group.row
- %p.light.append-bottom-0
+ %p.light.gl-mb-0
= _('Allow this key to push to repository as well? (Default only allows pull access.)')
.form-group.row
diff --git a/app/views/shared/deploy_tokens/_index.html.haml b/app/views/shared/deploy_tokens/_index.html.haml
index b0c9c72dfaa..8203b378297 100644
--- a/app/views/shared/deploy_tokens/_index.html.haml
+++ b/app/views/shared/deploy_tokens/_index.html.haml
@@ -10,7 +10,7 @@
.settings-content
- if @new_deploy_token.persisted?
= render 'shared/deploy_tokens/new_deploy_token', deploy_token: @new_deploy_token
- %h5.prepend-top-0
+ %h5.gl-mt-0
= s_('DeployTokens|Add a deploy token')
= render 'shared/deploy_tokens/form', group_or_project: group_or_project, token: @new_deploy_token, presenter: @deploy_tokens
%hr
diff --git a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
index f295fa82192..a9728dc841f 100644
--- a/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
+++ b/app/views/shared/deploy_tokens/_new_deploy_token.html.haml
@@ -1,6 +1,6 @@
.qa-created-deploy-token-section.created-deploy-token-container.info-well
.well-segment
- %h5.prepend-top-0
+ %h5.gl-mt-0
= s_('DeployTokens|Your New Deploy Token')
.form-group
diff --git a/app/views/shared/empty_states/_snippets.html.haml b/app/views/shared/empty_states/_snippets.html.haml
index efd9bceedc5..db8da50d868 100644
--- a/app/views/shared/empty_states/_snippets.html.haml
+++ b/app/views/shared/empty_states/_snippets.html.haml
@@ -3,7 +3,7 @@
.row.empty-state.mt-0
.col-12
.svg-content
- = image_tag 'illustrations/snippets_empty.svg'
+ = image_tag 'illustrations/snippets_empty.svg', data: { qa_selector: 'svg_content' }
.text-content.text-center.pt-0
- if current_user
%h4
@@ -12,7 +12,7 @@
= s_('SnippetsEmptyState|Store, share, and embed small pieces of code and text.')
.mt-2<
- if button_path
- = link_to s_('SnippetsEmptyState|New snippet'), button_path, class: 'btn btn-success', title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link'
+ = link_to s_('SnippetsEmptyState|New snippet'), button_path, class: 'btn btn-success', title: s_('SnippetsEmptyState|New snippet'), id: 'new_snippet_link', data: { qa_selector: 'create_first_snippet_link' }
= link_to s_('SnippetsEmptyState|Documentation'), help_page_path('user/snippets.md'), class: 'btn btn-default', title: s_('SnippetsEmptyState|Documentation')
- else
%h4.text-center= s_('SnippetsEmptyState|There are no snippets to show.')
diff --git a/app/views/shared/empty_states/_wikis.html.haml b/app/views/shared/empty_states/_wikis.html.haml
index 73eedcc1dc9..ff5ee801969 100644
--- a/app/views/shared/empty_states/_wikis.html.haml
+++ b/app/views/shared/empty_states/_wikis.html.haml
@@ -1,30 +1,31 @@
- 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)
diff --git a/app/views/shared/file_hooks/_index.html.haml b/app/views/shared/file_hooks/_index.html.haml
index 0e1f41bbbf6..436bd305df1 100644
--- a/app/views/shared/file_hooks/_index.html.haml
+++ b/app/views/shared/file_hooks/_index.html.haml
@@ -2,7 +2,7 @@
.row.prepend-top-default
.col-lg-4
- %h4.prepend-top-0
+ %h4.gl-mt-0
= _('File Hooks')
%p
= _('File hooks are similar to system hooks but are executed as files instead of sending data to a URL.')
diff --git a/app/views/shared/form_elements/_description.html.haml b/app/views/shared/form_elements/_description.html.haml
index 2f2e6d83f9f..77af4f09408 100644
--- a/app/views/shared/form_elements/_description.html.haml
+++ b/app/views/shared/form_elements/_description.html.haml
@@ -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
diff --git a/app/views/shared/groups/_group.html.haml b/app/views/shared/groups/_group.html.haml
index 60c9c076a70..5dac400bd5e 100644
--- a/app/views/shared/groups/_group.html.haml
+++ b/app/views/shared/groups/_group.html.haml
@@ -1,28 +1,29 @@
- user = local_assigns.fetch(:user, current_user)
- access = user&.max_member_access_for_group(group.id)
-%li.group-row.py-3{ class: ('no-description' if group.description.blank?) }
- .stats
- %span
+%li.group-row.py-3.gl-align-items-center{ class: "gl-display-flex!#{' no-description' if group.description.blank?}" }
+ .avatar-container.rect-avatar.s40.gl-flex-shrink-0
+ = link_to group do
+ = group_icon(group, class: "avatar s40")
+ .gl-min-w-0.gl-flex-grow-1
+ .title
+ = link_to group.full_name, group, class: 'group-name'
+
+ - if access&.nonzero?
+ %span.user-access-role= Gitlab::Access.human_access(access)
+
+ - if group.description.present?
+ .description
+ = markdown_field(group, :description)
+
+ .stats.gl-text-gray-700.gl-flex-shrink-0
+ %span.gl-ml-5
= icon('bookmark')
= number_with_delimiter(group.projects.non_archived.count)
- %span
+ %span.gl-ml-5
= icon('users')
= number_with_delimiter(group.users.count)
- %span.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
+ %span.gl-ml-5.visibility-icon.has-tooltip{ data: { container: 'body', placement: 'left' }, title: visibility_icon_description(group) }
= visibility_level_icon(group.visibility_level, fw: false)
-
- .avatar-container.rect-avatar.s40
- = link_to group do
- = group_icon(group, class: "avatar s40")
- .title
- = link_to group.full_name, group, class: 'group-name'
-
- - if access&.nonzero?
- %span.user-access-role= Gitlab::Access.human_access(access)
-
- - if group.description.present?
- .description
- = markdown_field(group, :description)
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index a020a04e366..1b3ad484bcc 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -31,7 +31,7 @@
= form.label :confidential, class: 'form-check-label' do
This issue is confidential and should only be visible to team members with at least Reporter access.
-= render 'shared/issuable/form/metadata', issuable: issuable, form: form
+= render 'shared/issuable/form/metadata', issuable: issuable, form: form, project: project
= render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index 34be9291f1f..d53ec4d4eeb 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -173,6 +173,8 @@
= render 'shared/issuable/board_create_list_dropdown', board: board
- if @project
#js-add-issues-btn.prepend-left-10{ data: { can_admin_list: can?(current_user, :admin_list, @project) } }
+ - if Feature.enabled?(:boards_with_swimlanes, @group)
+ #js-board-epics-swimlanes-toggle
#js-toggle-focus-btn
- elsif is_not_boards_modal_or_productivity_analytics && show_sorting_dropdown
= render 'shared/issuable/sort_dropdown'
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index a1c56cdb64f..ab4bd88cfe5 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -53,7 +53,8 @@
.selectbox.hide-collapsed
= f.hidden_field 'milestone_id', value: milestone[:id], id: nil
= dropdown_tag('Milestone', options: { title: _('Assign milestone'), toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: _('Search milestones'), data: { show_no: true, field_name: "#{issuable_type}[milestone_id]", project_id: issuable_sidebar[:project_id], issuable_id: issuable_sidebar[:id], milestones: issuable_sidebar[:project_milestones_path], ability_name: issuable_type, issue_update: issuable_sidebar[:issuable_json_path], use_id: true, default_no: true, selected: milestone[:title], null_default: true, display: 'static' }})
-
+ - if @project.group.present?
+ = render_if_exists 'shared/issuable/iteration_select', { can_edit: can_edit_issuable, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type }
#issuable-time-tracker.block
// Fallback while content is loading
.title.hide-collapsed
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index 4192ecd2238..cf239a5d04c 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -40,4 +40,17 @@
- data['max-select'] = dropdown_options[:data][:'max-select'] if dropdown_options[:data][:'max-select']
- options[:data].merge!(data)
- = dropdown_tag(title, options: options)
+ - if experiment_enabled?(:invite_members_version_a) && can_import_members?
+ - options[:dropdown_class] += ' dropdown-extended-height'
+ - options[:footer_content] = true
+ - options[:wrapper_class] = 'js-sidebar-assignee-dropdown'
+
+ = dropdown_tag(title, options: options) do
+ %ul.dropdown-footer-list
+ %li
+ = link_to _('Invite Members'),
+ project_project_members_path(@project),
+ title: _('Invite Members'),
+ data: { 'is-link': true, 'track-event': 'click_invite_members', 'track-label': 'edit_assignee' }
+ - else
+ = dropdown_tag(title, options: options)
diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml
index 90a6a98235d..1389bc2ab4d 100644
--- a/app/views/shared/issuable/form/_metadata.html.haml
+++ b/app/views/shared/issuable/form/_metadata.html.haml
@@ -1,3 +1,4 @@
+- project = local_assigns.fetch(:project)
- issuable = local_assigns.fetch(:issuable)
- return unless can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project)
@@ -10,6 +11,9 @@
%div{ class: (has_due_date ? "col-lg-6" : "col-12") }
.form-group.row.merge-request-assignee
= render "shared/issuable/form/metadata_issuable_assignee", issuable: issuable, form: form, has_due_date: has_due_date
+
+ = render_if_exists "shared/issuable/form/epic", issuable: issuable, form: form, project: project
+
.form-group.row.issue-milestone
= form.label :milestone_id, "Milestone", class: "col-form-label #{has_due_date ? "col-md-2 col-lg-4" : "col-sm-2"}"
.col-sm-10{ class: ("col-md-8" if has_due_date) }
@@ -22,11 +26,11 @@
.issuable-form-select-holder
= render "shared/issuable/label_dropdown", classes: ["js-issuable-form-dropdown"], selected: issuable.labels, data_options: { field_name: "#{issuable.class.model_name.param_key}[label_ids][]", show_any: false }, dropdown_title: "Select label"
- = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form
= render_if_exists "shared/issuable/form/merge_request_blocks", issuable: issuable, form: form
- - if has_due_date
+ - if has_due_date || issuable.supports_weight?
.col-lg-6
+ = render_if_exists "shared/issuable/form/weight", issuable: issuable, form: form
.form-group.row
= form.label :due_date, "Due date", class: "col-form-label col-md-2 col-lg-4"
.col-8
diff --git a/app/views/shared/milestones/_deprecation_message.html.haml b/app/views/shared/milestones/_deprecation_message.html.haml
index acd90fa9178..ba5eb54f017 100644
--- a/app/views/shared/milestones/_deprecation_message.html.haml
+++ b/app/views/shared/milestones/_deprecation_message.html.haml
@@ -1,14 +1,14 @@
.banner-callout.compact.milestone-deprecation-message.js-milestone-deprecation-message.prepend-top-20
.banner-graphic= image_tag 'illustrations/milestone_removing-page.svg'
.banner-body.prepend-left-10.append-right-10
- %h5.banner-title.prepend-top-0= _('This page will be removed in a future release.')
+ %h5.banner-title.gl-mt-0= _('This page will be removed in a future release.')
%p.milestone-banner-text= _('Use group milestones to manage issues from multiple projects in the same milestone.')
= button_tag _('Promote these project milestones into a group milestone.'), class: 'btn btn-link js-popover-link text-align-left milestone-banner-link'
.milestone-banner-buttons.prepend-top-20= link_to _('Learn more'), help_page_url('user/project/milestones/index', anchor: 'promoting-project-milestones-to-group-milestones'), class: 'btn btn-default', target: '_blank'
%template.js-milestone-deprecation-message-template
.milestone-popover-body
- %ol.milestone-popover-instructions-list.append-bottom-0
+ %ol.milestone-popover-instructions-list.gl-mb-0
%li= _('Click any <strong>project name</strong> in the project list below to navigate to the project milestone.').html_safe
%li= _('Click the <strong>Promote</strong> button in the top right corner to promote it to a group milestone.').html_safe
%hr.popover-hr
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
index 4de89d7c7a0..6dbc460d9bf 100644
--- a/app/views/shared/milestones/_form_dates.html.haml
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -1,13 +1,13 @@
.col-md-6
.form-group.row
.col-form-label.col-sm-2
- = f.label :start_date, "Start Date"
+ = f.label :start_date, _('Start Date')
.col-sm-10
- = f.text_field :start_date, class: "datepicker form-control", placeholder: "Select start date", autocomplete: 'off'
- %a.inline.float-right.prepend-top-5.js-clear-start-date{ href: "#" } Clear start date
+ = f.text_field :start_date, class: "datepicker form-control", placeholder: _('Select start date'), autocomplete: 'off'
+ %a.inline.float-right.prepend-top-5.js-clear-start-date{ href: "#" }= _('Clear start date')
.form-group.row
.col-form-label.col-sm-2
- = f.label :due_date, "Due Date"
+ = f.label :due_date, _('Due Date')
.col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", placeholder: "Select due date", autocomplete: 'off'
- %a.inline.float-right.prepend-top-5.js-clear-due-date{ href: "#" } Clear due date
+ = f.text_field :due_date, class: "datepicker form-control", placeholder: _('Select due date'), autocomplete: 'off'
+ %a.inline.float-right.prepend-top-5.js-clear-due-date{ href: "#" }= _('Clear due date')
diff --git a/app/views/shared/milestones/_header.html.haml b/app/views/shared/milestones/_header.html.haml
index 2da857261d1..99a46f1fb85 100644
--- a/app/views/shared/milestones/_header.html.haml
+++ b/app/views/shared/milestones/_header.html.haml
@@ -11,8 +11,7 @@
.milestone-buttons
- if can?(current_user, :admin_milestone, @group || @project)
- - unless milestone.legacy_group_milestone?
- = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn btn-grouped'
+ = link_to _('Edit'), edit_milestone_path(milestone), class: 'btn btn-grouped'
- if milestone.project_milestone? && milestone.project.group
%button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal',
@@ -31,8 +30,7 @@
- else
= link_to _('Reopen milestone'), update_milestone_path(milestone, { state_event: :activate }), method: :put, class: 'btn btn-grouped btn-reopen'
- - unless milestone.legacy_group_milestone?
- = render 'shared/milestones/delete_button'
+ = render 'shared/milestones/delete_button'
%button.btn.btn-default.btn-grouped.float-right.d-block.d-sm-none.js-sidebar-toggle{ type: 'button' }
= icon('angle-double-left')
diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml
index 9f61082d605..31505d2d9fb 100644
--- a/app/views/shared/milestones/_milestone.html.haml
+++ b/app/views/shared/milestones/_milestone.html.haml
@@ -6,39 +6,33 @@
.row
.col-sm-6
.append-bottom-5
- %strong= link_to truncate(milestone.title, length: 100), milestone_path
+ %strong= link_to truncate(milestone.title, length: 100), milestone_path(milestone)
- if @group
= " - #{milestone_type}"
- - if @project || milestone.is_a?(GlobalMilestone) || milestone.group_milestone?
- - if milestone.due_date || milestone.start_date
- .text-tertiary.append-bottom-5
- = milestone_date_range(milestone)
- - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
- - unless total_count.zero?
- .text-tertiary.append-bottom-5.milestone-release-links
- = icon('rocket')
- = n_('Release', 'Releases', total_count)
- - recent_releases.each do |release|
- = link_to release.name, project_releases_path(release.project, anchor: release.tag)
- - unless release == recent_releases.last
- &bull;
- - if total_count > recent_releases.count
+ - if milestone.due_date || milestone.start_date
+ .text-tertiary.append-bottom-5
+ = milestone_date_range(milestone)
+ - recent_releases, total_count, more_count = recent_releases_with_counts(milestone)
+ - unless total_count.zero?
+ .text-tertiary.append-bottom-5.milestone-release-links
+ = sprite_icon("rocket", size: 12)
+ = n_('Release', 'Releases', total_count)
+ - recent_releases.each do |release|
+ = link_to release.name, project_releases_path(release.project, anchor: release.tag)
+ - unless release == recent_releases.last
&bull;
- = link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(milestone.project)
- %div
- = render('shared/milestone_expired', milestone: milestone)
- - if milestone.group_milestone?
- .label-badge.label-badge-blue.d-inline-block
- = milestone.group.full_name
- - if milestone.legacy_group_milestone?
- .projects
- - link_to milestone_path(milestone.milestone) do
- %span.label-badge.label-badge-blue.d-inline-block.append-bottom-5
- = dashboard ? milestone.project.full_name : milestone.project.name
- - if milestone.project
- .label-badge.label-badge-gray.d-inline-block
- = milestone.project.full_name
+ - if total_count > recent_releases.count
+ &bull;
+ = link_to n_('%{count} more release', '%{count} more releases', more_count) % { count: more_count }, project_releases_path(milestone.project)
+ %div
+ = render('shared/milestone_expired', milestone: milestone)
+ - if milestone.group_milestone?
+ .label-badge.label-badge-blue.d-inline-block
+ = milestone.group.full_name
+ - if milestone.project_milestone?
+ .label-badge.label-badge-gray.d-inline-block
+ = milestone.project.full_name
.col-sm-4.milestone-progress
= milestone_progress_bar(milestone)
@@ -49,29 +43,25 @@
.float-lg-right.light #{milestone.percent_complete}% complete
.col-sm-2
.milestone-actions.d-flex.justify-content-sm-start.justify-content-md-end
- - if @project
- - if can_admin_project_milestones? and milestone.active?
- - if can_admin_group_milestones?
- %button.js-promote-project-milestone-button.btn.btn-blank.btn-sm.btn-grouped.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
- disabled: true,
- type: 'button',
- data: { url: promote_project_milestone_path(milestone.project, milestone),
- milestone_title: milestone.title,
- group_name: @project.group.name,
- target: '#promote-milestone-modal',
- container: 'body',
- toggle: 'modal' } }
- = sprite_icon('level-up', size: 14)
+ - if @project # if in milestones list on project level
+ - if can_admin_group_milestones?
+ %button.js-promote-project-milestone-button.btn.btn-blank.btn-sm.btn-grouped.has-tooltip{ title: s_('Milestones|Promote to Group Milestone'),
+ disabled: true,
+ type: 'button',
+ data: { url: promote_project_milestone_path(milestone.project, milestone),
+ milestone_title: milestone.title,
+ group_name: @project.group.name,
+ target: '#promote-milestone-modal',
+ container: 'body',
+ toggle: 'modal' } }
+ = sprite_icon('level-up', size: 14)
+
+ - if can?(current_user, :admin_milestone, milestone)
+ - if milestone.closed?
+ = link_to s_('Milestones|Reopen Milestone'), milestone_path(milestone, milestone: { state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
+ - else
+ = link_to s_('Milestones|Close Milestone'), milestone_path(milestone, milestone: { state_event: :close }), method: :put, class: "btn btn-sm btn-grouped btn-close"
- = link_to s_('Milestones|Close Milestone'), project_milestone_path(@project, milestone, milestone: {state_event: :close }), method: :put, remote: true, class: "btn btn-sm btn-close btn-grouped"
- - unless milestone.active?
- = link_to s_('Milestones|Reopen Milestone'), project_milestone_path(@project, milestone, milestone: {state_event: :activate }), method: :put, class: "btn btn-grouped btn-reopen"
- - if @group
- - if can?(current_user, :admin_milestone, @group)
- - if milestone.closed?
- = link_to s_('Milestones|Reopen Milestone'), group_milestone_route(milestone, {state_event: :activate }), method: :put, class: "btn btn-sm btn-grouped btn-reopen"
- - else
- = link_to s_('Milestones|Close Milestone'), group_milestone_route(milestone, {state_event: :close }), method: :put, class: "btn btn-sm btn-grouped btn-close"
- if dashboard
.label-badge.label-badge-gray
= milestone_type
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index ba1629bd99a..160f6487439 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -4,12 +4,12 @@
%aside.right-sidebar.js-right-sidebar{ data: { "offset-top" => affix_offset, "spy" => "affix", "always-show-toggle" => true }, class: sidebar_gutter_collapsed_class, 'aria-live' => 'polite' }
.issuable-sidebar.milestone-sidebar
.block.milestone-progress.issuable-sidebar-header
- %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => "Toggle sidebar", title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
+ %a.gutter-toggle.float-right.js-sidebar-toggle.has-tooltip{ role: "button", href: "#", "aria-label" => s_('MilestoneSidebar|Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }
= sidebar_gutter_toggle_icon
.title.hide-collapsed
%strong.bold== #{milestone.percent_complete}%
%span.hide-collapsed
- complete
+ = s_('MilestoneSidebar|complete')
.value.hide-collapsed
= milestone_progress_bar(milestone)
@@ -20,15 +20,15 @@
.block.start_date.hide-collapsed
.title
- Start date
+ = s_('MilestoneSidebar|Start date')
- if @project && can?(current_user, :admin_milestone, @project)
- = link_to 'Edit', edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
+ = link_to s_('MilestoneSidebar|Edit'), edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
.value
%span.value-content
- if milestone.start_date
%span.bold= milestone.start_date.to_s(:medium)
- else
- %span.no-value No start date
+ %span.no-value= s_('MilestoneSidebar|No start date')
.block.due_date
.sidebar-collapsed-icon
@@ -45,26 +45,26 @@
.due_date.has-tooltip{ title: milestone_time_for(milestone.due_date, :end), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= milestone.due_date.strftime('%b %-d %Y')
- elsif milestone.start_date
- From
+ = s_('MilestoneSidebar|From')
.milestone-date.has-tooltip{ title: milestone_time_for(milestone.start_date, :start), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= milestone.start_date.strftime('%b %-d %Y')
- elsif milestone.due_date
- Until
+ = s_('MilestoneSidebar|Until')
.milestone-date.has-tooltip{ title: milestone_time_for(milestone.due_date, :end), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
= milestone.due_date.strftime('%b %-d %Y')
- else
.has-tooltip{ title: milestone_time_for(milestone.start_date, :start), data: { container: 'body', html: 'true', placement: 'left', boundary: 'viewport' } }
- None
+ = s_('MilestoneSidebar|None')
.title.hide-collapsed
- Due date
+ = s_('MilestoneSidebar|Due date')
- if @project && can?(current_user, :admin_milestone, @project)
- = link_to 'Edit', edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
+ = link_to s_('MilestoneSidebar|Edit'), edit_project_milestone_path(@project, @milestone), class: 'js-sidebar-dropdown-toggle edit-link float-right'
.value.hide-collapsed
%span.value-content
- if milestone.due_date
%span.bold= milestone.due_date.to_s(:medium)
- else
- %span.no-value No due date
+ %span.no-value= s_('MilestoneSidebar|No due date')
- remaining_days = remaining_days_in_words(milestone.due_date, milestone.start_date)
- if remaining_days.present?
= surround '(', ')' do
@@ -77,19 +77,19 @@
= custom_icon('issues')
%span= milestone.issues_visible_to_user(current_user).count
.title.hide-collapsed
- Issues
+ = s_('MilestoneSidebar|Issues')
%span.badge.badge-pill= milestone.issues_visible_to_user(current_user).count
- if show_new_issue_link?(project)
- = link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "float-right", title: "New Issue" do
- New issue
+ = link_to new_project_issue_path(project, issue: { milestone_id: milestone.id }), class: "float-right", title: s_('MilestoneSidebar|New Issue') do
+ = s_('MilestoneSidebar|New issue')
.value.hide-collapsed.bold
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :issues) do
- Open:
+ = s_('MilestoneSidebar|Open:')
= milestone.issues_visible_to_user(current_user).opened.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :issues, state: 'closed') do
- Closed:
+ = s_('MilestoneSidebar|Closed:')
= milestone.issues_visible_to_user(current_user).closed.count
.block
@@ -108,31 +108,31 @@
= custom_icon('mr_bold')
%span= milestone.merge_requests.count
.title.hide-collapsed
- Merge requests
+ = s_('MilestoneSidebar|Merge requests')
%span.badge.badge-pill= milestone.merge_requests.count
.value.hide-collapsed.bold
- if !project || can?(current_user, :read_merge_request, project)
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests) do
- Open:
+ = s_('MilestoneSidebar|Open:')
= milestone.merge_requests.opened.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'closed') do
- Closed:
+ = s_('MilestoneSidebar|Closed:')
= milestone.merge_requests.closed.count
%span.milestone-stat
= link_to milestones_browse_issuables_path(milestone, type: :merge_requests, state: 'merged') do
- Merged:
+ = s_('MilestoneSidebar|Merged:')
= milestone.merge_requests.merged.count
- else
%span.milestone-stat
- Open:
+ = s_('MilestoneSidebar|Open:')
= milestone.merge_requests.opened.count
%span.milestone-stat
- Closed:
+ = s_('MilestoneSidebar|Closed:')
= milestone.merge_requests.closed.count
%span.milestone-stat
- Merged:
+ = s_('MilestoneSidebar|Merged:')
= milestone.merge_requests.merged.count
- if project
@@ -140,12 +140,12 @@
.block.releases
.sidebar-collapsed-icon.has-tooltip{ title: milestone_releases_tooltip_text(milestone), data: { container: 'body', placement: 'left', boundary: 'viewport' } }
%strong
- = icon('rocket')
+ = sprite_icon("rocket", size: 16)
%span= total_count
.title.hide-collapsed= n_('Release', 'Releases', total_count)
.hide-collapsed
- if total_count.zero?
- .no-value= _('None')
+ .no-value= s_('MilestoneSidebar|None')
- else
.font-weight-bold
- recent_releases.each do |release|
@@ -160,10 +160,10 @@
- if milestone_ref.present?
.block.reference
.sidebar-collapsed-icon.dont-change-state
- = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport')
.cross-project-reference.hide-collapsed
%span
- Reference:
+ = s_('MilestoneSidebar|Reference:')
%cite{ title: milestone_ref }
= milestone_ref
- = clipboard_button(text: milestone_ref, title: _("Copy reference"), placement: "left", boundary: 'viewport')
+ = clipboard_button(text: milestone_ref, title: s_('MilestoneSidebar|Copy reference'), placement: "left", boundary: 'viewport')
diff --git a/app/views/shared/milestones/_top.html.haml b/app/views/shared/milestones/_top.html.haml
index 5f53e6316af..49df00940b7 100644
--- a/app/views/shared/milestones/_top.html.haml
+++ b/app/views/shared/milestones/_top.html.haml
@@ -1,11 +1,9 @@
- page_title milestone.title
-- @breadcrumb_link = dashboard_milestone_path(milestone.safe_title, title: milestone.title)
+- @breadcrumb_link = milestone_path(milestone)
- group = local_assigns[:group]
-- is_dynamic_milestone = milestone.legacy_group_milestone? || milestone.dashboard_milestone?
= render 'shared/milestones/header', milestone: milestone
-= render 'shared/milestones/deprecation_message' if is_dynamic_milestone
= render 'shared/milestones/description', milestone: milestone
- if milestone.complete? && milestone.active?
@@ -15,26 +13,3 @@
= group ? _('You may close the milestone now.') : _('Navigate to the project to close the milestone.')
= render_if_exists 'shared/milestones/burndown', milestone: milestone, project: @project
-
-- if is_dynamic_milestone
- .table-holder
- %table.table
- %thead
- %tr
- %th= _('Project')
- %th= _('Open issues')
- %th= _('State')
- %th= _('Due date')
- %tr
- %td
- - project_name = group ? milestone.project.name : milestone.project.full_name
- = link_to project_name, milestone_path(milestone.milestone)
- %td
- = milestone.milestone.issues_visible_to_user(current_user).opened.count
- %td
- - if milestone.closed?
- = _('Closed')
- - else
- = _('Open')
- %td
- = milestone.expires_at
diff --git a/app/views/shared/notes/_edit_form.html.haml b/app/views/shared/notes/_edit_form.html.haml
index 6fe511c2999..244c191af12 100644
--- a/app/views/shared/notes/_edit_form.html.haml
+++ b/app/views/shared/notes/_edit_form.html.haml
@@ -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
diff --git a/app/views/shared/notes/_form.html.haml b/app/views/shared/notes/_form.html.haml
index 327745e4f4d..40e36728642 100644
--- a/app/views/shared/notes/_form.html.haml
+++ b/app/views/shared/notes/_form.html.haml
@@ -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…"),
diff --git a/app/views/shared/notifications/_custom_notifications.html.haml b/app/views/shared/notifications/_custom_notifications.html.haml
index 0142deb47f8..9bd08c2296f 100644
--- a/app/views/shared/notifications/_custom_notifications.html.haml
+++ b/app/views/shared/notifications/_custom_notifications.html.haml
@@ -16,7 +16,7 @@
= hidden_field_tag("hide_label", true) if hide_label
.row
.col-lg-4
- %h4.prepend-top-0= _('Notification events')
+ %h4.gl-mt-0= _('Notification events')
%p
- notification_link = link_to _('notification emails'), help_page_path('user/profile/notifications'), target: '_blank'
- paragraph = _('Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}.') % { notification_link: notification_link.html_safe }
@@ -26,7 +26,7 @@
- next if notification_event_disabled?(event)
- field_id = "#{notifications_menu_identifier("modal", notification_setting)}_notification_setting[#{event}]"
.form-group
- .form-check{ class: ("prepend-top-0" if index == 0) }
+ .form-check{ class: ("gl-mt-0" if index == 0) }
= check_box("notification_setting", event, id: field_id, class: "js-custom-notification-event form-check-input", checked: notification_setting.public_send(event))
%label.form-check-label{ for: field_id }
%strong
diff --git a/app/views/shared/notifications/_new_button.html.haml b/app/views/shared/notifications/_new_button.html.haml
index 566f08b94ce..796ff095eea 100644
--- a/app/views/shared/notifications/_new_button.html.haml
+++ b/app/views/shared/notifications/_new_button.html.haml
@@ -8,7 +8,7 @@
- else
- button_title = _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }
- .js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.append-right-8.dropdown.inline
+ .js-notification-dropdown.notification-dropdown.home-panel-action-button.prepend-top-default.gl-mr-3.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form no-label" } do |f|
= hidden_setting_source_input(notification_setting)
= hidden_field_tag "hide_label", true
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 3d61943193f..fc3f1a8d1c1 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -30,9 +30,9 @@
.project-details.d-sm-flex.flex-sm-fill.align-items-center{ data: { qa_selector: 'project', qa_project_name: project.name } }
.flex-wrapper
.d-flex.align-items-center.flex-wrap.project-title
- %h2.d-flex.prepend-top-8
+ %h2.d-flex.gl-mt-3
= link_to project_path(project), class: 'text-plain' do
- %span.project-full-name.append-right-8><
+ %span.project-full-name.gl-mr-3><
%span.namespace-name
- if project.namespace && !skip_namespace
= project.namespace.human_name
@@ -40,22 +40,22 @@
%span.project-name<
= project.name
- %span.metadata-info.visibility-icon.append-right-10.prepend-top-8.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) }
+ %span.metadata-info.visibility-icon.append-right-10.gl-mt-3.text-secondary.has-tooltip{ data: { container: 'body', placement: 'top' }, title: visibility_icon_description(project) }
= visibility_level_icon(project.visibility_level, fw: true)
- if explore_projects_tab? && license_name
- %span.metadata-info.d-inline-flex.align-items-center.append-right-10.prepend-top-8
+ %span.metadata-info.d-inline-flex.align-items-center.append-right-10.gl-mt-3
= sprite_icon('scale', size: 14, css_class: 'append-right-4')
= license_name
- if !explore_projects_tab? && access&.nonzero?
-# haml-lint:disable UnnecessaryStringOutput
= ' ' # prevent haml from eating the space between elements
- .metadata-info.prepend-top-8
+ .metadata-info.gl-mt-3
%span.user-access-role.d-block= Gitlab::Access.human_access(access)
- if !explore_projects_tab?
- .metadata-info.prepend-top-8
+ .metadata-info.gl-mt-3
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: project
- if show_last_commit_as_description
diff --git a/app/views/shared/snippets/_form.html.haml b/app/views/shared/snippets/_form.html.haml
index 4695692fb53..7f307f33b51 100644
--- a/app/views/shared/snippets/_form.html.haml
+++ b/app/views/shared/snippets/_form.html.haml
@@ -9,7 +9,7 @@
.form-group
= f.label :title, class: 'label-bold'
- = f.text_field :title, class: 'form-control qa-snippet-title', required: true, autofocus: true
+ = f.text_field :title, class: 'form-control', required: true, autofocus: true, data: { qa_selector: 'snippet_title_field' }
.form-group.js-description-input
- description_placeholder = s_('Snippets|Optionally add a description about what your snippet does or how to use it...')
@@ -19,15 +19,15 @@
.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
= f.label :file_name, s_('Snippets|File')
.file-holder.snippet
.js-file-title.file-title-flex-parent
- = f.text_field :file_name, placeholder: s_("Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"), class: 'form-control js-snippet-file-name qa-snippet-file-name'
+ = f.text_field :file_name, placeholder: s_("Snippets|Give your file a name to add code highlighting, e.g. example.rb for Ruby"), class: 'form-control js-snippet-file-name', data: { qa_selector: 'file_name_field' }
.file-content.code
%pre#editor{ data: { 'editor-loading': true } }= @snippet.content
= f.hidden_field :content, class: 'snippet-file-content'
diff --git a/app/views/shared/snippets/_header.html.haml b/app/views/shared/snippets/_header.html.haml
index e663d57ae6a..7f213c50de2 100644
--- a/app/views/shared/snippets/_header.html.haml
+++ b/app/views/shared/snippets/_header.html.haml
@@ -1,6 +1,6 @@
.detail-page-header
.detail-page-header-body
- .snippet-box.qa-snippet-box.has-tooltip.inline.append-right-5{ title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: "body" } }
+ .snippet-box.has-tooltip.inline.append-right-5{ title: snippet_visibility_level_description(@snippet.visibility_level, @snippet), data: { container: "body" } }
%span.sr-only
= visibility_level_label(@snippet.visibility_level)
= visibility_level_icon(@snippet.visibility_level, fw: false)
@@ -17,11 +17,11 @@
= render "snippets/actions"
.snippet-header.limited-header-width
- %h2.snippet-title.prepend-top-0.mb-3{ data: { qa_selector: 'snippet_title' } }
+ %h2.snippet-title.gl-mt-0.mb-3
= markdown_field(@snippet, :title)
- if @snippet.description.present?
- .description{ data: { qa_selector: 'snippet_description_field' } }
+ .description
.md
= markdown_field(@snippet, :description)
%textarea.hidden.js-task-list-field
diff --git a/app/views/shared/tokens/_scopes_list.html.haml b/app/views/shared/tokens/_scopes_list.html.haml
index 913392be510..558cf67f201 100644
--- a/app/views/shared/tokens/_scopes_list.html.haml
+++ b/app/views/shared/tokens/_scopes_list.html.haml
@@ -6,7 +6,7 @@
%td
= _('Scopes')
%td
- %ul.scopes-list.append-bottom-0
+ %ul.scopes-list.gl-mb-0
- token.scopes.each do |scope|
%li
%span.bold= scope
diff --git a/app/views/shared/web_hooks/_hook.html.haml b/app/views/shared/web_hooks/_hook.html.haml
index 34a62340966..470e2f6b904 100644
--- a/app/views/shared/web_hooks/_hook.html.haml
+++ b/app/views/shared/web_hooks/_hook.html.haml
@@ -11,6 +11,6 @@
= hook.enable_ssl_verification ? _('enabled') : _('disabled')
.col-md-4.col-lg-5.text-right-md.prepend-top-5
- %span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm append-right-8'
- %span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn btn-sm append-right-8'
+ %span>= render 'shared/web_hooks/test_button', hook: hook, button_class: 'btn-sm gl-mr-3'
+ %span>= link_to _('Edit'), edit_hook_path(hook), class: 'btn btn-sm gl-mr-3'
= link_to _('Delete'), destroy_hook_path(hook), data: { confirm: _('Are you sure?') }, method: :delete, class: 'btn btn-sm'
diff --git a/app/views/shared/web_hooks/_title_and_docs.html.haml b/app/views/shared/web_hooks/_title_and_docs.html.haml
index 359f5f34f5b..f00f3473efa 100644
--- a/app/views/shared/web_hooks/_title_and_docs.html.haml
+++ b/app/views/shared/web_hooks/_title_and_docs.html.haml
@@ -1,5 +1,10 @@
-%h4.prepend-top-0
+- webhooks_link_start = '<a href="%{url}">'.html_safe % { url: help_page_path(hook.help_path) }
+
+%h4.gl-mt-0
= page_title
-%p
- - link = link_to(hook.pluralized_name, help_page_path(hook.help_path))
- = _('%{link} can be used for binding events when something is happening within the project.').html_safe % { link: link }
+
+- if @project
+ - integrations_link_start = '<a href="%{url}">'.html_safe % { url: scoped_integrations_path }
+ %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project. We recommend using an %{integrations_link_start}integration%{link_end} in preference to a webhook.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, integrations_link_start: integrations_link_start, link_end: '</a>'.html_safe }
+- else
+ %p= _("%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project.").html_safe % { webhooks_link_start: webhooks_link_start, webhook_type: hook.pluralized_name, link_end: '</a>'.html_safe }
diff --git a/app/views/shared/wikis/_form.html.haml b/app/views/shared/wikis/_form.html.haml
new file mode 100644
index 00000000000..8ea06d4d6c3
--- /dev/null
+++ b/app/views/shared/wikis/_form.html.haml
@@ -0,0 +1,79 @@
+- form_classes = %w[wiki-form common-note-form prepend-top-default js-quick-submit]
+
+- 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)
+
+ - if @page.persisted?
+ = f.hidden_field :last_commit_sha, value: @page.last_commit_sha
+
+ .form-group.row
+ .col-sm-12= f.label :title, class: 'control-label-full-width'
+ .col-sm-12
+ = f.text_field :title, class: 'form-control qa-wiki-title-textbox', value: @page.title, required: true, autofocus: !@page.persisted?, placeholder: s_('Wiki|Page title')
+ %span.d-inline-block.mw-100.prepend-top-5
+ = icon('lightbulb-o')
+ - if @page.persisted?
+ = s_("WikiEditPageTip|Tip: You can move this page by adding the path to the beginning of the title.")
+ = link_to icon('question-circle'), help_page_path('user/project/wiki/index', anchor: 'moving-a-wiki-page'),
+ target: '_blank', rel: 'noopener noreferrer'
+ - else
+ = s_("WikiNewPageTip|Tip: You can specify the full path for the new file. We will automatically create any missing directories.")
+ = succeed '.' do
+ = link_to _('Learn more'), help_page_path('user/project/wiki/index', anchor: 'creating-a-new-wiki-page'),
+ target: '_blank', rel: 'noopener noreferrer'
+ .form-group.row
+ .col-sm-12= f.label :format, class: 'control-label-full-width'
+ .col-sm-12
+ .select-wrapper
+ = 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: '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
+ .error-alert
+
+ .form-text.text-muted
+ = succeed '.' do
+ - case @page.format.to_s
+ - when 'rdoc'
+ - link_example = '{Link title}[link:page-slug]'
+ - when 'asciidoc'
+ - link_example = 'link:page-slug[Link title]'
+ - when 'org'
+ - link_example = '[[page-slug]]'
+ - else
+ - link_example = '[Link Title](page-slug)'
+ = (s_('WikiMarkdownTip|To link to a (new) page, simply type <code class="js-markup-link-example">%{link_example}</code>') % { link_example: link_example }).html_safe
+ = succeed '.' do
+ - markdown_link = link_to s_("WikiMarkdownDocs|documentation"), help_page_path('user/markdown', anchor: 'wiki-specific-markdown')
+ = (s_("WikiMarkdownDocs|More examples are in the %{docs_link}") % { docs_link: markdown_link }).html_safe
+
+ .form-group.row
+ .col-sm-12= f.label :commit_message, class: 'control-label-full-width'
+ .col-sm-12= f.text_field :message, class: 'form-control qa-wiki-message-textbox', rows: 18, value: nil
+
+ .form-actions
+ - if @page && @page.persisted?
+ = f.submit _("Save changes"), class: 'btn-success btn qa-save-changes-button'
+ .float-right
+ = 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"), wiki_path(@wiki), class: 'btn btn-cancel'
diff --git a/app/views/shared/wikis/_main_links.html.haml b/app/views/shared/wikis/_main_links.html.haml
new file mode 100644
index 00000000000..e173ef72d11
--- /dev/null
+++ b/app/views/shared/wikis/_main_links.html.haml
@@ -0,0 +1,9 @@
+- 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")
diff --git a/app/views/shared/wikis/_pages_wiki_page.html.haml b/app/views/shared/wikis/_pages_wiki_page.html.haml
new file mode 100644
index 00000000000..534884eb848
--- /dev/null
+++ b/app/views/shared/wikis/_pages_wiki_page.html.haml
@@ -0,0 +1,6 @@
+%li
+ = link_to wiki_page.title, wiki_page_path(@wiki, wiki_page)
+ %small (#{wiki_page.format})
+ .float-right
+ - if wiki_page.last_version
+ %small= (s_("Last edited %{date}") % { date: time_ago_with_tooltip(wiki_page.last_version.authored_date) }).html_safe
diff --git a/app/views/shared/wikis/_sidebar.html.haml b/app/views/shared/wikis/_sidebar.html.haml
new file mode 100644
index 00000000000..8cfb95cdcf5
--- /dev/null
+++ b/app/views/shared/wikis/_sidebar.html.haml
@@ -0,0 +1,22 @@
+%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" } }
+ .sidebar-container
+ .block.wiki-sidebar-header.append-bottom-default.w-100
+ %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 = 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")
+
+ .blocks-container
+ .block.block-first.w-100
+ - if @sidebar_page
+ = render_wiki_content(@sidebar_page)
+ - else
+ %ul.wiki-pages
+ = render @sidebar_wiki_entries, context: 'sidebar'
+ .block.w-100
+ - if @sidebar_limited
+ = link_to wiki_path(@wiki, action: :pages), class: 'btn btn-block' do
+ = s_("Wiki|View All Pages")
diff --git a/app/views/shared/wikis/_sidebar_wiki_page.html.haml b/app/views/shared/wikis/_sidebar_wiki_page.html.haml
new file mode 100644
index 00000000000..2573471f9f9
--- /dev/null
+++ b/app/views/shared/wikis/_sidebar_wiki_page.html.haml
@@ -0,0 +1,3 @@
+%li{ class: active_when(params[:id] == wiki_page.slug) }
+ = link_to wiki_page_path(@wiki, wiki_page) do
+ = wiki_page.human_title
diff --git a/app/views/shared/wikis/_wiki_directory.html.haml b/app/views/shared/wikis/_wiki_directory.html.haml
new file mode 100644
index 00000000000..0e5f32ed859
--- /dev/null
+++ b/app/views/shared/wikis/_wiki_directory.html.haml
@@ -0,0 +1,4 @@
+%li
+ = wiki_directory.slug
+ %ul
+ = render wiki_directory.pages, context: context
diff --git a/app/views/shared/wikis/_wiki_page.html.haml b/app/views/shared/wikis/_wiki_page.html.haml
new file mode 100644
index 00000000000..b27feac86cc
--- /dev/null
+++ b/app/views/shared/wikis/_wiki_page.html.haml
@@ -0,0 +1 @@
+= render "shared/wikis/#{context}_wiki_page", wiki_page: wiki_page
diff --git a/app/views/shared/wikis/edit.html.haml b/app/views/shared/wikis/edit.html.haml
new file mode 100644
index 00000000000..5bda8d85627
--- /dev/null
+++ b/app/views/shared/wikis/edit.html.haml
@@ -0,0 +1,31 @@
+- @content_class = "limit-container-width" unless fluid_layout
+- 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")
+
+= wiki_page_errors(@error)
+
+.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" }
+ = icon('angle-double-left')
+
+ .nav-text
+ %h2.wiki-page-title
+ - if @page.persisted?
+ = link_to @page.human_title, wiki_page_path(@wiki, @page)
+ %span.light
+ &middot;
+ = s_("Wiki|Edit Page")
+ - else
+ = s_("Wiki|Create New Page")
+
+ .nav-controls.pb-md-3.pb-lg-0
+ - if @page.persisted?
+ = link_to wiki_page_path(@wiki, @page, action: :history), class: "btn" do
+ = s_("Wiki|Page history")
+ - 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 'shared/wikis/form', uploads_path: wiki_attachment_upload_url
+
+= render 'shared/wikis/sidebar'
diff --git a/app/views/shared/wikis/empty.html.haml b/app/views/shared/wikis/empty.html.haml
new file mode 100644
index 00000000000..62fa6e1907b
--- /dev/null
+++ b/app/views/shared/wikis/empty.html.haml
@@ -0,0 +1,4 @@
+- page_title _("Wiki")
+- @right_sidebar = false
+
+= render 'shared/empty_states/wikis'
diff --git a/app/views/shared/wikis/history.html.haml b/app/views/shared/wikis/history.html.haml
new file mode 100644
index 00000000000..ec07082bd02
--- /dev/null
+++ b/app/views/shared/wikis/history.html.haml
@@ -0,0 +1,41 @@
+- page_title _("History"), @page.human_title, _("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" }
+ = icon('angle-double-left')
+
+ .nav-text
+ %h2.wiki-page-title
+ = link_to @page.human_title, wiki_page_path(@wiki, @page)
+ %span.light
+ &middot;
+ = _("History")
+
+.table-holder
+ %table.table
+ %thead
+ %tr
+ %th= s_("Wiki|Page version")
+ %th= _("Author")
+ %th= _("Commit Message")
+ %th= _("Last updated")
+ %th= _("Format")
+ %tbody
+ - @page_versions.each_with_index do |version, index|
+ - commit = version
+ %tr
+ %td
+ = link_to wiki_page_path(@wiki, @page, version_id: index == 0 ? nil : commit.id) do
+ = truncate_sha(commit.id)
+ %td
+ = commit.author_name
+ %td
+ = commit.message
+ %td
+ #{time_ago_with_tooltip(version.authored_date)}
+ %td
+ %strong
+ = version.format
+= paginate @page_versions, theme: 'gitlab'
+
+= render 'shared/wikis/sidebar'
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
new file mode 100644
index 00000000000..987c696cdfe
--- /dev/null
+++ b/app/views/shared/wikis/pages.html.haml
@@ -0,0 +1,32 @@
+- 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])
+
+.wiki-page-header.top-area.flex-column.flex-lg-row
+
+ .nav-text.flex-fill
+ %h2.wiki-page-title
+ = s_("Wiki|Wiki Pages")
+
+ .nav-controls.pb-md-3.pb-lg-0
+ = link_to wiki_path(@wiki, action: :git_access), class: 'btn' do
+ = icon('cloud-download')
+ = _("Clone repository")
+
+ .dropdown.inline.wiki-sort-dropdown
+ .btn-group{ role: 'group' }
+ .btn-group{ role: 'group' }
+ %button.dropdown-toggle{ type: 'button', data: { toggle: 'dropdown', display: 'static' }, class: 'btn btn-default' }
+ = sort_title
+ = icon('chevron-down')
+ %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable.dropdown-menu-sort
+ %li
+ = 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'
+
+= paginate @wiki_pages, theme: 'gitlab'
diff --git a/app/views/shared/wikis/show.html.haml b/app/views/shared/wikis/show.html.haml
new file mode 100644
index 00000000000..a4f3996e5de
--- /dev/null
+++ b/app/views/shared/wikis/show.html.haml
@@ -0,0 +1,32 @@
+- @content_class = "limit-container-width" unless fluid_layout
+- breadcrumb_title @page.human_title
+- wiki_breadcrumb_dropdown_links(@page.slug)
+- page_title @page.human_title, _("Wiki")
+- 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" }
+ = icon('angle-double-left')
+
+ .nav-text.flex-fill
+ %h2.wiki-page-title{ data: { qa_selector: 'wiki_page_title' } }= @page.human_title
+ %span.wiki-last-edit-by
+ - if @page.last_version
+ = (_("Last edited by %{name}") % { name: "<strong>#{@page.last_version.author_name}</strong>" }).html_safe
+ #{time_ago_with_tooltip(@page.last_version.authored_date)}
+
+ .nav-controls.pb-md-3.pb-lg-0
+ = 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"), 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 'shared/wikis/sidebar'