diff options
Diffstat (limited to 'app/views/shared')
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 - • - - 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 • - = 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 + • + = 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 + · + = 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 + · + = _("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' |