Commit 97df9e86 authored by Dennis Tang's avatar Dennis Tang Committed by Mike Greiling

Port "Further improvements to Project overview UI" to EE

parent b6052c49
......@@ -12,6 +12,10 @@ export default function notificationsDropdown() {
const form = $(this).parents('.notification-form:first');
form.find('.js-notification-loading').toggleClass('fa-bell fa-spin fa-spinner');
if (form.hasClass('no-label')) {
form.find('.js-notification-loading').toggleClass('hidden');
form.find('.js-notifications-icon').toggleClass('hidden');
}
form.find('#notification_setting_level').val(notificationLevel);
form.submit();
});
......
......@@ -13,6 +13,9 @@ export default class Project {
const $cloneOptions = $('ul.clone-options-dropdown');
const $projectCloneField = $('#project_clone');
const $cloneBtnLabel = $('.js-git-clone-holder .js-clone-dropdown-label');
const mobileCloneField = document.querySelector(
'.js-mobile-git-clone .js-clone-dropdown-label',
);
const selectedCloneOption = $cloneBtnLabel.text().trim();
if (selectedCloneOption.length > 0) {
......@@ -41,7 +44,11 @@ export default class Project {
cloneUrlPrimary: $this.data('primaryUrl') || '',
});
$projectCloneField.val(url);
if (mobileCloneField) {
mobileCloneField.dataset.clipboardText = url;
} else {
$projectCloneField.val(url);
}
$('.js-git-empty .js-clone').text(url);
});
// Ref switcher
......
......@@ -21,6 +21,7 @@
&.s46 { @include avatar-size(46px, 15px); }
&.s48 { @include avatar-size(48px, 10px); }
&.s60 { @include avatar-size(60px, 12px); }
&.s64 { @include avatar-size(64px, 14px); }
&.s70 { @include avatar-size(70px, 14px); }
&.s90 { @include avatar-size(90px, 15px); }
&.s100 { @include avatar-size(100px, 15px); }
......@@ -84,6 +85,7 @@
&.s40 { font-size: 16px; line-height: 38px; }
&.s48 { font-size: 20px; line-height: 46px; }
&.s60 { font-size: 32px; line-height: 58px; }
&.s64 { font-size: 32px; line-height: 64px; }
&.s70 { font-size: 34px; line-height: 70px; }
&.s90 { font-size: 36px; line-height: 88px; }
&.s100 { font-size: 36px; line-height: 98px; }
......
......@@ -142,8 +142,14 @@
&.btn-sm {
padding: 4px 10px;
font-size: 13px;
line-height: 18px;
font-size: $gl-btn-small-font-size;
line-height: $gl-btn-small-line-height;
}
&.btn-xs {
padding: 2px $gl-btn-padding;
font-size: $gl-btn-small-font-size;
line-height: $gl-btn-small-line-height;
}
&.btn-success,
......
......@@ -39,15 +39,6 @@
.git-clone-holder {
display: none;
}
// Display Star and Fork buttons without counters on mobile.
.project-repo-buttons {
display: block;
.count-buttons .count-badge {
margin-top: $gl-padding-8;
}
}
}
.group-buttons {
......
......@@ -198,6 +198,7 @@ $well-light-text-color: #5b6169;
$gl-font-size: 14px;
$gl-font-size-xs: 11px;
$gl-font-size-small: 12px;
$gl-font-size-large: 16px;
$gl-font-weight-normal: 400;
$gl-font-weight-bold: 600;
$gl-text-color: #2e2e2e;
......@@ -271,7 +272,8 @@ $performance-bar-height: 35px;
$flash-height: 52px;
$context-header-height: 60px;
$breadcrumb-min-height: 48px;
$project-title-row-height: 24px;
$project-title-row-height: 64px;
$project-avatar-mobile-size: 24px;
$gl-line-height: 16px;
$gl-line-height-24: 24px;
......@@ -373,6 +375,8 @@ $gl-btn-padding: 10px;
$gl-btn-line-height: 16px;
$gl-btn-vert-padding: 8px;
$gl-btn-horz-padding: 12px;
$gl-btn-small-font-size: 13px;
$gl-btn-small-line-height: 13px;
/*
* Badges
......
......@@ -144,7 +144,6 @@
.group-home-panel {
padding-top: 24px;
padding-bottom: 24px;
border-bottom: 1px solid $border-color;
.group-avatar {
float: none;
......@@ -155,7 +154,6 @@
}
}
.project-title,
.group-title {
margin-top: 10px;
margin-bottom: 10px;
......@@ -195,25 +193,69 @@
}
.project-home-panel {
padding-top: $gl-padding-8;
padding-bottom: $gl-padding-24;
.project-title-row {
margin-right: $gl-padding-8;
}
padding-top: $gl-padding;
padding-bottom: $gl-padding;
.project-avatar {
width: $project-title-row-height;
height: $project-title-row-height;
flex-shrink: 0;
flex-basis: $project-title-row-height;
margin: 0 $gl-padding-8 0 0;
margin: 0 $gl-padding 0 0;
}
.project-title {
margin-top: 8px;
margin-bottom: 5px;
font-size: 20px;
line-height: $project-title-row-height;
line-height: $gl-line-height-24;
font-weight: bold;
.icon {
font-size: $gl-font-size-large;
}
.project-visibility {
color: $gl-text-color-secondary;
}
.project-tag-list {
font-size: $gl-font-size;
font-weight: $gl-font-weight-normal;
.icon {
position: relative;
top: 3px;
margin-right: $gl-padding-4;
}
}
}
.project-title-row {
@include media-breakpoint-down(sm) {
.project-avatar {
width: $project-avatar-mobile-size;
height: $project-avatar-mobile-size;
flex-basis: $project-avatar-mobile-size;
.avatar {
font-size: 20px;
line-height: 46px;
}
}
.project-title {
margin-top: 4px;
margin-bottom: 2px;
font-size: $gl-font-size;
line-height: $gl-font-size-large;
}
.project-tag-list,
.project-metadata {
font-size: $gl-font-size-small;
}
}
}
.project-metadata {
......@@ -222,16 +264,6 @@
line-height: $gl-btn-line-height;
color: $gl-text-color-secondary;
.icon {
margin-right: $gl-padding-4;
font-size: 16px;
}
.project-visibility,
.project-license,
.project-tag-list {
margin-right: $gl-padding-8;
}
.project-license {
.btn {
......@@ -240,12 +272,22 @@
}
}
.project-tag-list,
.project-license {
.icon {
position: relative;
top: 2px;
}
.access-request-link,
.project-tag-list {
padding-left: $gl-padding-8;
border-left: 1px solid $gl-text-color-secondary;
}
}
.project-description {
@include media-breakpoint-up(md) {
font-size: $gl-font-size-large;
}
}
.notifications-btn {
.fa-bell {
margin-right: 0;
}
}
}
......@@ -298,14 +340,6 @@
vertical-align: top;
margin-top: $gl-padding;
.count-badge {
height: $input-height;
.icon {
top: -1px;
}
}
.count-badge-count,
.count-badge-button {
border: 1px solid $border-color;
......@@ -319,29 +353,25 @@
.count-badge-count {
padding: 0 12px;
border-right: 0;
border-radius: $border-radius-base 0 0 $border-radius-base;
background: $gray-light;
border-radius: 0 $border-radius-base $border-radius-base 0;
}
.count-badge-button {
border-radius: 0 $border-radius-base $border-radius-base 0;
border-right: 0;
border-radius: $border-radius-base 0 0 $border-radius-base;
}
}
.project-clone-holder {
display: inline-block;
margin: $gl-padding $gl-padding-8 0 0;
margin: $gl-padding 0 0;
input {
height: $input-height;
}
}
.clone-dropdown-btn {
background-color: $white-light;
}
.clone-options-dropdown {
min-width: 240px;
......@@ -355,6 +385,31 @@
}
}
.project-repo-buttons {
.icon {
top: 0;
}
.count-badge,
.btn-xs {
height: 24px;
}
.dropdown-toggle,
.clone-dropdown-btn {
.fa {
color: unset;
}
}
.btn {
.notifications-icon {
top: 1px;
margin-right: 0;
}
}
}
.split-one {
display: inline-table;
margin-right: 12px;
......@@ -715,10 +770,10 @@
border-bottom: 1px solid $border-color;
}
.project-stats {
.project-stats,
.project-buttons {
font-size: 0;
text-align: center;
border-bottom: 1px solid $border-color;
.scrolling-tabs-container {
.scrolling-tabs {
......@@ -786,23 +841,43 @@
font-size: $gl-font-size;
line-height: $gl-btn-line-height;
color: $gl-text-color-secondary;
white-space: nowrap;
white-space: pre-wrap;
}
.stat-link {
border-bottom: 0;
color: $black;
&:hover,
&:focus {
color: $gl-text-color;
text-decoration: underline;
border-bottom: 0;
}
.project-stat-value {
color: $gl-text-color;
}
.icon {
color: $gl-text-color-secondary;
}
.add-license-link {
&,
.icon {
color: $blue-600;
}
}
}
.btn {
padding: $gl-btn-vert-padding $gl-btn-horz-padding;
margin-top: $gl-padding;
padding: $gl-btn-vert-padding $gl-btn-padding;
line-height: $gl-btn-line-height;
.icon {
top: 0;
}
}
.btn-missing {
......@@ -811,6 +886,13 @@
}
}
.project-buttons {
.stat-text {
@extend .btn;
@extend .btn-default;
}
}
.repository-languages-bar {
height: 8px;
margin-bottom: $gl-padding-8;
......@@ -934,8 +1016,6 @@ pre.light-well {
}
.git-clone-holder {
width: 320px;
.btn-clipboard {
border: 1px solid $border-color;
}
......@@ -958,6 +1038,15 @@ pre.light-well {
}
}
.git-clone-holder,
.mobile-git-clone {
.btn {
.icon {
fill: $white;
}
}
}
.cannot-be-merged,
.cannot-be-merged:hover {
color: $red-500;
......
......@@ -16,7 +16,11 @@ class NotificationSettingsController < ApplicationController
@notification_setting = current_user.notification_settings.find(params[:id])
@saved = @notification_setting.update(notification_setting_params_for(@notification_setting.source))
render_response
if params[:hide_label].present?
render_response("projects/buttons/_notifications")
else
render_response
end
end
private
......@@ -37,9 +41,9 @@ class NotificationSettingsController < ApplicationController
can?(current_user, ability_name, resource)
end
def render_response
def render_response(response_template = "shared/notifications/_button")
render json: {
html: view_to_html_string("shared/notifications/_button", notification_setting: @notification_setting),
html: view_to_html_string(response_template, notification_setting: @notification_setting),
saved: @saved
}
end
......
......@@ -85,13 +85,14 @@ module ButtonHelper
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { clone_type: 'ssh' })
end
def dropdown_item_with_description(title, description, href: nil, data: nil)
def dropdown_item_with_description(title, description, href: nil, data: nil, default: false)
active_class = "is-active" if default
button_content = content_tag(:strong, title, class: 'dropdown-menu-inner-title')
button_content << content_tag(:span, description, class: 'dropdown-menu-inner-content') if description
content_tag (href ? :a : :span),
(href ? button_content : title),
class: "#{title.downcase}-selector",
class: "#{title.downcase}-selector #{active_class}",
href: (href if href),
data: (data if data)
end
......
......@@ -140,7 +140,7 @@ module VisibilityLevelHelper
end
def project_visibility_icon_description(level)
"#{project_visibility_level_description(level)}"
"#{visibility_level_label(level)} - #{project_visibility_level_description(level)}"
end
def visibility_level_label(level)
......
This diff is collapsed.
.group-home-panel.text-center
.group-home-panel.text-center.border-bottom
%div{ class: container_class }
.avatar-container.s70.group-avatar
= group_icon(@group, class: "avatar s70 avatar-tile")
......
- is_project_overview = local_assigns.fetch(:is_project_overview, false)
- commit = local_assigns.fetch(:commit) { @repository.commit }
- ref = local_assigns.fetch(:ref) { current_ref }
- project = local_assigns.fetch(:project) { @project }
- content_url = local_assigns.fetch(:content_url) { @tree.readme ? project_blob_path(@project, tree_join(@ref, @tree.readme.path)) : project_tree_path(@project, @ref) }
- show_auto_devops_callout = show_auto_devops_callout?(@project)
#tree-holder.tree-holder.clearfix
.nav-block
......@@ -10,4 +12,8 @@
- if commit
= render 'shared/commit_well', commit: commit, ref: ref, project: project
- if is_project_overview
.project-buttons.append-bottom-default
= render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout)
= render 'projects/tree/tree_content', tree: @tree, content_url: content_url
- empty_repo = @project.empty_repo?
- license = @project.license_anchor_data
- show_auto_devops_callout = show_auto_devops_callout?(@project)
.project-home-panel{ class: ("empty-project" if empty_repo) }
.limit-container-width{ class: container_class }
.project-header.d-flex.flex-row.flex-wrap.align-items-center.append-bottom-8
.project-title-row.d-flex.align-items-center
.avatar-container.project-avatar.float-none
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s24', width: 24, height: 24)
%h1.project-title.d-flex.align-items-baseline.qa-project-name
= @project.name
.project-metadata.d-flex.flex-row.flex-wrap.align-items-baseline
.project-visibility.d-inline-flex.align-items-baseline.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, fw: false, options: {class: 'icon'})
= visibility_level_label(@project.visibility_level)
- if license.present?
.project-license.d-inline-flex.align-items-baseline
= link_to_if license.link, sprite_icon('scale', size: 16, css_class: 'icon') + license.label, license.link, class: license.enabled ? 'btn btn-link btn-secondary-hover-link' : 'btn btn-link'
- if @project.tag_list.present?
.project-tag-list.d-inline-flex.align-items-baseline.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_tags? ? @project.tag_list.join(', ') : nil }
= sprite_icon('tag', size: 16, css_class: 'icon')
= @project.tags_to_show
- if @project.has_extra_tags?
= _("+ %{count} more") % { count: @project.count_of_extra_tags_not_shown }
.project-header.row.append-bottom-8
.project-title-row.col-md-12.col-lg-7.d-flex
.avatar-container.project-avatar.float-none
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64)
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
%h1.project-title.qa-project-name
= @project.name
%span.project-visibility.prepend-left-8.d-inline-flex.align-items-baseline.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, fw: false, options: {class: 'icon'})
.project-metadata.d-flex.align-items-center
- if can?(current_user, :read_project, @project)
%span.text-secondary
= s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
- if current_user
%span.access-request-links.prepend-left-8
= render 'shared/members/access_request_links', source: @project
- if @project.tag_list.present?
%span.project-tag-list.d-inline-flex.prepend-left-8.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_tags? ? @project.tag_list.join(', ') : nil }
= sprite_icon('tag', size: 16, css_class: 'icon append-right-4')
= @project.tags_to_show
- if @project.has_extra_tags?
= _("+ %{count} more") % { count: @project.count_of_extra_tags_not_shown }
.project-home-desc
- if @project.description.present?
.project-description
.project-description-markdown.read-more-container
= markdown_field(@project, :description)
%button.btn.btn-blank.btn-link.text-secondary.js-read-more-trigger.text-secondary.d-lg-none{ type: "button" }
= _("Read more")
- if can?(current_user, :read_project, @project)
.text-secondary.prepend-top-8
= s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
- if @project.forked?
%p
- if @project.fork_source
#{ s_('ForkedFromProjectPath|Forked from') }
= link_to project_path(@project.fork_source) do
= fork_source_name(@project)
- else
- deleted_message = s_('ForkedFromProjectPath|Forked from %{project_name} (deleted)')
= deleted_message % { project_name: fork_source_name(@project) }
- if @project.mirror?
- import_url = @project.safe_import_url
%p
Mirrored from #{link_to import_url, import_url}.
%br
= render "shared/mirror_status"
- if @project.badges.present?
.project-badges.prepend-top-default.append-bottom-default
- @project.badges.each do |badge|
%a.append-right-8{ href: badge.rendered_link_url(@project),
target: '_blank',
rel: 'noopener noreferrer' }>
%img.project-badge{ src: badge.rendered_image_url(@project),
'aria-hidden': true,
alt: 'Project badge' }>
.project-repo-buttons.col-md-12.col-lg-5.d-inline-flex.flex-wrap.justify-content-lg-end
- if current_user
.d-inline-flex
= render 'projects/buttons/notifications', notification_setting: @notification_setting, btn_class: 'btn-xs'
.project-repo-buttons.d-inline-flex.flex-wrap
.count-buttons.d-inline-flex
= render 'projects/buttons/star'
= render 'projects/buttons/fork'
- if can?(current_user, :download_code, @project)
.project-clone-holder.d-inline-flex.d-sm-none
.project-clone-holder.d-inline-flex.d-md-none.btn-block
= render "shared/mobile_clone_panel"
.project-clone-holder.d-none.d-sm-inline-flex
= render "shared/clone_panel"
.project-clone-holder.d-none.d-md-inline-flex
= render "projects/buttons/clone"
- if show_xcode_link?(@project)
.project-action-button.project-xcode.inline
= render "projects/buttons/xcode_link"
- if can?(current_user, :download_code, @project)
%nav.project-stats
.nav-links.quick-links.mt-3
= render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
- if current_user
- if can?(current_user, :download_code, @project)
.d-none.d-sm-inline-flex
= render 'projects/buttons/download', project: @project, ref: @ref
.d-none.d-sm-inline-flex
= render 'projects/buttons/dropdown'
.project-home-desc.mt-1
- if @project.description.present?
.project-description
.project-description-markdown.read-more-container
= markdown_field(@project, :description)
%button.btn.btn-blank.btn-link.js-read-more-trigger.d-lg-none{ type: "button" }
= _("Read more")
- if @project.forked?
%p
- if @project.fork_source
#{ s_('ForkedFromProjectPath|Forked from') }
= link_to project_path(@project.fork_source) do
= fork_source_name(@project)
- else
- deleted_message = s_('ForkedFromProjectPath|Forked from %{project_name} (deleted)')
= deleted_message % { project_name: fork_source_name(@project) }
- if @project.mirror?
- import_url = @project.safe_import_url
%p
Mirrored from #{link_to import_url, import_url}.
%br
= render "shared/mirror_status"
.d-none.d-sm-inline-flex
= render 'shared/notifications/button', notification_setting: @notification_setting
.d-none.d-sm-inline-flex
= render 'shared/members/access_request_buttons', source: @project
- if @project.badges.present?
.project-badges.mb-2
- @project.badges.each do |badge|
%a.append-right-8{ href: badge.rendered_link_url(@project),
target: '_blank',
rel: 'noopener noreferrer' }>
%img.project-badge{ src: badge.rendered_image_url(@project),
'aria-hidden': true,
alt: 'Project badge' }>
......@@ -4,5 +4,5 @@
%ul.nav
- anchors.each do |anchor|
%li.nav-item
= link_to_if anchor.link, anchor.label, anchor.link, class: anchor.enabled ? 'nav-link stat-link' : "nav-link btn btn-#{anchor.class_modifier || 'missing'}" do
.stat-text= anchor.label
= link_to_if anchor.link, anchor.label, anchor.link, class: anchor.is_link ? 'nav-link stat-link d-flex align-items-center' : "nav-link btn btn-#{anchor.class_modifier || 'missing'} d-flex align-items-center" do
.stat-text.d-flex.align-items-center= anchor.label
- project = project || @project
.git-clone-holder.js-git-clone-holder.input-group
- if allowed_protocols_present?
.input-group-text.clone-dropdown-btn.btn
%span.js-clone-dropdown-label
= enabled_project_button(project, enabled_protocol)
- else
%a#clone-dropdown.input-group-text.btn.btn-primary.btn-xs.clone-dropdown-btn.qa-clone-dropdown{ href: '#', data: { toggle: 'dropdown' } }
%span.append-right-4.js-clone-dropdown-label
= _('Clone')
= sprite_icon("arrow-down", css_class: "icon")
%form.p-3.dropdown-menu.dropdown-menu-right.dropdown-menu-large.dropdown-menu-selectable.clone-options-dropdown
%li.pb-2
%label.label-bold
= _('Clone with SSH')
.input-group
= text_field_tag :ssh_project_clone, project.ssh_url_to_repo, class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
= clipboard_button(target: '#ssh_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
%li
%label.label-bold
= _('Clone with %{http_label}') % { http_label: gitlab_config.protocol.upcase }
.input-group
= text_field_tag :http_project_clone, project.http_url_to_repo, class: "js-select-on-focus form-control", readonly: true, aria: { label: 'Project clone URL' }
.input-group-append
= clipboard_button(target: '#http_project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
= render_if_exists 'projects/buttons/geo'
= render_if_exists 'shared/geo_info_modal', project: project
......@@ -5,8 +5,8 @@
.project-action-button.dropdown.inline>
%button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static' }
= sprite_icon('download')
= icon("caret-down")
%span.sr-only= _('Select Archive Format')
= sprite_icon("arrow-down")
%ul.dropdown-menu.dropdown-menu-right{ role: 'menu' }
%li.dropdown-header
#{ _('Source code') }
......
- unless @project.empty_repo?
- if current_user && can?(current_user, :fork_project, @project)
.count-badge.d-inline-flex.align-item-stretch.append-right-8
%span.fork-count.count-badge-count.d-flex.align-items-center
= link_to project_forks_path(@project), title: n_(s_('ProjectOverview|Fork'), s_('ProjectOverview|Forks'), @project.forks_count), class: 'count' do
= @project.forks_count
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'btn btn-default has-tooltip count-badge-button d-flex align-items-center fork-btn' do
= sprite_icon('fork', { css_class: 'icon' })
......@@ -15,3 +12,6 @@
title: (s_('ProjectOverview|You have reached your project limit') unless can_create_fork) do
= sprite_icon('fork', { css_class: 'icon' })
%span= s_('ProjectOverview|Fork')
%span.fork-count.count-badge-count.d-flex.align-items-center
= link_to project_forks_path(@project), title: n_(s_('ProjectOverview|Fork'), s_('ProjectOverview|Forks'), @project.forks_count), class: 'count' do
= @project.forks_count
- btn_class = local_assigns.fetch(:btn_class, "btn-xs")
- if notification_setting
.js-notification-dropdown.notification-dropdown.project-action-button.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
= f.hidden_field :level, class: "notification_setting_level"
.js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom?
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= sprite_icon("notifications", css_class: "icon notifications-icon js-notifications-icon")
%span.js-notification-loading.fa.hidden
%button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= sprite_icon("arrow-down", css_class: "icon")
.sr-only Toggle dropdown
- else
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting - #{notification_title(notification_setting.level)}", class: "#{btn_class}", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= sprite_icon("notifications", css_class: "icon notifications-icon js-notifications-icon")
%span.js-notification-loading.fa.hidden
= sprite_icon("arrow-down", css_class: "icon")
= render "shared/notifications/notification_dropdown", notification_setting: notification_setting
= content_for :scripts_body do
= render "shared/notifications/custom_notifications", notification_setting: notification_setting
- if current_user
.count-badge.d-inline-flex.align-item-stretch.append-right-8
%span.star-count.count-badge-count.d-flex.align-items-center
= @project.star_count
%button.count-badge-button.btn.btn-default.d-flex.align-items-center.star-btn.toggle-star{ type: "button", data: { endpoint: toggle_star_project_path(@project, :json) } }
%button.count-badge-button.btn.btn-default.btn-xs.d-flex.align-items-center.star-btn.toggle-star{ type: "button", data: { endpoint: toggle_star_project_path(@project, :json) } }
- if current_user.starred?(@project)
= sprite_icon('star', { css_class: 'icon' })
%span.starred= s_('ProjectOverview|Unstar')
- else
= sprite_icon('star-o', { css_class: 'icon' })
%span= s_('ProjectOverview|Star')
%span.star-count.count-badge-count.d-flex.align-items-center
= @project.star_count
- else
.count-badge.d-inline-flex.align-item-stretch.append-right-8
%span.star-count.count-badge-count.d-flex.align-items-center
= @project.star_count
= link_to new_user_session_path, class: 'btn btn-default has-tooltip count-badge-button d-flex align-items-center star-btn', title: s_('ProjectOverview|You must sign in to star a project') do
= link_to new_user_session_path, class: 'btn btn-default btn-xs has-tooltip count-badge-button d-flex align-items-center star-btn', title: s_('ProjectOverview|You must sign in to star a project') do
= sprite_icon('star-o', { css_class: 'icon' })
%span= s_('ProjectOverview|Star')
%span.star-count.count-badge-count.d-flex.align-items-center
= @project.star_count
......@@ -4,11 +4,10 @@
= render partial: 'flash_messages', locals: { project: @project }
= render "home_panel"
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
= render "home_panel"
.project-empty-note-panel
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
.prepend-top-20
.project-empty-note-panel
%h4.append-bottom-20
= _('The repository for this project is empty')
......@@ -32,66 +31,65 @@
= _('Otherwise it is recommended you start with one of the options below.')
.prepend-top-20
%nav.project-stats{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.nav-links.scrolling-tabs.quick-links
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_anchors
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons
%nav.project-buttons
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.nav-links.scrolling-tabs.quick-links
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons
- if can?(current_user, :push_code, @project)
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
.prepend-top-20
.empty_wrapper
%h3#repo-command-line-instructions.page-title-empty
Command line instructions
.git-empty.js-git-empty
%fieldset
%h5 Git global setup
%pre.bg-light
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
- if can?(current_user, :push_code, @project)
%div
.prepend-top-20
.empty_wrapper
%h3#repo-command-line-instructions.page-title-empty
= _('Command line instructions')
.git-empty.js-git-empty
%fieldset
%h5= _('Git global setup')
%pre.bg-light
:preserve
git config --global user.name "#{h git_user_name}"
git config --global user.email "#{h git_user_email}"
%fieldset
%h5 Create a new repository
%pre.bg-light
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin master
%fieldset
%h5= _('Create a new repository')
%pre.bg-light
:preserve
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
cd #{h @project.path}
touch README.md
git add README.md
git commit -m "add README"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin master
%fieldset
%h5 Existing folder
%pre.bg-light
:preserve
cd existing_folder
git init
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin master
%fieldset
%h5= _('Existing folder')
%pre.bg-light
:preserve
cd existing_folder
git init
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
git add .
git commit -m "Initial commit"
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin master
%fieldset
%h5 Existing Git repository
%pre.bg-light
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin --all
git push -u origin --tags
%fieldset
%h5= _('Existing Git repository')
%pre.bg-light
:preserve
cd existing_repo
git remote rename origin old-origin
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- if @project.can_current_user_push_to_default_branch?
%span><
git push -u origin --all
git push -u origin --tags
- if can? current_user, :remove_project, @project
.prepend-top-20
= link_to 'Remove project', [@project.namespace.becomes(Namespace), @project], data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-inverted btn-remove float-right"
- if can? current_user, :remove_project, @project
.prepend-top-20
= link_to _('Remove project'), [@project.namespace.becomes(Namespace), @project], data: { confirm: remove_project_message(@project)}, method: :delete, class: "btn btn-inverted btn-remove float-right"
- @no_container = true
- breadcrumb_title _("Details")
- @content_class = "limit-container-width" unless fluid_layout
- show_auto_devops_callout = show_auto_devops_callout?(@project)
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity")
......@@ -15,20 +14,11 @@
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
= render "projects/last_push"
= render "home_panel"
- if can?(current_user, :download_code, @project)
%nav.project-stats{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
.fade-left= icon('angle-left')
.fade-right= icon('angle-right')
.nav-links.scrolling-tabs.quick-links
= render 'stat_anchor_list', anchors: @project.statistics_anchors(show_auto_devops_callout: show_auto_devops_callout)
= render 'stat_anchor_list', anchors: @project.statistics_buttons(show_auto_devops_callout: show_auto_devops_callout)
= render "home_panel"
- if can?(current_user, :download_code, @project) && @project.repository_languages.present?
= repository_languages_bar(@project.repository_languages)
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
- if @project.archived?
.text-warning.center.prepend-top-20
%p
......@@ -41,4 +31,4 @@
= render 'shared/auto_devops_callout'
%div{ class: project_child_container_class(view_path) }
= render view_path
= render view_path, is_project_overview: true
......@@ -87,4 +87,8 @@
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
= _('Web IDE')
- if show_xcode_link?(@project)
.project-action-button.project-xcode.inline
= render "projects/buttons/xcode_link"
= render 'projects/buttons/download', project: @project, ref: @ref
......@@ -24,6 +24,6 @@
.input-group-append
= clipboard_button(target: '#project_clone', title: _("Copy URL to clipboard"), class: "input-group-text btn-default btn-clipboard")
= geo_button(modal_target: '#modal-geo-info') if Gitlab::Geo.secondary?
= geo_button(modal_target: '#modal-geo-info')
= render 'shared/geo_info_modal', project: project if Gitlab::Geo.secondary?
- project = project || @project
- ssh_copy_label = _("Copy SSH clone URL")
- http_copy_label = _("Copy HTTPS clone URL")
- http_copy_label = _('Copy %{http_label} clone URL') % { http_label: gitlab_config.protocol.upcase }
.btn-group.mobile-git-clone.js-mobile-git-clone
= clipboard_button(button_text: default_clone_label, target: '#project_clone', hide_button_icon: true, class: "input-group-text clone-dropdown-btn js-clone-dropdown-label btn btn-default")
%button.btn.btn-default.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { toggle: "dropdown" } }
= icon("caret-down", class: "dropdown-btn-icon")
.btn-group.mobile-git-clone.js-mobile-git-clone.btn-block
= clipboard_button(button_text: default_clone_label, text: default_url_to_repo(project), hide_button_icon: true, class: "btn-primary flex-fill bold justify-content-center input-group-text clone-dropdown-btn js-clone-dropdown-label")
%button.btn.btn-primary.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { toggle: "dropdown" } }
= sprite_icon("arrow-down", css_class: "dropdown-btn-icon icon")
%ul.dropdown-menu.dropdown-menu-selectable.dropdown-menu-right.clone-options-dropdown{ data: { dropdown: true } }
%li
= dropdown_item_with_description(ssh_copy_label, project.ssh_url_to_repo, href: project.ssh_url_to_repo, data: { clone_type: 'ssh' })
= dropdown_item_with_description(ssh_copy_label, project.ssh_url_to_repo, href: project.ssh_url_to_repo, data: { clone_type: 'ssh' }, default: true)
%li
= dropdown_item_with_description(http_copy_label, project.http_url_to_repo, href: project.http_url_to_repo, data: { clone_type: 'http' })
- model_name = source.model_name.to_s.downcase
- if can?(current_user, :"destroy_#{model_name}_member", source.members.find_by(user_id: current_user.id)) # rubocop: disable CodeReuse/ActiveRecord
- link_text = source.is_a?(Group) ? _('Leave group') : _('Leave project')
= link_to link_text, polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: leave_confirmation_message(source) },
class: 'access-request-link'
- elsif requester = source.requesters.find_by(user_id: current_user.id) # rubocop: disable CodeReuse/ActiveRecord
= link_to _('Withdraw Access Request'), polymorphic_path([:leave, source, :members]),
method: :delete,
data: { confirm: remove_member_message(requester) },
class: 'access-request-link'
- elsif source.request_access_enabled && can?(current_user, :request_access, source)
= link_to _('Request Access'), polymorphic_path([:request_access, source, :members]),
method: :post,
class: 'access-request-link'
- btn_class = local_assigns.fetch(:btn_class, nil)
- if notification_setting
.js-notification-dropdown.notification-dropdown.project-action-button.dropdown.inline
= form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f|
......@@ -6,14 +8,14 @@
.js-notification-toggle-btns
%div{ class: ("btn-group" if notification_setting.custom?) }
- if notification_setting.custom?
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: _("Notification setting"), class: "#{btn_class}", "aria-label" => _("Notification setting - %{notification_title}") % { notification_title: notification_title(notification_setting.level) }, data: { container: "body", toggle: "modal", target: "#" + notifications_menu_identifier("modal", notification_setting), display: 'static' } }
= icon("bell", class: "js-notification-loading")
= notification_title(notification_setting.level)
%button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= icon('caret-down')
.sr-only Toggle dropdown
- else
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
%button.dropdown-new.btn.btn-default.has-tooltip.notifications-btn#notifications-button{ type: "button", title: "Notification setting", class: "#{btn_class}", "aria-label" => "Notification setting: #{notification_title(notification_setting.level)}", data: { container: "body", toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
= icon("bell", class: "js-notification-loading")
= notification_title(notification_setting.level)
= icon("caret-down")
......
---
title: Design improvements to project overview page
merge_request: 22196
author:
type: changed
......@@ -5,22 +5,8 @@ export default () => {
if (!$modal.length) return;
$modal
.appendTo('body')
.modal({
modal: true,
show: false,
})
.on('show.bs.modal', e => {
const { cloneUrlPrimary, cloneUrlSecondary } = $(e.currentTarget).data();
$('#geo-info-1').val(
`git clone ${cloneUrlSecondary || '<clone url for secondary repository>'}`,
);
$('#geo-info-2').val(
`git remote set-url --push origin ${cloneUrlPrimary ||
'<clone url for primary repository>'}`,
);
});
$modal.appendTo('body').modal({
modal: true,
show: false,
});
};
......@@ -4,19 +4,19 @@ module EE
module ProjectPresenter
extend ::Gitlab::Utils::Override
override :statistics_anchors
def statistics_anchors(show_auto_devops_callout:)
super + extra_statistics_anchors
override :statistics_buttons
def statistics_buttons(show_auto_devops_callout:)
super + extra_statistics_buttons
end
def extra_statistics_anchors
anchors = []
def extra_statistics_buttons
buttons = []
if can?(current_user, :read_project_security_dashboard, project)
anchors << security_dashboard_data
buttons << security_dashboard_data
end
anchors
buttons
end
def approver_groups
......@@ -26,9 +26,10 @@ module EE
private
def security_dashboard_data
OpenStruct.new(enabled: true,
label: _('Security Dashboard'),
link: project_security_dashboard_path(project))
OpenStruct.new(is_link: false,
label: statistic_icon('lock') + _('Security Dashboard'),
link: project_security_dashboard_path(project),
class_modifier: 'default')
end
end
end
- if Gitlab::Geo.secondary?
= geo_button(modal_target: '#modal-geo-info')
#modal-geo-info.modal.in{ tabindex: '-1', data: { clone_url_secondary: h(default_url_to_repo(project)), clone_url_primary: h(geo_primary_default_url_to_repo(project)) } }
.modal-dialog
.modal-content
.modal-header
%h3.page-title
How to work faster with Geo
%a.close{ href: "#", "data-dismiss" => "modal" } ×
.modal-body
%p
%strong= 'Step 1.'
Clone the repository from your secondary node:
.form-group
.input-group
%input#geo-info-1.form-control{ value: "git clone " + default_url_to_repo(), readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-1', class: "btn-default", container: "#modal-geo-info")
%p
%strong= 'Step 2.'
Go to the new directory and define
%strong= "primary node's"
repository URL as the
%strong= 'push'
remote:
.form-group
.input-group
%input#geo-info-2.form-control{ value: "git remote set-url --push origin &lt;clone url for primary repository&gt;", readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-2', class: "btn-default", container: "#modal-geo-info")
%p
%strong= 'Done.'
You can now commit and push code as you normally do, but with increased speed.
- if Gitlab::Geo.secondary?
#modal-geo-info.modal.in{ tabindex: '-1' }
.modal-dialog
.modal-content
.modal-header
%h3.page-title
How to work faster with Geo
%a.close{ href: "#", "data-dismiss" => "modal" } ×
.modal-body
%p
%strong= 'Step 1.'
Clone the repository from your secondary node:
- if project.ssh_url_to_repo.present?
%p
%strong= 'SSH'
.form-group
.input-group
%input#geo-info-1-ssh.form-control{ value: "git clone " + project.ssh_url_to_repo, readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-1-ssh', class: "btn-default", container: "#modal-geo-info")
- if project.http_url_to_repo.present?
%p
%strong= 'HTTP'
.form-group
.input-group
%input#geo-info-1-http.form-control{ value: "git clone " + project.http_url_to_repo, readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-1-http', class: "btn-default", container: "#modal-geo-info")
- if alternative_kerberos_url?
%p
%strong= 'Kerberos'
.form-group
.input-group
%input#geo-info-1-kerberos.form-control{ value: "git clone " + project.kerberos_url_to_repo, readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-1-kerberos', class: "btn-default", container: "#modal-geo-info")
%p
%strong= 'Step 2.'
Go to the new directory and define
%strong= "primary node's"
repository URL as the
%strong= 'push'
remote:
- if geo_primary_ssh_url_to_repo(project).present? or geo_primary_http_url_to_repo(project).present?
- if geo_primary_ssh_url_to_repo(project).present?
%p
%strong= 'SSH'
.form-group
.input-group
%input#geo-info-2-ssh.form-control{ value: "git remote set-url --push origin " + geo_primary_ssh_url_to_repo(project), readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-2-ssh', class: "btn-default", container: "#modal-geo-info")
- if geo_primary_http_url_to_repo(project).present?
%p
%strong= 'HTTP'
.form-group
.input-group
%input#geo-info-2-http.form-control{ value: "git remote set-url --push origin " + geo_primary_http_url_to_repo(project), readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-2-http', class: "btn-default", container: "#modal-geo-info")
- else
.form-group
.input-group
%input#geo-info-2.form-control{ value: "git remote set-url --push origin &lt;clone url for primary repository&gt;", readonly: "readonly" }
.input-group-append
= clipboard_button(target: '#geo-info-2', class: "btn-default", container: "#modal-geo-info")
%p
%strong= 'Done.'
You can now commit and push code as you normally do, but with increased speed.
......@@ -23,20 +23,12 @@ describe 'Geo clone instructions', :js do
create(:personal_key, user: developer)
end
it 'defaults to SSH' do
it 'displays clone instructions' do
visit_project
show_geo_clone_instructions
expect_instructions_for('ssh')
end
it 'switches to HTTP' do
visit_project
select_protocol('HTTP')
show_geo_clone_instructions
expect_instructions_for('http')
end
end
......@@ -45,13 +37,9 @@ describe 'Geo clone instructions', :js do
visit project_path(project)
end
def select_protocol(protocol)
find('#clone-dropdown').click
find(".#{protocol.downcase}-selector").click
end
def show_geo_clone_instructions
find('.btn-geo').click
find('.qa-clone-dropdown').click
find('.btn-geo', match: :first).click
end
def expect_instructions_for(protocol)
......@@ -59,9 +47,9 @@ describe 'Geo clone instructions', :js do
secondary_remote = secondary_url(protocol)
expect(page).to have_content('How to work faster with Geo')
expect(page.find('#geo-info-1').value).to eq "git clone #{secondary_remote}"
expect(page.find("#geo-info-1-#{protocol}").value).to eq "git clone #{secondary_remote}"
# the primary_url does not return the full url, but just the part up to the host:
expect(page.find('#geo-info-2').value).to start_with("git remote set-url --push origin #{primary_remote}")
expect(page.find("#geo-info-2-#{protocol}").value).to start_with("git remote set-url --push origin #{primary_remote}")
end
def primary_url(protocol)
......
......@@ -21,7 +21,7 @@ describe 'Project show page', :feature do
visit project_path(project)
page.within('.project-stats') do
page.within('.project-buttons') do
expect(page).to have_link('Kubernetes configured', href: project_clusters_path(project))
end
end
......
......@@ -7,15 +7,16 @@ describe ProjectPresenter do
let(:user) { create(:user) }
describe '#extra_statistics_anchors' do
describe '#extra_statistics_buttons' do
let(:project) { create(:project) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:presenter) { described_class.new(project, current_user: user) }
let(:security_dashboard_data) do
OpenStruct.new(enabled: true,
label: _('Security Dashboard'),
link: project_security_dashboard_path(project))
OpenStruct.new(is_link: false,
label: a_string_including('Security Dashboard'),
link: project_security_dashboard_path(project),
class_modifier: 'default')
end
context 'user is allowed to read security dashboard' do
......@@ -24,7 +25,7 @@ describe ProjectPresenter do
end
it 'has security dashboard link' do
expect(presenter.extra_statistics_anchors).to include(security_dashboard_data)
expect(presenter.extra_statistics_buttons.find { |button| button[:link] == project_security_dashboard_path(project) }).not_to be_nil
end
end
......@@ -34,7 +35,7 @@ describe ProjectPresenter do
end
it 'has no security dashboard link' do
expect(presenter.extra_statistics_anchors).not_to include(security_dashboard_data)
expect(presenter.extra_statistics_buttons.find { |button| button[:link] == project_security_dashboard_path(project) }).to be_nil
end
end
end
......
......@@ -174,6 +174,24 @@ msgstr ""
msgid "%{state} epics"
msgstr ""
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
msgstr[0] ""
msgstr[1] ""
msgid "%{strong_start}%{commit_count}%{strong_end} Commit"
msgid_plural "%{strong_start}%{commit_count}%{strong_end} Commits"
msgstr[0] ""
msgstr[1] ""
msgid "%{strong_start}%{human_size}%{strong_end} Files"
msgstr ""
msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
msgstr[0] ""
msgstr[1] ""
msgid "%{text} %{files}"
msgid_plural "%{text} %{files} files"
msgstr[0] ""
......@@ -402,10 +420,10 @@ msgstr ""
msgid "Add"
msgstr ""
msgid "Add Changelog"
msgid "Add CHANGELOG"
msgstr ""
msgid "Add Contribution guide"
msgid "Add CONTRIBUTING"
msgstr ""
msgid "Add Group Webhooks and GitLab Enterprise Edition."
......@@ -417,7 +435,7 @@ msgstr ""
msgid "Add Kubernetes cluster"
msgstr ""
msgid "Add Readme"
msgid "Add README"
msgstr ""
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
......@@ -1232,11 +1250,6 @@ msgstr ""
msgid "Branch %{branchName} was not found in this project's repository."
msgstr ""
msgid "Branch (%{branch_count})"
msgid_plural "Branches (%{branch_count})"
msgstr[0] ""
msgstr[1] ""
msgid "Branch <strong>%{branch_name}</strong> was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
......@@ -1402,6 +1415,9 @@ msgstr ""
msgid "ByAuthor|by"
msgstr ""
msgid "CHANGELOG"
msgstr ""
msgid "CI / CD"
msgstr ""
......@@ -1468,6 +1484,9 @@ msgstr ""
msgid "CICD|instance enabled"
msgstr ""
msgid "CONTRIBUTING"
msgstr ""
msgid "Callback URL"
msgstr ""
......@@ -1519,9 +1538,6 @@ msgstr ""
msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
msgstr ""
msgid "Changelog"
msgstr ""
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
msgstr ""
......@@ -1738,9 +1754,18 @@ msgstr ""
msgid "Clients"
msgstr ""
msgid "Clone"
msgstr ""
msgid "Clone repository"
msgstr ""
msgid "Clone with %{http_label}"
msgstr ""
msgid "Clone with SSH"
msgstr ""
msgid "Close"
msgstr ""
......@@ -2182,6 +2207,9 @@ msgstr ""
msgid "Collapse sidebar"
msgstr ""
msgid "Command line instructions"
msgstr ""
msgid "Comment"
msgstr ""
......@@ -2202,11 +2230,6 @@ msgid_plural "Commits"
msgstr[0] ""
msgstr[1] ""
msgid "Commit (%{commit_count})"
msgid_plural "Commits (%{commit_count})"
msgstr[0] ""
msgstr[1] ""
msgid "Commit Message"
msgstr ""
......@@ -2411,9 +2434,6 @@ msgstr ""
msgid "Contribution Charts"
msgstr ""
msgid "Contribution guide"
msgstr ""
msgid "Contributions for <strong>%{calendar_date}</strong>"
msgstr ""
......@@ -2453,10 +2473,10 @@ msgstr ""
msgid "ConvDev Index"
msgstr ""
msgid "Copy %{protocol} clone URL"
msgid "Copy %{http_label} clone URL"
msgstr ""
msgid "Copy HTTPS clone URL"
msgid "Copy %{protocol} clone URL"
msgstr ""
msgid "Copy ID to clipboard"
......@@ -2525,6 +2545,9 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
msgid "Create a new repository"
msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
......@@ -3409,6 +3432,12 @@ msgstr ""
msgid "Everyone can contribute"
msgstr ""
msgid "Existing Git repository"
msgstr ""
msgid "Existing folder"
msgstr ""
msgid "Expand"
msgstr ""
......@@ -3616,9 +3645,6 @@ msgstr ""
msgid "Files"
msgstr ""
msgid "Files (%{human_size})"
msgstr ""
msgid "Fill in the fields below, turn on <strong>%{enable_label}</strong>, and press <strong>%{save_changes}</strong>"
msgstr ""
......@@ -4108,6 +4134,9 @@ msgstr ""
msgid "Git"
msgstr ""
msgid "Git global setup"
msgstr ""
msgid "Git repository URL"
msgstr ""
......@@ -5867,6 +5896,12 @@ msgstr ""
msgid "Notification events"
msgstr ""
msgid "Notification setting"
msgstr ""
msgid "Notification setting - %{notification_title}"
msgstr ""
msgid "NotificationEvent|Close issue"
msgstr ""
......@@ -6997,6 +7032,9 @@ msgstr ""
msgid "Quick actions can be used in the issues description and comment boxes."
msgstr ""
msgid "README"
msgstr ""
msgid "Read more"
msgstr ""
......@@ -7006,9 +7044,6 @@ msgstr ""
msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
msgstr ""
msgid "Readme"
msgstr ""
msgid "Real-time features"
msgstr ""
......@@ -8266,11 +8301,6 @@ msgstr ""
msgid "System metrics (Kubernetes)"
msgstr ""
msgid "Tag (%{tag_count})"
msgid_plural "Tags (%{tag_count})"
msgstr[0] ""
msgstr[1] ""
msgid "Tags"
msgstr ""
......
......@@ -10,54 +10,9 @@ describe 'Projects > Show > Developer views empty project instructions' do
sign_in(developer)
end
context 'without an SSH key' do
it 'defaults to HTTP' do
visit_project
expect_instructions_for('http')
end
it 'switches to SSH', :js do
visit_project
select_protocol('SSH')
expect_instructions_for('ssh')
end
end
context 'with an SSH key' do
before do
create(:personal_key, user: developer)
end
it 'defaults to SSH' do
visit_project
expect_instructions_for('ssh')
end
it 'switches to HTTP', :js do
visit_project
select_protocol('HTTP')
expect_instructions_for('http')
end
end
def visit_project
it 'displays "git clone" instructions' do
visit project_path(project)
end
def select_protocol(protocol)
find('#clone-dropdown').click
find(".#{protocol.downcase}-selector").click
end
def expect_instructions_for(protocol)
msg = :"#{protocol.downcase}_url_to_repo"
expect(page).to have_content("git clone #{project.send(msg)}")
expect(page).to have_content("git clone")
end
end
......@@ -8,13 +8,18 @@ describe 'Projects > Show > User manages notifications', :js do
visit project_path(project)
end
it 'changes the notification setting' do
def click_notifications_button
first('.notifications-btn').click
end
it 'changes the notification setting' do
click_notifications_button
click_link 'On mention'
page.within '#notifications-button' do
expect(page).to have_content 'On mention'
end
wait_for_requests
click_notifications_button
expect(find('.update-notification.is-active')).to have_content('On mention')
end
context 'custom notification settings' do
......@@ -38,7 +43,7 @@ describe 'Projects > Show > User manages notifications', :js do
end
it 'shows notification settings checkbox' do
first('.notifications-btn').click
click_notifications_button
page.find('a[data-notification-level="custom"]').click
page.within('.custom-notifications-form') do
......
......@@ -21,18 +21,6 @@ describe 'Projects > Show > Collaboration links' do
end
end
# The project header
page.within('.project-home-panel') do
aggregate_failures 'dropdown links in the project home panel' do
expect(page).to have_link('New issue')
expect(page).to have_link('New merge request')
expect(page).to have_link('New snippet')
expect(page).to have_link('New file')
expect(page).to have_link('New branch')
expect(page).to have_link('New tag')
end
end
# The dropdown above the tree
page.within('.repo-breadcrumb') do
aggregate_failures 'dropdown links above the repo tree' do
......@@ -61,17 +49,6 @@ describe 'Projects > Show > Collaboration links' do
end
end
page.within('.project-home-panel') do
aggregate_failures 'dropdown links' do
expect(page).not_to have_link('New issue')
expect(page).not_to have_link('New merge request')
expect(page).not_to have_link('New snippet')
expect(page).not_to have_link('New file')
expect(page).not_to have_link('New branch')
expect(page).not_to have_link('New tag')
end
end
page.within('.repo-breadcrumb') do
aggregate_failures 'dropdown links' do
expect(page).not_to have_link('New file')
......
......@@ -29,7 +29,7 @@ describe 'Projects > Show > User sees Git instructions' do
expect(element.text).to include(project.http_url_to_repo)
end
expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key
expect(page).to have_field('http_project_clone', with: project.http_url_to_repo) unless user_has_ssh_key
end
end
......@@ -41,7 +41,7 @@ describe 'Projects > Show > User sees Git instructions' do
expect(page).to have_content(project.title)
end
expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key
expect(page).to have_field('http_project_clone', with: project.http_url_to_repo) unless user_has_ssh_key
end
end
......
......@@ -13,7 +13,7 @@ describe 'Maintainer views tags' do
before do
visit project_path(project)
click_on 'Add Readme'
click_on 'Add README'
fill_in :commit_message, with: 'Add a README file', visible: true
click_button 'Commit changes'
visit project_tags_path(project)
......
This diff is collapsed.
......@@ -23,7 +23,7 @@ describe 'projects/_home_panel' do
it 'makes it possible to set notification level' do
render
expect(view).to render_template('shared/notifications/_button')
expect(view).to render_template('projects/buttons/_notifications')
expect(rendered).to have_selector('.notification-dropdown')
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment