Further design iteration on project overview
Continues the iteration on the project overview UI: - moved star, fork and new clone button (copy SSH/HTTPS URLs) to top right, made them smaller - avatar is now larger (64px) - 'Request access' is now a link instead of a button - overview comes before the description + changed styling and added icons - description font-size is now 16px (large-paragraph) - quick links to files are moved downwards below the commit/pipeline info - margins changed to group content into 4 groups to clean up the interface - visibility info reduced to icon-only and moved to the right of the title
This commit is contained in:
parent
61d91f640b
commit
75496059a1
|
@ -12,6 +12,10 @@ export default function notificationsDropdown() {
|
||||||
const form = $(this).parents('.notification-form:first');
|
const form = $(this).parents('.notification-form:first');
|
||||||
|
|
||||||
form.find('.js-notification-loading').toggleClass('fa-bell fa-spin fa-spinner');
|
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.find('#notification_setting_level').val(notificationLevel);
|
||||||
form.submit();
|
form.submit();
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,6 +13,9 @@ export default class Project {
|
||||||
const $cloneOptions = $('ul.clone-options-dropdown');
|
const $cloneOptions = $('ul.clone-options-dropdown');
|
||||||
const $projectCloneField = $('#project_clone');
|
const $projectCloneField = $('#project_clone');
|
||||||
const $cloneBtnLabel = $('.js-git-clone-holder .js-clone-dropdown-label');
|
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();
|
const selectedCloneOption = $cloneBtnLabel.text().trim();
|
||||||
if (selectedCloneOption.length > 0) {
|
if (selectedCloneOption.length > 0) {
|
||||||
|
@ -36,7 +39,11 @@ export default class Project {
|
||||||
$label.text(activeText);
|
$label.text(activeText);
|
||||||
});
|
});
|
||||||
|
|
||||||
$projectCloneField.val(url);
|
if (mobileCloneField) {
|
||||||
|
mobileCloneField.dataset.clipboardText = url;
|
||||||
|
} else {
|
||||||
|
$projectCloneField.val(url);
|
||||||
|
}
|
||||||
$('.js-git-empty .js-clone').text(url);
|
$('.js-git-empty .js-clone').text(url);
|
||||||
});
|
});
|
||||||
// Ref switcher
|
// Ref switcher
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
&.s46 { @include avatar-size(46px, 15px); }
|
&.s46 { @include avatar-size(46px, 15px); }
|
||||||
&.s48 { @include avatar-size(48px, 10px); }
|
&.s48 { @include avatar-size(48px, 10px); }
|
||||||
&.s60 { @include avatar-size(60px, 12px); }
|
&.s60 { @include avatar-size(60px, 12px); }
|
||||||
|
&.s64 { @include avatar-size(64px, 14px); }
|
||||||
&.s70 { @include avatar-size(70px, 14px); }
|
&.s70 { @include avatar-size(70px, 14px); }
|
||||||
&.s90 { @include avatar-size(90px, 15px); }
|
&.s90 { @include avatar-size(90px, 15px); }
|
||||||
&.s100 { @include avatar-size(100px, 15px); }
|
&.s100 { @include avatar-size(100px, 15px); }
|
||||||
|
@ -80,6 +81,7 @@
|
||||||
&.s40 { font-size: 16px; line-height: 38px; }
|
&.s40 { font-size: 16px; line-height: 38px; }
|
||||||
&.s48 { font-size: 20px; line-height: 46px; }
|
&.s48 { font-size: 20px; line-height: 46px; }
|
||||||
&.s60 { font-size: 32px; line-height: 58px; }
|
&.s60 { font-size: 32px; line-height: 58px; }
|
||||||
|
&.s64 { font-size: 32px; line-height: 64px; }
|
||||||
&.s70 { font-size: 34px; line-height: 70px; }
|
&.s70 { font-size: 34px; line-height: 70px; }
|
||||||
&.s90 { font-size: 36px; line-height: 88px; }
|
&.s90 { font-size: 36px; line-height: 88px; }
|
||||||
&.s100 { font-size: 36px; line-height: 98px; }
|
&.s100 { font-size: 36px; line-height: 98px; }
|
||||||
|
|
|
@ -142,8 +142,14 @@
|
||||||
|
|
||||||
&.btn-sm {
|
&.btn-sm {
|
||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
font-size: 13px;
|
font-size: $gl-btn-small-font-size;
|
||||||
line-height: 18px;
|
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,
|
&.btn-success,
|
||||||
|
|
|
@ -39,15 +39,6 @@
|
||||||
.git-clone-holder {
|
.git-clone-holder {
|
||||||
display: none;
|
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 {
|
.group-buttons {
|
||||||
|
|
|
@ -197,6 +197,7 @@ $well-light-text-color: #5b6169;
|
||||||
$gl-font-size: 14px;
|
$gl-font-size: 14px;
|
||||||
$gl-font-size-xs: 11px;
|
$gl-font-size-xs: 11px;
|
||||||
$gl-font-size-small: 12px;
|
$gl-font-size-small: 12px;
|
||||||
|
$gl-font-size-large: 16px;
|
||||||
$gl-font-weight-normal: 400;
|
$gl-font-weight-normal: 400;
|
||||||
$gl-font-weight-bold: 600;
|
$gl-font-weight-bold: 600;
|
||||||
$gl-text-color: #2e2e2e;
|
$gl-text-color: #2e2e2e;
|
||||||
|
@ -270,7 +271,8 @@ $performance-bar-height: 35px;
|
||||||
$flash-height: 52px;
|
$flash-height: 52px;
|
||||||
$context-header-height: 60px;
|
$context-header-height: 60px;
|
||||||
$breadcrumb-min-height: 48px;
|
$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: 16px;
|
||||||
$gl-line-height-24: 24px;
|
$gl-line-height-24: 24px;
|
||||||
|
|
||||||
|
@ -365,6 +367,8 @@ $gl-btn-padding: 10px;
|
||||||
$gl-btn-line-height: 16px;
|
$gl-btn-line-height: 16px;
|
||||||
$gl-btn-vert-padding: 8px;
|
$gl-btn-vert-padding: 8px;
|
||||||
$gl-btn-horz-padding: 12px;
|
$gl-btn-horz-padding: 12px;
|
||||||
|
$gl-btn-small-font-size: 13px;
|
||||||
|
$gl-btn-small-line-height: 13px;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Badges
|
* Badges
|
||||||
|
|
|
@ -144,7 +144,6 @@
|
||||||
.group-home-panel {
|
.group-home-panel {
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
padding-bottom: 24px;
|
padding-bottom: 24px;
|
||||||
border-bottom: 1px solid $border-color;
|
|
||||||
|
|
||||||
.group-avatar {
|
.group-avatar {
|
||||||
float: none;
|
float: none;
|
||||||
|
@ -155,7 +154,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-title,
|
|
||||||
.group-title {
|
.group-title {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
@ -195,25 +193,69 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-home-panel {
|
.project-home-panel {
|
||||||
padding-top: $gl-padding-8;
|
padding-top: $gl-padding;
|
||||||
padding-bottom: $gl-padding-24;
|
padding-bottom: $gl-padding;
|
||||||
|
|
||||||
.project-title-row {
|
|
||||||
margin-right: $gl-padding-8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-avatar {
|
.project-avatar {
|
||||||
width: $project-title-row-height;
|
width: $project-title-row-height;
|
||||||
height: $project-title-row-height;
|
height: $project-title-row-height;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
flex-basis: $project-title-row-height;
|
flex-basis: $project-title-row-height;
|
||||||
margin: 0 $gl-padding-8 0 0;
|
margin: 0 $gl-padding 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-title {
|
.project-title {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 5px;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
line-height: $project-title-row-height;
|
line-height: $gl-line-height-24;
|
||||||
font-weight: bold;
|
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 {
|
.project-metadata {
|
||||||
|
@ -222,16 +264,6 @@
|
||||||
line-height: $gl-btn-line-height;
|
line-height: $gl-btn-line-height;
|
||||||
color: $gl-text-color-secondary;
|
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 {
|
.project-license {
|
||||||
.btn {
|
.btn {
|
||||||
|
@ -240,12 +272,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-tag-list,
|
.access-request-link,
|
||||||
.project-license {
|
.project-tag-list {
|
||||||
.icon {
|
padding-left: $gl-padding-8;
|
||||||
position: relative;
|
border-left: 1px solid $gl-text-color-secondary;
|
||||||
top: 2px;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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;
|
vertical-align: top;
|
||||||
margin-top: $gl-padding;
|
margin-top: $gl-padding;
|
||||||
|
|
||||||
.count-badge {
|
|
||||||
height: $input-height;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
top: -1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.count-badge-count,
|
.count-badge-count,
|
||||||
.count-badge-button {
|
.count-badge-button {
|
||||||
border: 1px solid $border-color;
|
border: 1px solid $border-color;
|
||||||
|
@ -319,29 +353,25 @@
|
||||||
|
|
||||||
.count-badge-count {
|
.count-badge-count {
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
border-right: 0;
|
|
||||||
border-radius: $border-radius-base 0 0 $border-radius-base;
|
|
||||||
background: $gray-light;
|
background: $gray-light;
|
||||||
|
border-radius: 0 $border-radius-base $border-radius-base 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.count-badge-button {
|
.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 {
|
.project-clone-holder {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: $gl-padding $gl-padding-8 0 0;
|
margin: $gl-padding 0 0;
|
||||||
|
|
||||||
input {
|
input {
|
||||||
height: $input-height;
|
height: $input-height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.clone-dropdown-btn {
|
|
||||||
background-color: $white-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clone-options-dropdown {
|
.clone-options-dropdown {
|
||||||
min-width: 240px;
|
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 {
|
.split-one {
|
||||||
display: inline-table;
|
display: inline-table;
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
|
@ -715,10 +770,10 @@
|
||||||
border-bottom: 1px solid $border-color;
|
border-bottom: 1px solid $border-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-stats {
|
.project-stats,
|
||||||
|
.project-buttons {
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-bottom: 1px solid $border-color;
|
|
||||||
|
|
||||||
.scrolling-tabs-container {
|
.scrolling-tabs-container {
|
||||||
.scrolling-tabs {
|
.scrolling-tabs {
|
||||||
|
@ -786,23 +841,43 @@
|
||||||
font-size: $gl-font-size;
|
font-size: $gl-font-size;
|
||||||
line-height: $gl-btn-line-height;
|
line-height: $gl-btn-line-height;
|
||||||
color: $gl-text-color-secondary;
|
color: $gl-text-color-secondary;
|
||||||
white-space: nowrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-link {
|
.stat-link {
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
|
color: $black;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
color: $gl-text-color;
|
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project-stat-value {
|
||||||
|
color: $gl-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
color: $gl-text-color-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-license-link {
|
||||||
|
&,
|
||||||
|
.icon {
|
||||||
|
color: $blue-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn {
|
.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;
|
line-height: $gl-btn-line-height;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-missing {
|
.btn-missing {
|
||||||
|
@ -811,6 +886,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project-buttons {
|
||||||
|
.stat-text {
|
||||||
|
@extend .btn;
|
||||||
|
@extend .btn-default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.repository-languages-bar {
|
.repository-languages-bar {
|
||||||
height: 8px;
|
height: 8px;
|
||||||
margin-bottom: $gl-padding-8;
|
margin-bottom: $gl-padding-8;
|
||||||
|
@ -934,8 +1016,6 @@ pre.light-well {
|
||||||
}
|
}
|
||||||
|
|
||||||
.git-clone-holder {
|
.git-clone-holder {
|
||||||
width: 320px;
|
|
||||||
|
|
||||||
.btn-clipboard {
|
.btn-clipboard {
|
||||||
border: 1px solid $border-color;
|
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,
|
||||||
.cannot-be-merged:hover {
|
.cannot-be-merged:hover {
|
||||||
color: $red-500;
|
color: $red-500;
|
||||||
|
|
|
@ -16,7 +16,11 @@ class NotificationSettingsController < ApplicationController
|
||||||
@notification_setting = current_user.notification_settings.find(params[:id])
|
@notification_setting = current_user.notification_settings.find(params[:id])
|
||||||
@saved = @notification_setting.update(notification_setting_params_for(@notification_setting.source))
|
@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
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -37,9 +41,9 @@ class NotificationSettingsController < ApplicationController
|
||||||
can?(current_user, ability_name, resource)
|
can?(current_user, ability_name, resource)
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_response
|
def render_response(response_template = "shared/notifications/_button")
|
||||||
render json: {
|
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
|
saved: @saved
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -85,13 +85,14 @@ module ButtonHelper
|
||||||
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { clone_type: 'ssh' })
|
dropdown_item_with_description('SSH', dropdown_description, href: append_url, data: { clone_type: 'ssh' })
|
||||||
end
|
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(:strong, title, class: 'dropdown-menu-inner-title')
|
||||||
button_content << content_tag(:span, description, class: 'dropdown-menu-inner-content') if description
|
button_content << content_tag(:span, description, class: 'dropdown-menu-inner-content') if description
|
||||||
|
|
||||||
content_tag (href ? :a : :span),
|
content_tag (href ? :a : :span),
|
||||||
(href ? button_content : title),
|
(href ? button_content : title),
|
||||||
class: "#{title.downcase}-selector",
|
class: "#{title.downcase}-selector #{active_class}",
|
||||||
href: (href if href),
|
href: (href if href),
|
||||||
data: (data if data)
|
data: (data if data)
|
||||||
end
|
end
|
||||||
|
|
|
@ -140,7 +140,7 @@ module VisibilityLevelHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_visibility_icon_description(level)
|
def project_visibility_icon_description(level)
|
||||||
"#{project_visibility_level_description(level)}"
|
"#{visibility_level_label(level)} - #{project_visibility_level_description(level)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def visibility_level_label(level)
|
def visibility_level_label(level)
|
||||||
|
|
|
@ -6,27 +6,27 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
include GitlabRoutingHelper
|
include GitlabRoutingHelper
|
||||||
include StorageHelper
|
include StorageHelper
|
||||||
include TreeHelper
|
include TreeHelper
|
||||||
|
include IconsHelper
|
||||||
include ChecksCollaboration
|
include ChecksCollaboration
|
||||||
include Gitlab::Utils::StrongMemoize
|
include Gitlab::Utils::StrongMemoize
|
||||||
|
|
||||||
presents :project
|
presents :project
|
||||||
|
|
||||||
AnchorData = Struct.new(:enabled, :label, :link, :class_modifier)
|
AnchorData = Struct.new(:is_link, :label, :link, :class_modifier, :icon)
|
||||||
MAX_TAGS_TO_SHOW = 3
|
MAX_TAGS_TO_SHOW = 3
|
||||||
|
|
||||||
|
def statistic_icon(icon_name = 'plus-square-o')
|
||||||
|
sprite_icon(icon_name, size: 16, css_class: 'icon append-right-4')
|
||||||
|
end
|
||||||
|
|
||||||
def statistics_anchors(show_auto_devops_callout:)
|
def statistics_anchors(show_auto_devops_callout:)
|
||||||
[
|
[
|
||||||
readme_anchor_data,
|
license_anchor_data,
|
||||||
changelog_anchor_data,
|
|
||||||
contribution_guide_anchor_data,
|
|
||||||
files_anchor_data,
|
|
||||||
commits_anchor_data,
|
commits_anchor_data,
|
||||||
branches_anchor_data,
|
branches_anchor_data,
|
||||||
tags_anchor_data,
|
tags_anchor_data,
|
||||||
gitlab_ci_anchor_data,
|
files_anchor_data
|
||||||
autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout),
|
].compact.select(&:is_link)
|
||||||
kubernetes_cluster_anchor_data
|
|
||||||
].compact.select { |item| item.enabled }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def statistics_buttons(show_auto_devops_callout:)
|
def statistics_buttons(show_auto_devops_callout:)
|
||||||
|
@ -37,27 +37,28 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout),
|
autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout),
|
||||||
kubernetes_cluster_anchor_data,
|
kubernetes_cluster_anchor_data,
|
||||||
gitlab_ci_anchor_data
|
gitlab_ci_anchor_data
|
||||||
].compact.reject { |item| item.enabled }
|
].compact.reject(&:is_link)
|
||||||
end
|
end
|
||||||
|
|
||||||
def empty_repo_statistics_anchors
|
def empty_repo_statistics_anchors
|
||||||
[
|
[
|
||||||
files_anchor_data,
|
license_anchor_data,
|
||||||
commits_anchor_data,
|
commits_anchor_data,
|
||||||
branches_anchor_data,
|
branches_anchor_data,
|
||||||
tags_anchor_data,
|
tags_anchor_data,
|
||||||
autodevops_anchor_data,
|
files_anchor_data
|
||||||
kubernetes_cluster_anchor_data
|
].compact.select { |item| item.is_link }
|
||||||
].compact.select { |item| item.enabled }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def empty_repo_statistics_buttons
|
def empty_repo_statistics_buttons
|
||||||
[
|
[
|
||||||
new_file_anchor_data,
|
new_file_anchor_data,
|
||||||
readme_anchor_data,
|
readme_anchor_data,
|
||||||
|
changelog_anchor_data,
|
||||||
|
contribution_guide_anchor_data,
|
||||||
autodevops_anchor_data,
|
autodevops_anchor_data,
|
||||||
kubernetes_cluster_anchor_data
|
kubernetes_cluster_anchor_data
|
||||||
].compact.reject { |item| item.enabled }
|
].compact.reject { |item| item.is_link }
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_view
|
def default_view
|
||||||
|
@ -113,7 +114,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_contribution_guide_path
|
def add_contribution_guide_path
|
||||||
add_special_file_path(file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide')
|
add_special_file_path(file_name: 'CONTRIBUTING.md', commit_message: 'Add CONTRIBUTING')
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_ci_yml_path
|
def add_ci_yml_path
|
||||||
|
@ -149,32 +150,52 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
|
|
||||||
def files_anchor_data
|
def files_anchor_data
|
||||||
AnchorData.new(true,
|
AnchorData.new(true,
|
||||||
_('Files (%{human_size})') % { human_size: storage_counter(statistics.total_repository_size) },
|
statistic_icon('doc-code') +
|
||||||
|
_('%{strong_start}%{human_size}%{strong_end} Files').html_safe % {
|
||||||
|
human_size: storage_counter(statistics.total_repository_size),
|
||||||
|
strong_start: '<strong class="project-stat-value">'.html_safe,
|
||||||
|
strong_end: '</strong>'.html_safe
|
||||||
|
},
|
||||||
empty_repo? ? nil : project_tree_path(project))
|
empty_repo? ? nil : project_tree_path(project))
|
||||||
end
|
end
|
||||||
|
|
||||||
def commits_anchor_data
|
def commits_anchor_data
|
||||||
AnchorData.new(true,
|
AnchorData.new(true,
|
||||||
n_('Commit (%{commit_count})', 'Commits (%{commit_count})', statistics.commit_count) % { commit_count: number_with_delimiter(statistics.commit_count) },
|
statistic_icon('commit') +
|
||||||
|
n_('%{strong_start}%{commit_count}%{strong_end} Commit', '%{strong_start}%{commit_count}%{strong_end} Commits', statistics.commit_count).html_safe % {
|
||||||
|
commit_count: number_with_delimiter(statistics.commit_count),
|
||||||
|
strong_start: '<strong class="project-stat-value">'.html_safe,
|
||||||
|
strong_end: '</strong>'.html_safe
|
||||||
|
},
|
||||||
empty_repo? ? nil : project_commits_path(project, repository.root_ref))
|
empty_repo? ? nil : project_commits_path(project, repository.root_ref))
|
||||||
end
|
end
|
||||||
|
|
||||||
def branches_anchor_data
|
def branches_anchor_data
|
||||||
AnchorData.new(true,
|
AnchorData.new(true,
|
||||||
n_('Branch (%{branch_count})', 'Branches (%{branch_count})', repository.branch_count) % { branch_count: number_with_delimiter(repository.branch_count) },
|
statistic_icon('branch') +
|
||||||
|
n_('%{strong_start}%{branch_count}%{strong_end} Branch', '%{strong_start}%{branch_count}%{strong_end} Branches', repository.branch_count).html_safe % {
|
||||||
|
branch_count: number_with_delimiter(repository.branch_count),
|
||||||
|
strong_start: '<strong class="project-stat-value">'.html_safe,
|
||||||
|
strong_end: '</strong>'.html_safe
|
||||||
|
},
|
||||||
empty_repo? ? nil : project_branches_path(project))
|
empty_repo? ? nil : project_branches_path(project))
|
||||||
end
|
end
|
||||||
|
|
||||||
def tags_anchor_data
|
def tags_anchor_data
|
||||||
AnchorData.new(true,
|
AnchorData.new(true,
|
||||||
n_('Tag (%{tag_count})', 'Tags (%{tag_count})', repository.tag_count) % { tag_count: number_with_delimiter(repository.tag_count) },
|
statistic_icon('label') +
|
||||||
|
n_('%{strong_start}%{tag_count}%{strong_end} Tag', '%{strong_start}%{tag_count}%{strong_end} Tags', repository.tag_count).html_safe % {
|
||||||
|
tag_count: number_with_delimiter(repository.tag_count),
|
||||||
|
strong_start: '<strong class="project-stat-value">'.html_safe,
|
||||||
|
strong_end: '</strong>'.html_safe
|
||||||
|
},
|
||||||
empty_repo? ? nil : project_tags_path(project))
|
empty_repo? ? nil : project_tags_path(project))
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_file_anchor_data
|
def new_file_anchor_data
|
||||||
if current_user && can_current_user_push_to_default_branch?
|
if current_user && can_current_user_push_to_default_branch?
|
||||||
AnchorData.new(false,
|
AnchorData.new(false,
|
||||||
_('New file'),
|
statistic_icon + _('New file'),
|
||||||
project_new_blob_path(project, default_branch || 'master'),
|
project_new_blob_path(project, default_branch || 'master'),
|
||||||
'success')
|
'success')
|
||||||
end
|
end
|
||||||
|
@ -183,40 +204,45 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
def readme_anchor_data
|
def readme_anchor_data
|
||||||
if current_user && can_current_user_push_to_default_branch? && repository.readme.nil?
|
if current_user && can_current_user_push_to_default_branch? && repository.readme.nil?
|
||||||
AnchorData.new(false,
|
AnchorData.new(false,
|
||||||
_('Add Readme'),
|
statistic_icon + _('Add README'),
|
||||||
add_readme_path)
|
add_readme_path)
|
||||||
elsif repository.readme
|
elsif repository.readme
|
||||||
AnchorData.new(true,
|
AnchorData.new(false,
|
||||||
_('Readme'),
|
statistic_icon('doc-text') + _('README'),
|
||||||
default_view != 'readme' ? readme_path : '#readme')
|
default_view != 'readme' ? readme_path : '#readme',
|
||||||
|
'default',
|
||||||
|
'doc-text')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def changelog_anchor_data
|
def changelog_anchor_data
|
||||||
if current_user && can_current_user_push_to_default_branch? && repository.changelog.blank?
|
if current_user && can_current_user_push_to_default_branch? && repository.changelog.blank?
|
||||||
AnchorData.new(false,
|
AnchorData.new(false,
|
||||||
_('Add Changelog'),
|
statistic_icon + _('Add CHANGELOG'),
|
||||||
add_changelog_path)
|
add_changelog_path)
|
||||||
elsif repository.changelog.present?
|
elsif repository.changelog.present?
|
||||||
AnchorData.new(true,
|
AnchorData.new(false,
|
||||||
_('Changelog'),
|
statistic_icon('doc-text') + _('CHANGELOG'),
|
||||||
changelog_path)
|
changelog_path,
|
||||||
|
'default')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def license_anchor_data
|
def license_anchor_data
|
||||||
|
icon = statistic_icon('scale')
|
||||||
|
|
||||||
if repository.license_blob.present?
|
if repository.license_blob.present?
|
||||||
AnchorData.new(true,
|
AnchorData.new(true,
|
||||||
license_short_name,
|
icon + content_tag(:strong, license_short_name, class: 'project-stat-value'),
|
||||||
license_path)
|
license_path)
|
||||||
else
|
else
|
||||||
if current_user && can_current_user_push_to_default_branch?
|
if current_user && can_current_user_push_to_default_branch?
|
||||||
AnchorData.new(false,
|
AnchorData.new(true,
|
||||||
_('Add license'),
|
content_tag(:span, icon + _('Add license'), class: 'add-license-link d-flex'),
|
||||||
add_license_path)
|
add_license_path)
|
||||||
else
|
else
|
||||||
AnchorData.new(false,
|
AnchorData.new(true,
|
||||||
_('No license. All rights reserved'),
|
icon + content_tag(:strong, _('No license. All rights reserved'), class: 'project-stat-value'),
|
||||||
nil)
|
nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -225,22 +251,29 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
def contribution_guide_anchor_data
|
def contribution_guide_anchor_data
|
||||||
if current_user && can_current_user_push_to_default_branch? && repository.contribution_guide.blank?
|
if current_user && can_current_user_push_to_default_branch? && repository.contribution_guide.blank?
|
||||||
AnchorData.new(false,
|
AnchorData.new(false,
|
||||||
_('Add Contribution guide'),
|
statistic_icon + _('Add CONTRIBUTING'),
|
||||||
add_contribution_guide_path)
|
add_contribution_guide_path)
|
||||||
elsif repository.contribution_guide.present?
|
elsif repository.contribution_guide.present?
|
||||||
AnchorData.new(true,
|
AnchorData.new(false,
|
||||||
_('Contribution guide'),
|
statistic_icon('doc-text') + _('CONTRIBUTING'),
|
||||||
contribution_guide_path)
|
contribution_guide_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def autodevops_anchor_data(show_auto_devops_callout: false)
|
def autodevops_anchor_data(show_auto_devops_callout: false)
|
||||||
if current_user && can?(current_user, :admin_pipeline, project) && repository.gitlab_ci_yml.blank? && !show_auto_devops_callout
|
if current_user && can?(current_user, :admin_pipeline, project) && repository.gitlab_ci_yml.blank? && !show_auto_devops_callout
|
||||||
AnchorData.new(auto_devops_enabled?,
|
if auto_devops_enabled?
|
||||||
auto_devops_enabled? ? _('Auto DevOps enabled') : _('Enable Auto DevOps'),
|
AnchorData.new(false,
|
||||||
project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
statistic_icon('doc-text') + _('Auto DevOps enabled'),
|
||||||
|
project_settings_ci_cd_path(project, anchor: 'autodevops-settings'),
|
||||||
|
'default')
|
||||||
|
else
|
||||||
|
AnchorData.new(false,
|
||||||
|
statistic_icon + _('Enable Auto DevOps'),
|
||||||
|
project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
||||||
|
end
|
||||||
elsif auto_devops_enabled?
|
elsif auto_devops_enabled?
|
||||||
AnchorData.new(true,
|
AnchorData.new(false,
|
||||||
_('Auto DevOps enabled'),
|
_('Auto DevOps enabled'),
|
||||||
nil)
|
nil)
|
||||||
end
|
end
|
||||||
|
@ -248,27 +281,32 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
|
||||||
|
|
||||||
def kubernetes_cluster_anchor_data
|
def kubernetes_cluster_anchor_data
|
||||||
if current_user && can?(current_user, :create_cluster, project)
|
if current_user && can?(current_user, :create_cluster, project)
|
||||||
cluster_link = clusters.count == 1 ? project_cluster_path(project, clusters.first) : project_clusters_path(project)
|
|
||||||
|
|
||||||
if clusters.empty?
|
if clusters.empty?
|
||||||
cluster_link = new_project_cluster_path(project)
|
AnchorData.new(false,
|
||||||
end
|
statistic_icon + _('Add Kubernetes cluster'),
|
||||||
|
new_project_cluster_path(project))
|
||||||
|
else
|
||||||
|
cluster_link = clusters.count == 1 ? project_cluster_path(project, clusters.first) : project_clusters_path(project)
|
||||||
|
|
||||||
AnchorData.new(!clusters.empty?,
|
AnchorData.new(false,
|
||||||
clusters.empty? ? _('Add Kubernetes cluster') : _('Kubernetes configured'),
|
_('Kubernetes configured'),
|
||||||
cluster_link)
|
cluster_link,
|
||||||
|
'default')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def gitlab_ci_anchor_data
|
def gitlab_ci_anchor_data
|
||||||
if current_user && can_current_user_push_code? && repository.gitlab_ci_yml.blank? && !auto_devops_enabled?
|
if current_user && can_current_user_push_code? && repository.gitlab_ci_yml.blank? && !auto_devops_enabled?
|
||||||
AnchorData.new(false,
|
AnchorData.new(false,
|
||||||
_('Set up CI/CD'),
|
statistic_icon + _('Set up CI/CD'),
|
||||||
add_ci_yml_path)
|
add_ci_yml_path)
|
||||||
elsif repository.gitlab_ci_yml.present?
|
elsif repository.gitlab_ci_yml.present?
|
||||||
AnchorData.new(true,
|
AnchorData.new(false,
|
||||||
_('CI/CD configuration'),
|
statistic_icon('doc-text') + _('CI/CD configuration'),
|
||||||
ci_configuration_path)
|
ci_configuration_path,
|
||||||
|
'default')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.group-home-panel.text-center
|
.group-home-panel.text-center.border-bottom
|
||||||
%div{ class: container_class }
|
%div{ class: container_class }
|
||||||
.avatar-container.s70.group-avatar
|
.avatar-container.s70.group-avatar
|
||||||
= group_icon(@group, class: "avatar s70 avatar-tile")
|
= group_icon(@group, class: "avatar s70 avatar-tile")
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
- is_project_overview = local_assigns.fetch(:is_project_overview, false)
|
||||||
- commit = local_assigns.fetch(:commit) { @repository.commit }
|
- commit = local_assigns.fetch(:commit) { @repository.commit }
|
||||||
- ref = local_assigns.fetch(:ref) { current_ref }
|
- ref = local_assigns.fetch(:ref) { current_ref }
|
||||||
- project = local_assigns.fetch(:project) { @project }
|
- 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) }
|
- 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
|
#tree-holder.tree-holder.clearfix
|
||||||
.nav-block
|
.nav-block
|
||||||
|
@ -10,4 +12,8 @@
|
||||||
- if commit
|
- if commit
|
||||||
= render 'shared/commit_well', commit: commit, ref: ref, project: project
|
= 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
|
= render 'projects/tree/tree_content', tree: @tree, content_url: content_url
|
||||||
|
|
|
@ -1,83 +1,75 @@
|
||||||
- empty_repo = @project.empty_repo?
|
- 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) }
|
.project-home-panel{ class: ("empty-project" if empty_repo) }
|
||||||
.limit-container-width{ class: container_class }
|
.project-header.row.append-bottom-8
|
||||||
.project-header.d-flex.flex-row.flex-wrap.align-items-center.append-bottom-8
|
.project-title-row.col-md-12.col-lg-7.d-flex
|
||||||
.project-title-row.d-flex.align-items-center
|
.avatar-container.project-avatar.float-none
|
||||||
.avatar-container.project-avatar.float-none
|
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64)
|
||||||
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s24', width: 24, height: 24)
|
.d-flex.flex-column.flex-wrap.align-items-baseline
|
||||||
%h1.project-title.d-flex.align-items-baseline.qa-project-name
|
.d-inline-flex.align-items-baseline
|
||||||
= @project.name
|
%h1.project-title.qa-project-name
|
||||||
.project-metadata.d-flex.flex-row.flex-wrap.align-items-baseline
|
= @project.name
|
||||||
.project-visibility.d-inline-flex.align-items-baseline.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
|
%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'})
|
= visibility_level_icon(@project.visibility_level, fw: false, options: {class: 'icon'})
|
||||||
= visibility_level_label(@project.visibility_level)
|
.project-metadata.d-flex.align-items-center
|
||||||
- if license.present?
|
- if can?(current_user, :read_project, @project)
|
||||||
.project-license.d-inline-flex.align-items-baseline
|
%span.text-secondary
|
||||||
= 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'
|
= s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
|
||||||
- if @project.tag_list.present?
|
- if current_user
|
||||||
.project-tag-list.d-inline-flex.align-items-baseline.has-tooltip{ data: { container: 'body' }, title: @project.has_extra_tags? ? @project.tag_list.join(', ') : nil }
|
%span.access-request-links.prepend-left-8
|
||||||
= sprite_icon('tag', size: 16, css_class: 'icon')
|
= render 'shared/members/access_request_links', source: @project
|
||||||
= @project.tags_to_show
|
- if @project.tag_list.present?
|
||||||
- if @project.has_extra_tags?
|
%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 }
|
||||||
= _("+ %{count} more") % { count: @project.count_of_extra_tags_not_shown }
|
= 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
|
.project-repo-buttons.col-md-12.col-lg-5.d-inline-flex.flex-wrap.justify-content-lg-end
|
||||||
- if @project.description.present?
|
- if current_user
|
||||||
.project-description
|
.d-inline-flex
|
||||||
.project-description-markdown.read-more-container
|
= render 'projects/buttons/notifications', notification_setting: @notification_setting, btn_class: 'btn-xs'
|
||||||
= 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.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.d-inline-flex.flex-wrap
|
|
||||||
.count-buttons.d-inline-flex
|
.count-buttons.d-inline-flex
|
||||||
= render 'projects/buttons/star'
|
= render 'projects/buttons/star'
|
||||||
= render 'projects/buttons/fork'
|
= render 'projects/buttons/fork'
|
||||||
|
|
||||||
- if can?(current_user, :download_code, @project)
|
- 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"
|
= render "shared/mobile_clone_panel"
|
||||||
|
|
||||||
.project-clone-holder.d-none.d-sm-inline-flex
|
.project-clone-holder.d-none.d-md-inline-flex
|
||||||
= render "shared/clone_panel"
|
= render "projects/buttons/clone"
|
||||||
|
|
||||||
- if show_xcode_link?(@project)
|
- if can?(current_user, :download_code, @project)
|
||||||
.project-action-button.project-xcode.inline
|
%nav.project-stats
|
||||||
= render "projects/buttons/xcode_link"
|
.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
|
.project-home-desc.mt-1
|
||||||
- if can?(current_user, :download_code, @project)
|
- if @project.description.present?
|
||||||
.d-none.d-sm-inline-flex
|
.project-description
|
||||||
= render 'projects/buttons/download', project: @project, ref: @ref
|
.project-description-markdown.read-more-container
|
||||||
.d-none.d-sm-inline-flex
|
= markdown_field(@project, :description)
|
||||||
= render 'projects/buttons/dropdown'
|
%button.btn.btn-blank.btn-link.js-read-more-trigger.d-lg-none{ type: "button" }
|
||||||
|
= _("Read more")
|
||||||
|
|
||||||
.d-none.d-sm-inline-flex
|
- if @project.forked?
|
||||||
= render 'shared/notifications/button', notification_setting: @notification_setting
|
%p
|
||||||
.d-none.d-sm-inline-flex
|
- if @project.fork_source
|
||||||
= render 'shared/members/access_request_buttons', source: @project
|
#{ 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.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
|
%ul.nav
|
||||||
- anchors.each do |anchor|
|
- anchors.each do |anchor|
|
||||||
%li.nav-item
|
%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
|
= 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= anchor.label
|
.stat-text.d-flex.align-items-center= anchor.label
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
- 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>
|
.project-action-button.dropdown.inline>
|
||||||
%button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static' }
|
%button.btn.has-tooltip{ title: s_('DownloadSource|Download'), 'data-toggle' => 'dropdown', 'aria-label' => s_('DownloadSource|Download'), 'data-display' => 'static' }
|
||||||
= sprite_icon('download')
|
= sprite_icon('download')
|
||||||
= icon("caret-down")
|
|
||||||
%span.sr-only= _('Select Archive Format')
|
%span.sr-only= _('Select Archive Format')
|
||||||
|
= sprite_icon("arrow-down")
|
||||||
%ul.dropdown-menu.dropdown-menu-right{ role: 'menu' }
|
%ul.dropdown-menu.dropdown-menu-right{ role: 'menu' }
|
||||||
%li.dropdown-header
|
%li.dropdown-header
|
||||||
#{ _('Source code') }
|
#{ _('Source code') }
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
- unless @project.empty_repo?
|
- unless @project.empty_repo?
|
||||||
- if current_user && can?(current_user, :fork_project, @project)
|
- if current_user && can?(current_user, :fork_project, @project)
|
||||||
.count-badge.d-inline-flex.align-item-stretch.append-right-8
|
.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
|
- 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
|
= 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' })
|
= sprite_icon('fork', { css_class: 'icon' })
|
||||||
|
@ -15,3 +12,6 @@
|
||||||
title: (s_('ProjectOverview|You have reached your project limit') unless can_create_fork) do
|
title: (s_('ProjectOverview|You have reached your project limit') unless can_create_fork) do
|
||||||
= sprite_icon('fork', { css_class: 'icon' })
|
= sprite_icon('fork', { css_class: 'icon' })
|
||||||
%span= s_('ProjectOverview|Fork')
|
%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
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
- 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
|
|
@ -1,19 +1,19 @@
|
||||||
- if current_user
|
- if current_user
|
||||||
.count-badge.d-inline-flex.align-item-stretch.append-right-8
|
.count-badge.d-inline-flex.align-item-stretch.append-right-8
|
||||||
%span.star-count.count-badge-count.d-flex.align-items-center
|
%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) } }
|
||||||
= @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) } }
|
|
||||||
- if current_user.starred?(@project)
|
- if current_user.starred?(@project)
|
||||||
= sprite_icon('star', { css_class: 'icon' })
|
= sprite_icon('star', { css_class: 'icon' })
|
||||||
%span.starred= s_('ProjectOverview|Unstar')
|
%span.starred= s_('ProjectOverview|Unstar')
|
||||||
- else
|
- else
|
||||||
= sprite_icon('star-o', { css_class: 'icon' })
|
= sprite_icon('star-o', { css_class: 'icon' })
|
||||||
%span= s_('ProjectOverview|Star')
|
%span= s_('ProjectOverview|Star')
|
||||||
|
%span.star-count.count-badge-count.d-flex.align-items-center
|
||||||
|
= @project.star_count
|
||||||
|
|
||||||
- else
|
- else
|
||||||
.count-badge.d-inline-flex.align-item-stretch.append-right-8
|
.count-badge.d-inline-flex.align-item-stretch.append-right-8
|
||||||
%span.star-count.count-badge-count.d-flex.align-items-center
|
= 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
|
||||||
= @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
|
|
||||||
= sprite_icon('star-o', { css_class: 'icon' })
|
= sprite_icon('star-o', { css_class: 'icon' })
|
||||||
%span= s_('ProjectOverview|Star')
|
%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 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
|
.project-empty-note-panel
|
||||||
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
|
|
||||||
.prepend-top-20
|
|
||||||
%h4.append-bottom-20
|
%h4.append-bottom-20
|
||||||
= _('The repository for this project is empty')
|
= _('The repository for this project is empty')
|
||||||
|
|
||||||
|
@ -32,66 +31,65 @@
|
||||||
= _('Otherwise it is recommended you start with one of the options below.')
|
= _('Otherwise it is recommended you start with one of the options below.')
|
||||||
.prepend-top-20
|
.prepend-top-20
|
||||||
|
|
||||||
%nav.project-stats{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
|
%nav.project-buttons
|
||||||
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
|
.scrolling-tabs-container.inner-page-scroll-tabs.is-smaller
|
||||||
.fade-left= icon('angle-left')
|
.fade-left= icon('angle-left')
|
||||||
.fade-right= icon('angle-right')
|
.fade-right= icon('angle-right')
|
||||||
.nav-links.scrolling-tabs.quick-links
|
.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
|
||||||
= render 'stat_anchor_list', anchors: @project.empty_repo_statistics_buttons
|
|
||||||
|
|
||||||
- if can?(current_user, :push_code, @project)
|
- if can?(current_user, :push_code, @project)
|
||||||
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
|
%div
|
||||||
.prepend-top-20
|
.prepend-top-20
|
||||||
.empty_wrapper
|
.empty_wrapper
|
||||||
%h3#repo-command-line-instructions.page-title-empty
|
%h3#repo-command-line-instructions.page-title-empty
|
||||||
Command line instructions
|
= _('Command line instructions')
|
||||||
.git-empty.js-git-empty
|
.git-empty.js-git-empty
|
||||||
%fieldset
|
%fieldset
|
||||||
%h5 Git global setup
|
%h5= _('Git global setup')
|
||||||
%pre.bg-light
|
%pre.bg-light
|
||||||
:preserve
|
:preserve
|
||||||
git config --global user.name "#{h git_user_name}"
|
git config --global user.name "#{h git_user_name}"
|
||||||
git config --global user.email "#{h git_user_email}"
|
git config --global user.email "#{h git_user_email}"
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
%h5 Create a new repository
|
%h5= _('Create a new repository')
|
||||||
%pre.bg-light
|
%pre.bg-light
|
||||||
:preserve
|
:preserve
|
||||||
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
|
git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
|
||||||
cd #{h @project.path}
|
cd #{h @project.path}
|
||||||
touch README.md
|
touch README.md
|
||||||
git add README.md
|
git add README.md
|
||||||
git commit -m "add README"
|
git commit -m "add README"
|
||||||
- if @project.can_current_user_push_to_default_branch?
|
- if @project.can_current_user_push_to_default_branch?
|
||||||
%span><
|
%span><
|
||||||
git push -u origin master
|
git push -u origin master
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
%h5 Existing folder
|
%h5= _('Existing folder')
|
||||||
%pre.bg-light
|
%pre.bg-light
|
||||||
:preserve
|
:preserve
|
||||||
cd existing_folder
|
cd existing_folder
|
||||||
git init
|
git init
|
||||||
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
|
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
|
||||||
git add .
|
git add .
|
||||||
git commit -m "Initial commit"
|
git commit -m "Initial commit"
|
||||||
- if @project.can_current_user_push_to_default_branch?
|
- if @project.can_current_user_push_to_default_branch?
|
||||||
%span><
|
%span><
|
||||||
git push -u origin master
|
git push -u origin master
|
||||||
|
|
||||||
%fieldset
|
%fieldset
|
||||||
%h5 Existing Git repository
|
%h5= _('Existing Git repository')
|
||||||
%pre.bg-light
|
%pre.bg-light
|
||||||
:preserve
|
:preserve
|
||||||
cd existing_repo
|
cd existing_repo
|
||||||
git remote rename origin old-origin
|
git remote rename origin old-origin
|
||||||
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
|
git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
|
||||||
- if @project.can_current_user_push_to_default_branch?
|
- if @project.can_current_user_push_to_default_branch?
|
||||||
%span><
|
%span><
|
||||||
git push -u origin --all
|
git push -u origin --all
|
||||||
git push -u origin --tags
|
git push -u origin --tags
|
||||||
|
|
||||||
- if can? current_user, :remove_project, @project
|
- if can? current_user, :remove_project, @project
|
||||||
.prepend-top-20
|
.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"
|
= 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"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
- @no_container = true
|
- @no_container = true
|
||||||
- breadcrumb_title _("Details")
|
- breadcrumb_title _("Details")
|
||||||
- @content_class = "limit-container-width" unless fluid_layout
|
- @content_class = "limit-container-width" unless fluid_layout
|
||||||
- show_auto_devops_callout = show_auto_devops_callout?(@project)
|
|
||||||
|
|
||||||
= content_for :meta_tags do
|
= content_for :meta_tags do
|
||||||
= auto_discovery_link_tag(:atom, project_path(@project, rss_url_options), title: "#{@project.name} activity")
|
= 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)] }
|
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
|
||||||
= render "projects/last_push"
|
= render "projects/last_push"
|
||||||
|
|
||||||
= render "home_panel"
|
= 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)
|
|
||||||
|
|
||||||
|
- if can?(current_user, :download_code, @project) && @project.repository_languages.present?
|
||||||
= repository_languages_bar(@project.repository_languages)
|
= repository_languages_bar(@project.repository_languages)
|
||||||
|
|
||||||
%div{ class: [container_class, ("limit-container-width" unless fluid_layout)] }
|
|
||||||
- if @project.archived?
|
- if @project.archived?
|
||||||
.text-warning.center.prepend-top-20
|
.text-warning.center.prepend-top-20
|
||||||
%p
|
%p
|
||||||
|
@ -41,4 +31,4 @@
|
||||||
= render 'shared/auto_devops_callout'
|
= render 'shared/auto_devops_callout'
|
||||||
|
|
||||||
%div{ class: project_child_container_class(view_path) }
|
%div{ class: project_child_container_class(view_path) }
|
||||||
= render view_path
|
= render view_path, is_project_overview: true
|
||||||
|
|
|
@ -85,4 +85,8 @@
|
||||||
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
|
= link_to ide_edit_path(@project, @ref, @path), class: 'btn btn-default qa-web-ide-button' do
|
||||||
= _('Web IDE')
|
= _('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
|
= render 'projects/buttons/download', project: @project, ref: @ref
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
- project = project || @project
|
- project = project || @project
|
||||||
- ssh_copy_label = _("Copy SSH clone URL")
|
- 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
|
.btn-group.mobile-git-clone.js-mobile-git-clone.btn-block
|
||||||
= 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")
|
= 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-default.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { toggle: "dropdown" } }
|
%button.btn.btn-primary.dropdown-toggle.js-dropdown-toggle{ type: "button", data: { toggle: "dropdown" } }
|
||||||
= icon("caret-down", class: "dropdown-btn-icon")
|
= 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 } }
|
%ul.dropdown-menu.dropdown-menu-selectable.dropdown-menu-right.clone-options-dropdown{ data: { dropdown: true } }
|
||||||
%li
|
%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
|
%li
|
||||||
= dropdown_item_with_description(http_copy_label, project.http_url_to_repo, href: project.http_url_to_repo, data: { clone_type: 'http' })
|
= dropdown_item_with_description(http_copy_label, project.http_url_to_repo, href: project.http_url_to_repo, data: { clone_type: 'http' })
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
- 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'
|
|
@ -1,3 +1,5 @@
|
||||||
|
- btn_class = local_assigns.fetch(:btn_class, nil)
|
||||||
|
|
||||||
- if notification_setting
|
- if notification_setting
|
||||||
.js-notification-dropdown.notification-dropdown.project-action-button.dropdown.inline
|
.js-notification-dropdown.notification-dropdown.project-action-button.dropdown.inline
|
||||||
= form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f|
|
= form_for notification_setting, remote: true, html: { class: "inline notification-form" } do |f|
|
||||||
|
@ -6,14 +8,14 @@
|
||||||
.js-notification-toggle-btns
|
.js-notification-toggle-btns
|
||||||
%div{ class: ("btn-group" if notification_setting.custom?) }
|
%div{ class: ("btn-group" if notification_setting.custom?) }
|
||||||
- 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")
|
= icon("bell", class: "js-notification-loading")
|
||||||
= notification_title(notification_setting.level)
|
= notification_title(notification_setting.level)
|
||||||
%button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
|
%button.btn.dropdown-toggle{ data: { toggle: "dropdown", target: notifications_menu_identifier("dropdown", notification_setting), flip: "false" } }
|
||||||
= icon('caret-down')
|
= icon('caret-down')
|
||||||
.sr-only Toggle dropdown
|
.sr-only Toggle dropdown
|
||||||
- else
|
- 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")
|
= icon("bell", class: "js-notification-loading")
|
||||||
= notification_title(notification_setting.level)
|
= notification_title(notification_setting.level)
|
||||||
= icon("caret-down")
|
= icon("caret-down")
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Design improvements to project overview page
|
||||||
|
merge_request: 22196
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -141,6 +141,24 @@ msgstr ""
|
||||||
msgid "%{percent}%% complete"
|
msgid "%{percent}%% complete"
|
||||||
msgstr ""
|
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 "%{text} %{files}"
|
||||||
msgid_plural "%{text} %{files} files"
|
msgid_plural "%{text} %{files} files"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
|
@ -333,16 +351,16 @@ msgstr ""
|
||||||
msgid "Activity"
|
msgid "Activity"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add Changelog"
|
msgid "Add CHANGELOG"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add Contribution guide"
|
msgid "Add CONTRIBUTING"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add Kubernetes cluster"
|
msgid "Add Kubernetes cluster"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add Readme"
|
msgid "Add README"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
|
msgid "Add a homepage to your wiki that contains information about your project and GitLab will display it here instead of this message."
|
||||||
|
@ -945,11 +963,6 @@ msgstr ""
|
||||||
msgid "Branch %{branchName} was not found in this project's repository."
|
msgid "Branch %{branchName} was not found in this project's repository."
|
||||||
msgstr ""
|
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}"
|
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 ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1103,6 +1116,9 @@ msgstr ""
|
||||||
msgid "ByAuthor|by"
|
msgid "ByAuthor|by"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "CHANGELOG"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "CI / CD"
|
msgid "CI / CD"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1160,6 +1176,9 @@ msgstr ""
|
||||||
msgid "CICD|instance enabled"
|
msgid "CICD|instance enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "CONTRIBUTING"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Callback URL"
|
msgid "Callback URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1202,9 +1221,6 @@ msgstr ""
|
||||||
msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
|
msgid "ChangeTypeAction|This will create a new commit in order to revert the existing changes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Changelog"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
|
msgid "Changes are shown as if the <b>source</b> revision was being merged into the <b>target</b> revision."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1388,9 +1404,18 @@ msgstr ""
|
||||||
msgid "Clients"
|
msgid "Clients"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clone"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Clone repository"
|
msgid "Clone repository"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clone with %{http_label}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Clone with SSH"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1811,6 +1836,9 @@ msgstr ""
|
||||||
msgid "Collapse sidebar"
|
msgid "Collapse sidebar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Command line instructions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comment"
|
msgid "Comment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1831,11 +1859,6 @@ msgid_plural "Commits"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
msgid "Commit (%{commit_count})"
|
|
||||||
msgid_plural "Commits (%{commit_count})"
|
|
||||||
msgstr[0] ""
|
|
||||||
msgstr[1] ""
|
|
||||||
|
|
||||||
msgid "Commit Message"
|
msgid "Commit Message"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2019,9 +2042,6 @@ msgstr ""
|
||||||
msgid "Contribution Charts"
|
msgid "Contribution Charts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Contribution guide"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Contributions for <strong>%{calendar_date}</strong>"
|
msgid "Contributions for <strong>%{calendar_date}</strong>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2046,10 +2066,10 @@ msgstr ""
|
||||||
msgid "ConvDev Index"
|
msgid "ConvDev Index"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Copy %{protocol} clone URL"
|
msgid "Copy %{http_label} clone URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Copy HTTPS clone URL"
|
msgid "Copy %{protocol} clone URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Copy ID to clipboard"
|
msgid "Copy ID to clipboard"
|
||||||
|
@ -2112,6 +2132,9 @@ msgstr ""
|
||||||
msgid "Create a new issue"
|
msgid "Create a new issue"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Create a new repository"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Create a personal access token on your account to pull or push via %{protocol}."
|
msgid "Create a personal access token on your account to pull or push via %{protocol}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2870,6 +2893,12 @@ msgstr ""
|
||||||
msgid "Everyone can contribute"
|
msgid "Everyone can contribute"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Existing Git repository"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Existing folder"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Expand"
|
msgid "Expand"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2978,9 +3007,6 @@ msgstr ""
|
||||||
msgid "Files"
|
msgid "Files"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Files (%{human_size})"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Filter"
|
msgid "Filter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -3107,6 +3133,9 @@ msgstr ""
|
||||||
msgid "Git"
|
msgid "Git"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Git global setup"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Git repository URL"
|
msgid "Git repository URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -4438,6 +4467,12 @@ msgstr ""
|
||||||
msgid "Notification events"
|
msgid "Notification events"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Notification setting"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Notification setting - %{notification_title}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "NotificationEvent|Close issue"
|
msgid "NotificationEvent|Close issue"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -5349,6 +5384,9 @@ msgstr ""
|
||||||
msgid "Quick actions can be used in the issues description and comment boxes."
|
msgid "Quick actions can be used in the issues description and comment boxes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "README"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read more"
|
msgid "Read more"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -5358,9 +5396,6 @@ msgstr ""
|
||||||
msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
|
msgid "Read more about project permissions <strong>%{link_to_help}</strong>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Readme"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Real-time features"
|
msgid "Real-time features"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -6294,11 +6329,6 @@ msgstr ""
|
||||||
msgid "System metrics (Kubernetes)"
|
msgid "System metrics (Kubernetes)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Tag (%{tag_count})"
|
|
||||||
msgid_plural "Tags (%{tag_count})"
|
|
||||||
msgstr[0] ""
|
|
||||||
msgstr[1] ""
|
|
||||||
|
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -10,54 +10,9 @@ describe 'Projects > Show > Developer views empty project instructions' do
|
||||||
sign_in(developer)
|
sign_in(developer)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'without an SSH key' do
|
it 'displays "git clone" instructions' 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
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
end
|
|
||||||
|
|
||||||
def select_protocol(protocol)
|
expect(page).to have_content("git clone")
|
||||||
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)}")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,13 +8,18 @@ describe 'Projects > Show > User manages notifications', :js do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'changes the notification setting' do
|
def click_notifications_button
|
||||||
first('.notifications-btn').click
|
first('.notifications-btn').click
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'changes the notification setting' do
|
||||||
|
click_notifications_button
|
||||||
click_link 'On mention'
|
click_link 'On mention'
|
||||||
|
|
||||||
page.within '#notifications-button' do
|
wait_for_requests
|
||||||
expect(page).to have_content 'On mention'
|
|
||||||
end
|
click_notifications_button
|
||||||
|
expect(find('.update-notification.is-active')).to have_content('On mention')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'custom notification settings' do
|
context 'custom notification settings' do
|
||||||
|
@ -38,7 +43,7 @@ describe 'Projects > Show > User manages notifications', :js do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows notification settings checkbox' do
|
it 'shows notification settings checkbox' do
|
||||||
first('.notifications-btn').click
|
click_notifications_button
|
||||||
page.find('a[data-notification-level="custom"]').click
|
page.find('a[data-notification-level="custom"]').click
|
||||||
|
|
||||||
page.within('.custom-notifications-form') do
|
page.within('.custom-notifications-form') do
|
||||||
|
|
|
@ -21,18 +21,6 @@ describe 'Projects > Show > Collaboration links' do
|
||||||
end
|
end
|
||||||
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
|
# The dropdown above the tree
|
||||||
page.within('.repo-breadcrumb') do
|
page.within('.repo-breadcrumb') do
|
||||||
aggregate_failures 'dropdown links above the repo tree' do
|
aggregate_failures 'dropdown links above the repo tree' do
|
||||||
|
@ -61,17 +49,6 @@ describe 'Projects > Show > Collaboration links' do
|
||||||
end
|
end
|
||||||
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
|
page.within('.repo-breadcrumb') do
|
||||||
aggregate_failures 'dropdown links' do
|
aggregate_failures 'dropdown links' do
|
||||||
expect(page).not_to have_link('New file')
|
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)
|
expect(element.text).to include(project.http_url_to_repo)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ describe 'Projects > Show > User sees Git instructions' do
|
||||||
expect(page).to have_content(project.title)
|
expect(page).to have_content(project.title)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'no Auto DevOps button if can not manage pipelines' do
|
it 'no Auto DevOps button if can not manage pipelines' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Enable Auto DevOps')
|
expect(page).not_to have_link('Enable Auto DevOps')
|
||||||
expect(page).not_to have_link('Auto DevOps enabled')
|
expect(page).not_to have_link('Auto DevOps enabled')
|
||||||
end
|
end
|
||||||
|
@ -30,7 +30,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it '"Auto DevOps enabled" button not linked' do
|
it '"Auto DevOps enabled" button not linked' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_text('Auto DevOps enabled')
|
expect(page).to have_text('Auto DevOps enabled')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -45,19 +45,19 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it '"New file" button linked to new file page' do
|
it '"New file" button linked to new file page' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master'))
|
expect(page).to have_link('New file', href: project_new_blob_path(project, project.default_branch || 'master'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it '"Add Readme" button linked to new file populated for a readme' do
|
it '"Add README" button linked to new file populated for a README' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Add Readme', href: presenter.add_readme_path)
|
expect(page).to have_link('Add README', href: presenter.add_readme_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it '"Add license" button linked to new file populated for a license' do
|
it '"Add license" button linked to new file populated for a license' do
|
||||||
page.within('.project-metadata') do
|
page.within('.project-stats') do
|
||||||
expect(page).to have_link('Add license', href: presenter.add_license_path)
|
expect(page).to have_link('Add license', href: presenter.add_license_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -67,7 +67,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it '"Auto DevOps enabled" anchor linked to settings page' do
|
it '"Auto DevOps enabled" anchor linked to settings page' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -77,7 +77,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
let(:project) { create(:project, :public, :empty_repo, auto_devops_attributes: { enabled: false }) }
|
let(:project) { create(:project, :public, :empty_repo, auto_devops_attributes: { enabled: false }) }
|
||||||
|
|
||||||
it '"Enable Auto DevOps" button linked to settings page' do
|
it '"Enable Auto DevOps" button linked to settings page' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -86,7 +86,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
describe 'Kubernetes cluster button' do
|
describe 'Kubernetes cluster button' do
|
||||||
it '"Add Kubernetes cluster" button linked to clusters page' do
|
it '"Add Kubernetes cluster" button linked to clusters page' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
|
expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -96,7 +96,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
|
expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -119,7 +119,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it '"Auto DevOps enabled" button not linked' do
|
it '"Auto DevOps enabled" button not linked' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_text('Auto DevOps enabled')
|
expect(page).to have_text('Auto DevOps enabled')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -129,14 +129,14 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
let(:project) { create(:project, :public, :repository, auto_devops_attributes: { enabled: false }) }
|
let(:project) { create(:project, :public, :repository, auto_devops_attributes: { enabled: false }) }
|
||||||
|
|
||||||
it 'no Auto DevOps button if can not manage pipelines' do
|
it 'no Auto DevOps button if can not manage pipelines' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Enable Auto DevOps')
|
expect(page).not_to have_link('Enable Auto DevOps')
|
||||||
expect(page).not_to have_link('Auto DevOps enabled')
|
expect(page).not_to have_link('Auto DevOps enabled')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'no Kubernetes cluster button if can not manage clusters' do
|
it 'no Kubernetes cluster button if can not manage clusters' do
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Add Kubernetes cluster')
|
expect(page).not_to have_link('Add Kubernetes cluster')
|
||||||
expect(page).not_to have_link('Kubernetes configured')
|
expect(page).not_to have_link('Kubernetes configured')
|
||||||
end
|
end
|
||||||
|
@ -151,59 +151,59 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Readme button' do
|
context 'README button' do
|
||||||
before do
|
before do
|
||||||
allow(Project).to receive(:find_by_full_path)
|
allow(Project).to receive(:find_by_full_path)
|
||||||
.with(project.full_path, follow_redirects: true)
|
.with(project.full_path, follow_redirects: true)
|
||||||
.and_return(project)
|
.and_return(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the project has a populated Readme' do
|
context 'when the project has a populated README' do
|
||||||
it 'show the "Readme" anchor' do
|
it 'show the "README" anchor' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
expect(project.repository.readme).not_to be_nil
|
expect(project.repository.readme).not_to be_nil
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Add Readme', href: presenter.add_readme_path)
|
expect(page).not_to have_link('Add README', href: presenter.add_readme_path)
|
||||||
expect(page).to have_link('Readme', href: presenter.readme_path)
|
expect(page).to have_link('README', href: presenter.readme_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the project has an empty Readme' do
|
context 'when the project has an empty README' do
|
||||||
it 'show the "Readme" anchor' do
|
it 'show the "README" anchor' do
|
||||||
allow(project.repository).to receive(:readme).and_return(fake_blob(path: 'README.md', data: '', size: 0))
|
allow(project.repository).to receive(:readme).and_return(fake_blob(path: 'README.md', data: '', size: 0))
|
||||||
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Add Readme', href: presenter.add_readme_path)
|
expect(page).not_to have_link('Add README', href: presenter.add_readme_path)
|
||||||
expect(page).to have_link('Readme', href: presenter.readme_path)
|
expect(page).to have_link('README', href: presenter.readme_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the project does not have a Readme' do
|
context 'when the project does not have a README' do
|
||||||
it 'shows the "Add Readme" button' do
|
it 'shows the "Add README" button' do
|
||||||
allow(project.repository).to receive(:readme).and_return(nil)
|
allow(project.repository).to receive(:readme).and_return(nil)
|
||||||
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Add Readme', href: presenter.add_readme_path)
|
expect(page).to have_link('Add README', href: presenter.add_readme_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'no "Add Changelog" button if the project already has a changelog' do
|
it 'no "Add CHANGELOG" button if the project already has a changelog' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
expect(project.repository.changelog).not_to be_nil
|
expect(project.repository.changelog).not_to be_nil
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Add Changelog')
|
expect(page).not_to have_link('Add CHANGELOG')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -212,18 +212,18 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
expect(project.repository.license_blob).not_to be_nil
|
expect(project.repository.license_blob).not_to be_nil
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Add license')
|
expect(page).not_to have_link('Add license')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'no "Add Contribution guide" button if the project already has a contribution guide' do
|
it 'no "Add CONTRIBUTING" button if the project already has a contribution guide' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
expect(project.repository.contribution_guide).not_to be_nil
|
expect(project.repository.contribution_guide).not_to be_nil
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Add Contribution guide')
|
expect(page).not_to have_link('Add CONTRIBUTING')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do
|
it 'no "Set up CI/CD" button if the project has Auto DevOps enabled' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Set up CI/CD')
|
expect(page).not_to have_link('Set up CI/CD')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -246,7 +246,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
expect(project.repository.gitlab_ci_yml).to be_nil
|
expect(project.repository.gitlab_ci_yml).to be_nil
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path)
|
expect(page).to have_link('Set up CI/CD', href: presenter.add_ci_yml_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -266,7 +266,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Set up CI/CD')
|
expect(page).not_to have_link('Set up CI/CD')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -278,7 +278,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it '"Auto DevOps enabled" anchor linked to settings page' do
|
it '"Auto DevOps enabled" anchor linked to settings page' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
expect(page).to have_link('Auto DevOps enabled', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -290,7 +290,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it '"Enable Auto DevOps" button linked to settings page' do
|
it '"Enable Auto DevOps" button linked to settings page' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
expect(page).to have_link('Enable Auto DevOps', href: project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -302,7 +302,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
expect(page).to have_selector('.js-autodevops-banner')
|
expect(page).to have_selector('.js-autodevops-banner')
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Enable Auto DevOps')
|
expect(page).not_to have_link('Enable Auto DevOps')
|
||||||
expect(page).not_to have_link('Auto DevOps enabled')
|
expect(page).not_to have_link('Auto DevOps enabled')
|
||||||
end
|
end
|
||||||
|
@ -323,7 +323,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).not_to have_link('Enable Auto DevOps')
|
expect(page).not_to have_link('Enable Auto DevOps')
|
||||||
expect(page).not_to have_link('Auto DevOps enabled')
|
expect(page).not_to have_link('Auto DevOps enabled')
|
||||||
end
|
end
|
||||||
|
@ -335,7 +335,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
it '"Add Kubernetes cluster" button linked to clusters page' do
|
it '"Add Kubernetes cluster" button linked to clusters page' do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
|
expect(page).to have_link('Add Kubernetes cluster', href: new_project_cluster_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -345,7 +345,7 @@ describe 'Projects > Show > User sees setup shortcut buttons' do
|
||||||
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
|
|
||||||
page.within('.project-stats') do
|
page.within('.project-buttons') do
|
||||||
expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
|
expect(page).to have_link('Kubernetes configured', href: project_cluster_path(project, cluster))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,7 +13,7 @@ describe 'Maintainer views tags' do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
click_on 'Add Readme'
|
click_on 'Add README'
|
||||||
fill_in :commit_message, with: 'Add a README file', visible: true
|
fill_in :commit_message, with: 'Add a README file', visible: true
|
||||||
click_button 'Commit changes'
|
click_button 'Commit changes'
|
||||||
visit project_tags_path(project)
|
visit project_tags_path(project)
|
||||||
|
|
|
@ -165,32 +165,32 @@ describe ProjectPresenter do
|
||||||
|
|
||||||
describe '#files_anchor_data' do
|
describe '#files_anchor_data' do
|
||||||
it 'returns files data' do
|
it 'returns files data' do
|
||||||
expect(presenter.files_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.files_anchor_data).to have_attributes(is_link: true,
|
||||||
label: 'Files (0 Bytes)',
|
label: a_string_including('0 Bytes'),
|
||||||
link: nil)
|
link: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#commits_anchor_data' do
|
describe '#commits_anchor_data' do
|
||||||
it 'returns commits data' do
|
it 'returns commits data' do
|
||||||
expect(presenter.commits_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.commits_anchor_data).to have_attributes(is_link: true,
|
||||||
label: 'Commits (0)',
|
label: a_string_including('0'),
|
||||||
link: nil)
|
link: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#branches_anchor_data' do
|
describe '#branches_anchor_data' do
|
||||||
it 'returns branches data' do
|
it 'returns branches data' do
|
||||||
expect(presenter.branches_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.branches_anchor_data).to have_attributes(is_link: true,
|
||||||
label: "Branches (0)",
|
label: a_string_including('0'),
|
||||||
link: nil)
|
link: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#tags_anchor_data' do
|
describe '#tags_anchor_data' do
|
||||||
it 'returns tags data' do
|
it 'returns tags data' do
|
||||||
expect(presenter.tags_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.tags_anchor_data).to have_attributes(is_link: true,
|
||||||
label: "Tags (0)",
|
label: a_string_including('0'),
|
||||||
link: nil)
|
link: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -202,32 +202,32 @@ describe ProjectPresenter do
|
||||||
|
|
||||||
describe '#files_anchor_data' do
|
describe '#files_anchor_data' do
|
||||||
it 'returns files data' do
|
it 'returns files data' do
|
||||||
expect(presenter.files_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.files_anchor_data).to have_attributes(is_link: true,
|
||||||
label: 'Files (0 Bytes)',
|
label: a_string_including('0 Bytes'),
|
||||||
link: presenter.project_tree_path(project))
|
link: presenter.project_tree_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#commits_anchor_data' do
|
describe '#commits_anchor_data' do
|
||||||
it 'returns commits data' do
|
it 'returns commits data' do
|
||||||
expect(presenter.commits_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.commits_anchor_data).to have_attributes(is_link: true,
|
||||||
label: 'Commits (0)',
|
label: a_string_including('0'),
|
||||||
link: presenter.project_commits_path(project, project.repository.root_ref))
|
link: presenter.project_commits_path(project, project.repository.root_ref))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#branches_anchor_data' do
|
describe '#branches_anchor_data' do
|
||||||
it 'returns branches data' do
|
it 'returns branches data' do
|
||||||
expect(presenter.branches_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.branches_anchor_data).to have_attributes(is_link: true,
|
||||||
label: "Branches (#{project.repository.branches.size})",
|
label: a_string_including("#{project.repository.branches.size}"),
|
||||||
link: presenter.project_branches_path(project))
|
link: presenter.project_branches_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#tags_anchor_data' do
|
describe '#tags_anchor_data' do
|
||||||
it 'returns tags data' do
|
it 'returns tags data' do
|
||||||
expect(presenter.tags_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.tags_anchor_data).to have_attributes(is_link: true,
|
||||||
label: "Tags (#{project.repository.tags.size})",
|
label: a_string_including("#{project.repository.tags.size}"),
|
||||||
link: presenter.project_tags_path(project))
|
link: presenter.project_tags_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -236,8 +236,8 @@ describe ProjectPresenter do
|
||||||
it 'returns new file data if user can push' do
|
it 'returns new file data if user can push' do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
|
|
||||||
expect(presenter.new_file_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.new_file_anchor_data).to have_attributes(is_link: false,
|
||||||
label: "New file",
|
label: a_string_including("New file"),
|
||||||
link: presenter.project_new_blob_path(project, 'master'),
|
link: presenter.project_new_blob_path(project, 'master'),
|
||||||
class_modifier: 'success')
|
class_modifier: 'success')
|
||||||
end
|
end
|
||||||
|
@ -264,8 +264,8 @@ describe ProjectPresenter do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
allow(project.repository).to receive(:readme).and_return(nil)
|
allow(project.repository).to receive(:readme).and_return(nil)
|
||||||
|
|
||||||
expect(presenter.readme_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.readme_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Add Readme',
|
label: a_string_including('Add README'),
|
||||||
link: presenter.add_readme_path)
|
link: presenter.add_readme_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -274,21 +274,21 @@ describe ProjectPresenter do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
allow(project.repository).to receive(:readme).and_return(double(name: 'readme'))
|
allow(project.repository).to receive(:readme).and_return(double(name: 'readme'))
|
||||||
|
|
||||||
expect(presenter.readme_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.readme_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Readme',
|
label: a_string_including('README'),
|
||||||
link: presenter.readme_path)
|
link: presenter.readme_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#changelog_anchor_data' do
|
describe '#changelog_anchor_data' do
|
||||||
context 'when user can push and CHANGELOG does not exists' do
|
context 'when user can push and CHANGELOG does not exist' do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
allow(project.repository).to receive(:changelog).and_return(nil)
|
allow(project.repository).to receive(:changelog).and_return(nil)
|
||||||
|
|
||||||
expect(presenter.changelog_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.changelog_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Add Changelog',
|
label: a_string_including('Add CHANGELOG'),
|
||||||
link: presenter.add_changelog_path)
|
link: presenter.add_changelog_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -297,21 +297,21 @@ describe ProjectPresenter do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
allow(project.repository).to receive(:changelog).and_return(double(name: 'foo'))
|
allow(project.repository).to receive(:changelog).and_return(double(name: 'foo'))
|
||||||
|
|
||||||
expect(presenter.changelog_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.changelog_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Changelog',
|
label: a_string_including('CHANGELOG'),
|
||||||
link: presenter.changelog_path)
|
link: presenter.changelog_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#license_anchor_data' do
|
describe '#license_anchor_data' do
|
||||||
context 'when user can push and LICENSE does not exists' do
|
context 'when user can push and LICENSE does not exist' do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
allow(project.repository).to receive(:license_blob).and_return(nil)
|
allow(project.repository).to receive(:license_blob).and_return(nil)
|
||||||
|
|
||||||
expect(presenter.license_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.license_anchor_data).to have_attributes(is_link: true,
|
||||||
label: 'Add license',
|
label: a_string_including('Add license'),
|
||||||
link: presenter.add_license_path)
|
link: presenter.add_license_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -320,21 +320,21 @@ describe ProjectPresenter do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
allow(project.repository).to receive(:license_blob).and_return(double(name: 'foo'))
|
allow(project.repository).to receive(:license_blob).and_return(double(name: 'foo'))
|
||||||
|
|
||||||
expect(presenter.license_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.license_anchor_data).to have_attributes(is_link: true,
|
||||||
label: presenter.license_short_name,
|
label: a_string_including(presenter.license_short_name),
|
||||||
link: presenter.license_path)
|
link: presenter.license_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#contribution_guide_anchor_data' do
|
describe '#contribution_guide_anchor_data' do
|
||||||
context 'when user can push and CONTRIBUTING does not exists' do
|
context 'when user can push and CONTRIBUTING does not exist' do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
allow(project.repository).to receive(:contribution_guide).and_return(nil)
|
allow(project.repository).to receive(:contribution_guide).and_return(nil)
|
||||||
|
|
||||||
expect(presenter.contribution_guide_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.contribution_guide_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Add Contribution guide',
|
label: a_string_including('Add CONTRIBUTING'),
|
||||||
link: presenter.add_contribution_guide_path)
|
link: presenter.add_contribution_guide_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -343,8 +343,8 @@ describe ProjectPresenter do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
allow(project.repository).to receive(:contribution_guide).and_return(double(name: 'foo'))
|
allow(project.repository).to receive(:contribution_guide).and_return(double(name: 'foo'))
|
||||||
|
|
||||||
expect(presenter.contribution_guide_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.contribution_guide_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Contribution guide',
|
label: a_string_including('CONTRIBUTING'),
|
||||||
link: presenter.contribution_guide_path)
|
link: presenter.contribution_guide_path)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -355,20 +355,20 @@ describe ProjectPresenter do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
allow(project).to receive(:auto_devops_enabled?).and_return(true)
|
allow(project).to receive(:auto_devops_enabled?).and_return(true)
|
||||||
|
|
||||||
expect(presenter.autodevops_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.autodevops_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Auto DevOps enabled',
|
label: a_string_including('Auto DevOps enabled'),
|
||||||
link: nil)
|
link: nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user can admin pipeline and CI yml does not exists' do
|
context 'when user can admin pipeline and CI yml does not exist' do
|
||||||
it 'returns anchor data' do
|
it 'returns anchor data' do
|
||||||
project.add_maintainer(user)
|
project.add_maintainer(user)
|
||||||
allow(project).to receive(:auto_devops_enabled?).and_return(false)
|
allow(project).to receive(:auto_devops_enabled?).and_return(false)
|
||||||
allow(project.repository).to receive(:gitlab_ci_yml).and_return(nil)
|
allow(project.repository).to receive(:gitlab_ci_yml).and_return(nil)
|
||||||
|
|
||||||
expect(presenter.autodevops_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.autodevops_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Enable Auto DevOps',
|
label: a_string_including('Enable Auto DevOps'),
|
||||||
link: presenter.project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
link: presenter.project_settings_ci_cd_path(project, anchor: 'autodevops-settings'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -380,8 +380,8 @@ describe ProjectPresenter do
|
||||||
project.add_maintainer(user)
|
project.add_maintainer(user)
|
||||||
cluster = create(:cluster, projects: [project])
|
cluster = create(:cluster, projects: [project])
|
||||||
|
|
||||||
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Kubernetes configured',
|
label: a_string_including('Kubernetes configured'),
|
||||||
link: presenter.project_cluster_path(project, cluster))
|
link: presenter.project_cluster_path(project, cluster))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -390,16 +390,16 @@ describe ProjectPresenter do
|
||||||
create(:cluster, :production_environment, projects: [project])
|
create(:cluster, :production_environment, projects: [project])
|
||||||
create(:cluster, projects: [project])
|
create(:cluster, projects: [project])
|
||||||
|
|
||||||
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(enabled: true,
|
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Kubernetes configured',
|
label: a_string_including('Kubernetes configured'),
|
||||||
link: presenter.project_clusters_path(project))
|
link: presenter.project_clusters_path(project))
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns link to create a cluster if no cluster exists' do
|
it 'returns link to create a cluster if no cluster exists' do
|
||||||
project.add_maintainer(user)
|
project.add_maintainer(user)
|
||||||
|
|
||||||
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(enabled: false,
|
expect(presenter.kubernetes_cluster_anchor_data).to have_attributes(is_link: false,
|
||||||
label: 'Add Kubernetes cluster',
|
label: a_string_including('Add Kubernetes cluster'),
|
||||||
link: presenter.new_project_cluster_path(project))
|
link: presenter.new_project_cluster_path(project))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,7 +23,7 @@ describe 'projects/_home_panel' do
|
||||||
it 'makes it possible to set notification level' do
|
it 'makes it possible to set notification level' do
|
||||||
render
|
render
|
||||||
|
|
||||||
expect(view).to render_template('shared/notifications/_button')
|
expect(view).to render_template('projects/buttons/_notifications')
|
||||||
expect(rendered).to have_selector('.notification-dropdown')
|
expect(rendered).to have_selector('.notification-dropdown')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue