Commit 8181f58d authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'master' into auto-pipelines-vue

* master: (35 commits)
  Adds back removed class in merge request pipelines table
  Fix dropdown icon alignment
  Simplify HTML of mini pipeline graph and dropdown Creates individual html for dropdown Adds simplified  CSS for the new dropdown Removes old CSS Improves dropdown item in Chrome, Firefox and Safari Use SCSS variables for colors. Fix scss linter errors Adds animation when the stage is hovered. Adds back tooltip on dropdown toggle Fixes broken tests additional css changes to get more into direction of mockups
  Adds CHANGELOG entry
  Removes unneeded `window` declaration
  Decreases font-size on login page
  Ensure internal Gitlab::Git references use the namespace
  Absorb gitlab_git
  Fix review comments.
  Add spec for note edit and fix one commented spec.
  Review fixes.
  Use gl.utils.isInViewport and improve gl.utils.animateToElement.
  Make sure elements share the same scope
  Hide edit warning element when form reverted.
  Remove unnecessary styling came from merge conflicts.
  Fix single note edit form specs.
  Separate edit form in Changes and Discussions tab.
  Fix warning styling for responsive design.
  Fix task list for single edit note widget changes.
  Fix notes spec.
  ...
parents e4da8b11 cd85baf5
......@@ -16,6 +16,8 @@ gem 'default_value_for', '~> 3.0.0'
gem 'mysql2', '~> 0.3.16', group: :mysql
gem 'pg', '~> 0.18.2', group: :postgres
gem 'rugged', '~> 0.24.0'
# Authentication libraries
gem 'devise', '~> 4.2'
gem 'doorkeeper', '~> 4.2.0'
......@@ -49,10 +51,6 @@ gem 'u2f', '~> 0.2.1'
# Browser detection
gem 'browser', '~> 2.2'
# Extracting information from a git repository
# Provide access to Gitlab::Git library
gem 'gitlab_git', '~> 10.7.0'
# LDAP Auth
# GitLab fork with several improvements to original library. For full list of changes
# see https://github.com/intridea/omniauth-ldap/compare/master...gitlabhq:master
......
......@@ -255,11 +255,6 @@ GEM
mime-types (>= 1.16, < 3)
posix-spawn (~> 0.3)
gitlab-markup (1.5.0)
gitlab_git (10.7.0)
activesupport (~> 4.0)
charlock_holmes (~> 0.7.3)
github-linguist (~> 4.7.0)
rugged (~> 0.24.0)
gitlab_omniauth-ldap (1.2.1)
net-ldap (~> 0.9)
omniauth (~> 1.0)
......@@ -857,7 +852,6 @@ DEPENDENCIES
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.5.0)
gitlab_git (~> 10.7.0)
gitlab_omniauth-ldap (~> 1.2.1)
gollum-lib (~> 4.2)
gollum-rugged_adapter (~> 0.4.2)
......@@ -942,6 +936,7 @@ DEPENDENCIES
rubocop-rspec (~> 1.5.0)
ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 0.16.2)
rugged (~> 0.24.0)
sanitize (~> 2.0)
sass-rails (~> 5.0.6)
scss_lint (~> 0.47.0)
......@@ -988,4 +983,4 @@ DEPENDENCIES
wikicloth (= 0.8.1)
BUNDLED WITH
1.13.6
1.13.7
......@@ -45,7 +45,7 @@
return fn(item);
}).filter(Boolean);
window.gl.environmentsList.EnvironmentsComponent = Vue.component('environment-component', {
gl.environmentsList.EnvironmentsComponent = Vue.component('environment-component', {
props: {
store: {
type: Object,
......@@ -55,7 +55,7 @@
},
components: {
'environment-item': window.gl.environmentsList.EnvironmentItem,
'environment-item': gl.environmentsList.EnvironmentItem,
},
data() {
......
......@@ -5,7 +5,7 @@
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
window.gl.environmentsList.ActionsComponent = Vue.component('actions-component', {
gl.environmentsList.ActionsComponent = Vue.component('actions-component', {
props: {
actions: {
type: Array,
......
......@@ -5,7 +5,7 @@
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
window.gl.environmentsList.ExternalUrlComponent = Vue.component('external-url-component', {
gl.environmentsList.ExternalUrlComponent = Vue.component('external-url-component', {
props: {
externalUrl: {
type: String,
......
......@@ -29,12 +29,12 @@
gl.environmentsList.EnvironmentItem = Vue.component('environment-item', {
components: {
'commit-component': window.gl.CommitComponent,
'actions-component': window.gl.environmentsList.ActionsComponent,
'external-url-component': window.gl.environmentsList.ExternalUrlComponent,
'stop-component': window.gl.environmentsList.StopComponent,
'rollback-component': window.gl.environmentsList.RollbackComponent,
'terminal-button-component': window.gl.environmentsList.TerminalButtonComponent,
'commit-component': gl.CommitComponent,
'actions-component': gl.environmentsList.ActionsComponent,
'external-url-component': gl.environmentsList.ExternalUrlComponent,
'stop-component': gl.environmentsList.StopComponent,
'rollback-component': gl.environmentsList.RollbackComponent,
'terminal-button-component': gl.environmentsList.TerminalButtonComponent,
},
props: {
......@@ -183,7 +183,7 @@
* @returns {String}
*/
createdDate() {
return window.gl.environmentsList.timeagoInstance.format(
return gl.environmentsList.timeagoInstance.format(
this.model.last_deployment.deployable.created_at,
);
},
......
......@@ -5,7 +5,7 @@
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
window.gl.environmentsList.RollbackComponent = Vue.component('rollback-component', {
gl.environmentsList.RollbackComponent = Vue.component('rollback-component', {
props: {
retryUrl: {
type: String,
......
......@@ -5,7 +5,7 @@
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
window.gl.environmentsList.StopComponent = Vue.component('stop-component', {
gl.environmentsList.StopComponent = Vue.component('stop-component', {
props: {
stopUrl: {
type: String,
......
......@@ -5,7 +5,7 @@
window.gl = window.gl || {};
window.gl.environmentsList = window.gl.environmentsList || {};
window.gl.environmentsList.TerminalButtonComponent = Vue.component('terminal-button-component', {
gl.environmentsList.TerminalButtonComponent = Vue.component('terminal-button-component', {
props: {
terminalPath: {
type: String,
......
......@@ -7,15 +7,17 @@
$(() => {
window.gl = window.gl || {};
if (window.gl.EnvironmentsListApp) {
window.gl.EnvironmentsListApp.$destroy(true);
if (gl.EnvironmentsListApp) {
gl.EnvironmentsListApp.$destroy(true);
}
const Store = window.gl.environmentsList.EnvironmentsStore;
const Store = gl.environmentsList.EnvironmentsStore;
window.gl.EnvironmentsListApp = new window.gl.environmentsList.EnvironmentsComponent({
gl.EnvironmentsListApp = new gl.environmentsList.EnvironmentsComponent({
el: document.querySelector('#environments-list-view'),
propsData: {
store: Store.create(),
},
});
});
......@@ -35,8 +35,8 @@
autosize(this.textarea);
// form and textarea event listeners
this.addEventListeners();
gl.text.init(this.form);
}
gl.text.init(this.form);
// hide discard button
this.form.find('.js-note-discard').hide();
return this.form.show();
......
......@@ -106,8 +106,9 @@
);
};
gl.utils.getPagePath = function() {
return $('body').data('page').split(':')[0];
gl.utils.getPagePath = function(index) {
index = index || 0;
return $('body').data('page').split(':')[index];
};
gl.utils.parseUrl = function (url) {
......@@ -127,6 +128,17 @@
return e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
};
gl.utils.scrollToElement = function($el) {
var top = $el.offset().top;
gl.navBarHeight = gl.navBarHeight || $('.navbar-gitlab').height();
gl.navLinksHeight = gl.navLinksHeight || $('.nav-links').height();
gl.mrTabsHeight = gl.mrTabsHeight || $('.merge-request-tabs').height();
return $('body, html').animate({
scrollTop: top - (gl.navBarHeight + gl.navLinksHeight + gl.mrTabsHeight)
}, 200);
};
})(window);
}).call(this);
/**
* CustomEvent support for IE
*/
if (typeof window.CustomEvent !== 'function') {
window.CustomEvent = function CustomEvent(e, params) {
const options = params || { bubbles: false, cancelable: false, detail: undefined };
const evt = document.createEvent('CustomEvent');
evt.initCustomEvent(e, options.bubbles, options.cancelable, options.detail);
return evt;
};
window.CustomEvent.prototype = window.Event.prototype;
}
......@@ -52,6 +52,12 @@
this.setupMainTargetNoteForm();
this.initTaskList();
this.collapseLongCommitList();
// We are in the Merge Requests page so we need another edit form for Changes tab
if (gl.utils.getPagePath(1) === 'merge_requests') {
$('.note-edit-form').clone()
.addClass('mr-note-edit-form').insertAfter('.note-edit-form');
}
}
Notes.prototype.addBinding = function() {
......@@ -63,7 +69,7 @@
// change note in UI after update
$(document).on("ajax:success", "form.edit-note", this.updateNote);
// Edit note link
$(document).on("click", ".js-note-edit", this.showEditForm);
$(document).on("click", ".js-note-edit", this.showEditForm.bind(this));
$(document).on("click", ".note-edit-cancel", this.cancelEdit);
// Reopen and close actions for Issue/MR combined with note form submit
$(document).on("click", ".js-comment-button", this.updateCloseButton);
......@@ -466,6 +472,7 @@
var $html, $note_li;
// Convert returned HTML to a jQuery object so we can modify it further
$html = $(note.html);
this.revertNoteEditForm();
gl.utils.localTimeAgo($('.js-timeago', $html));
$html.renderGFM();
$html.find('.js-task-list-container').taskList('enable');
......@@ -480,48 +487,56 @@
};
Notes.prototype.checkContentToAllowEditing = function($el) {
var initialContent = $el.find('.original-note-content').text().trim();
var currentContent = $el.find('.note-textarea').val();
var isAllowed = true;
if (currentContent === initialContent) {
this.removeNoteEditForm($el);
}
else {
var $buttons = $el.find('.note-form-actions');
var isWidgetVisible = gl.utils.isInViewport($el.get(0));
if (!isWidgetVisible) {
gl.utils.scrollToElement($el);
}
$el.find('.js-edit-warning').show();
isAllowed = false;
}
return isAllowed;
}
/*
Called in response to clicking the edit note link
Replaces the note text with the note edit form
Adds a data attribute to the form with the original content of the note for cancellations
*/
*/
Notes.prototype.showEditForm = function(e, scrollTo, myLastNote) {
var $noteText, done, form, note;
e.preventDefault();
note = $(this).closest(".note");
note.addClass("is-editting");
form = note.find(".note-edit-form");
form.addClass('current-note-edit-form');
// Show the attachment delete link
note.find(".js-note-attachment-delete").show();
done = function($noteText) {
var noteTextVal;
// Neat little trick to put the cursor at the end
noteTextVal = $noteText.val();
// Store the original note text in a data attribute to retrieve if a user cancels edit.
form.find('form.edit-note').data('original-note', noteTextVal);
return $noteText.val('').val(noteTextVal);
};
new GLForm(form);
if ((scrollTo != null) && (myLastNote != null)) {
// scroll to the bottom
// so the open of the last element doesn't make a jump
$('html, body').scrollTop($(document).height());
return $('html, body').animate({
scrollTop: myLastNote.offset().top - 150
}, 500, function() {
var $noteText;
$noteText = form.find(".js-note-text");
$noteText.focus();
return done($noteText);
});
} else {
$noteText = form.find('.js-note-text');
$noteText.focus();
return done($noteText);
var $target = $(e.target);
var $editForm = $(this.getEditFormSelector($target));
var $note = $target.closest('.note');
var $currentlyEditing = $('.note.is-editting:visible');
if ($currentlyEditing.length) {
var isEditAllowed = this.checkContentToAllowEditing($currentlyEditing);
if (!isEditAllowed) {
return;
}
}
$note.find('.js-note-attachment-delete').show();
$editForm.addClass('current-note-edit-form');
$note.addClass('is-editting');
this.putEditFormInPlace($target);
};
......@@ -532,19 +547,41 @@
*/
Notes.prototype.cancelEdit = function(e) {
var note;
e.preventDefault();
note = $(e.target).closest('.note');
var $target = $(e.target);
var note = $target.closest('.note');
note.find('.js-edit-warning').hide();
this.revertNoteEditForm($target);
return this.removeNoteEditForm(note);
};
Notes.prototype.revertNoteEditForm = function($target) {
$target = $target || $('.note.is-editting:visible');
var selector = this.getEditFormSelector($target);
var $editForm = $(selector);
$editForm.insertBefore('.notes-form');
$editForm.find('.js-comment-button').enable();
$editForm.find('.js-edit-warning').hide();
};
Notes.prototype.getEditFormSelector = function($el) {
var selector = '.note-edit-form:not(.mr-note-edit-form)';
if ($el.parents('#diffs').length) {
selector = '.note-edit-form.mr-note-edit-form';
}
return selector;
};
Notes.prototype.removeNoteEditForm = function(note) {
var form;
form = note.find(".current-note-edit-form");
note.removeClass("is-editting");
form.removeClass("current-note-edit-form");
var form = note.find('.current-note-edit-form');
note.removeClass('is-editting');
form.removeClass('current-note-edit-form');
form.find('.js-edit-warning').hide();
// Replace markdown textarea text with original note text.
return form.find(".js-note-text").val(form.find('form.edit-note').data('original-note'));
return form.find('.js-note-text').val(form.find('form.edit-note').data('original-note'));
};
......@@ -837,15 +874,44 @@
Notes.prototype.initTaskList = function() {
this.enableTaskList();
return $(document).on('tasklist:changed', '.note .js-task-list-container', this.updateTaskList);
return $(document).on('tasklist:changed', '.note .js-task-list-container', this.updateTaskList.bind(this));
};
Notes.prototype.enableTaskList = function() {
return $('.note .js-task-list-container').taskList('enable');
};
Notes.prototype.updateTaskList = function() {
return $('form', this).submit();
Notes.prototype.putEditFormInPlace = function($el) {
var $editForm = $(this.getEditFormSelector($el));
var $note = $el.closest('.note');
$editForm.insertAfter($note.find('.note-text'));
var $originalContentEl = $note.find('.original-note-content');
var originalContent = $originalContentEl.text().trim();
var postUrl = $originalContentEl.data('post-url');
var targetId = $originalContentEl.data('target-id');
var targetType = $originalContentEl.data('target-type');
new GLForm($editForm.find('form'));
$editForm.find('form').attr('action', postUrl);
$editForm.find('.js-form-target-id').val(targetId);
$editForm.find('.js-form-target-type').val(targetType);
$editForm.find('.js-note-text').focus().val(originalContent);
$editForm.find('.js-md-write-button').trigger('click');
$editForm.find('.referenced-users').hide();
}
Notes.prototype.updateTaskList = function(e) {
var $target = $(e.target);
var $list = $target.closest('.js-task-list-container');
var $editForm = $(this.getEditFormSelector($target));
var $note = $list.closest('.note');
this.putEditFormInPlace($list);
$editForm.find('#note_note').val($note.find('.original-task-list').val());
$('form', $list).submit();
};
Notes.prototype.updateNotesCount = function(updateCount) {
......
//= require xterm/encoding-indexes
//= require xterm/encoding
//= require xterm/xterm.js
//= require xterm/fit.js
//= require ./terminal.js
......
......@@ -4,8 +4,3 @@
color: $badge-color;
vertical-align: baseline;
}
.badge-dark {
background-color: $badge-bg-dark;
color: $badge-color-dark;
}
.centered-light-block {
text-align: center;
color: $gl-gray;
color: $gl-text-color;
margin: 20px;
}
.nothing-here-block {
text-align: center;
padding: 20px;
color: $gl-gray;
color: $gl-text-color;
font-weight: normal;
font-size: 14px;
line-height: 36px;
......@@ -29,7 +29,7 @@
margin-bottom: 0;
border-top: 1px solid $white-dark;
border-bottom: 1px solid $white-dark;
color: $gl-gray;
color: $gl-text-color;
&.oneline-block {
line-height: 42px;
......@@ -135,11 +135,11 @@
}
.cover-title {
color: $gl-header-color;
color: $gl-text-color;
font-size: 23px;
h1 {
color: $gl-gray-dark;
color: $gl-text-color;
margin-bottom: 6px;
font-size: 23px;
}
......@@ -153,7 +153,7 @@
p {
padding: 0 $gl-padding;
color: $gl-text-color-dark;
color: $gl-text-color;
}
}
......@@ -211,7 +211,7 @@
display: inline;
font-weight: normal;
font-size: 24px;
color: $gl-title-color;
color: $gl-text-color;
}
}
}
......
......@@ -88,7 +88,7 @@
}
@mixin btn-gray {
@include btn-color($gray-light, $border-gray-normal, $gray-normal, $border-gray-normal, $gray-dark, $border-gray-dark, $gl-gray-dark);
@include btn-color($gray-light, $border-gray-normal, $gray-normal, $border-gray-normal, $gray-dark, $border-gray-dark, $gl-text-color);
}
@mixin btn-white {
......@@ -242,7 +242,7 @@
}
.btn-transparent {
color: $gl-gray-light;
color: $gl-text-color-secondary;
background-color: transparent;
border: 0;
......@@ -338,7 +338,7 @@
margin-left: 10px;
i {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
......
......@@ -412,7 +412,7 @@ table {
padding: 0 10px;
clip: auto;
text-decoration: none;
color: $gl-title-color;
color: $gl-text-color;
background: $gray-light;
z-index: 1;
}
......
......@@ -201,7 +201,7 @@
}
.icon-play {
fill: $gl-gray-light;
fill: $gl-text-color-secondary;
margin-right: 6px;
height: 12px;
width: 11px;
......@@ -209,7 +209,7 @@
}
.dropdown-header {
color: $gl-gray-light;
color: $gl-text-color-secondary;
font-size: 13px;
line-height: 22px;
padding: 0 10px;
......@@ -222,7 +222,7 @@
.unclickable {
cursor: not-allowed;
padding: 5px 8px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
......@@ -592,7 +592,7 @@
}
.ui-datepicker-title {
color: $gl-gray;
color: $gl-text-color;
font-size: 14px;
line-height: 1;
font-weight: normal;
......@@ -614,17 +614,17 @@
.dropdown-menu-inner-title {
display: block;
color: $gl-title-color;
color: $gl-text-color;
font-weight: 600;
}
.dropdown-menu-inner-content {
display: block;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.dropdown-toggle-text {
&.is-default {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
......@@ -153,7 +153,7 @@ label {
}
.form-control::-webkit-input-placeholder {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.input-group {
......
......@@ -45,7 +45,7 @@ header {
padding: 0;
.nav > li > a {
color: $gl-gray-light;
color: $gl-text-color-secondary;
font-size: 18px;
padding: 0;
margin: ($header-height - 28) / 2 0;
......@@ -63,7 +63,7 @@ header {
&:focus,
&:active {
background-color: $gray-light;
color: darken($gl-gray-light, 30%);
color: darken($gl-text-color-secondary, 30%);
.todos-pending-count {
background: darken($todo-alert-blue, 10%);
......@@ -88,7 +88,7 @@ header {
}
&.active {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
}
......
......@@ -35,10 +35,10 @@
.ci-status-icon-canceled,
.ci-status-icon-disabled,
.ci-status-icon-not-found {
color: $gl-gray;
color: $gl-text-color;
svg {
fill: $gl-gray;
fill: $gl-text-color;
}
}
......
......@@ -41,6 +41,6 @@
}
&.status-box-upcoming {
background: $gl-gray-light;
background: $gl-text-color-secondary;
}
}
......@@ -128,7 +128,7 @@ ul.content-list {
}
a {
color: $gl-dark-link-color;
color: $gl-text-color;
}
.member-group-link {
......@@ -230,7 +230,7 @@ ul.content-list {
}
.label-default {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
......
......@@ -73,7 +73,7 @@
}
.referenced-users {
color: $gl-header-color;
color: $gl-text-color;
padding-top: 10px;
}
......@@ -135,7 +135,7 @@
.toolbar-btn {
float: left;
padding: 0 5px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
background: transparent;
border: 0;
outline: 0;
......
......@@ -46,7 +46,7 @@
&.light {
a {
color: $gl-gray;
color: $gl-text-color;
}
}
}
......
......@@ -51,7 +51,7 @@
margin-bottom: -1px;
font-size: 14px;
line-height: 28px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
border-bottom: 2px solid transparent;
&:hover,
......@@ -315,7 +315,7 @@
.fa-caret-down {
margin-left: 5px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.dropdown {
......
......@@ -14,7 +14,7 @@
.header-action-buttons {
i {
color: $gl-gray-light;
color: $gl-text-color-secondary;
font-size: 13px;
margin-right: 3px;
}
......@@ -42,7 +42,7 @@
.commit-committer-link,
.commit-author-link {
color: $gl-gray;
color: $gl-text-color;
font-weight: bold;
}
......
......@@ -7,7 +7,7 @@
.timeline-entry {
padding: $gl-padding $gl-btn-padding 11px;
border-color: $white-normal;
color: $gl-gray;
color: $gl-text-color;
border-bottom: 1px solid $border-white-light;
&:target {
......@@ -32,7 +32,7 @@
.system-note {
.note-text {
color: $gl-gray !important;
color: $gl-text-color !important;
}
}
......
......@@ -98,7 +98,7 @@
&.label-gray {
background-color: $label-gray-bg;
color: $gl-gray;
color: $gl-text-color;
text-shadow: none;
}
......
......@@ -65,11 +65,11 @@ $legend-color: $text-color;
//
//##
$pagination-color: $gl-gray;
$pagination-color: $gl-text-color;
$pagination-bg: $white-light;
$pagination-border: $border-color;
$pagination-hover-color: $gl-gray;
$pagination-hover-color: $gl-text-color;
$pagination-hover-bg: $row-hover;
$pagination-hover-border: $border-color;
......@@ -121,6 +121,9 @@ $panel-default-heading-bg: $gray-light;
$panel-footer-bg: $gray-light;
$panel-inner-border: $border-color;
$badge-bg: $badge-bg;
$badge-color: $badge-color;
//== Wells
//
//##
......@@ -154,7 +157,7 @@ $nav-link-padding: 13px $gl-padding;
//
//##
$pre-bg: $gray-light !default;
$pre-color: $gl-gray !default;
$pre-color: $gl-text-color !default;
$pre-border-color: $border-color;
$table-bg-accent: $gray-light;
@mixin md-typography {
color: $md-text-color;
color: $gl-text-color;
word-wrap: break-word;
a {
......@@ -50,14 +50,14 @@
margin: 16px 0 10px;
padding: 0 0 0.3em;
border-bottom: 1px solid $white-dark;
color: $gl-gray-dark;
color: $gl-text-color;
}
h2 {
font-size: 1.5em;
font-weight: 600;
margin: 16px 0 10px;
color: $gl-gray-dark;
color: $gl-text-color;
}
h3 {
......@@ -100,7 +100,7 @@
}
p {
color: $gl-text-color-dark;
color: $gl-text-color;
margin: 6px 0 0;
}
......@@ -108,7 +108,7 @@
@extend .table;
@extend .table-bordered;
margin: 12px 0;
color: $gl-text-color-dark;
color: $gl-text-color;
th {
background: $label-gray-bg;
......@@ -230,7 +230,7 @@ h3,
h4,
h5,
h6 {
color: $gl-title-color;
color: $gl-text-color;
font-weight: 600;
}
......@@ -292,7 +292,7 @@ h2,
h3,
h4 {
small {
color: $gl-gray;
color: $gl-text-color;
}
}
......
......@@ -94,29 +94,22 @@ $well-light-text-color: #5b6169;
* Text
*/
$gl-font-size: 14px;
$gl-title-color: #333;
$gl-text-color: #5c5c5c;
$gl-text-color-dark: #5c5d5e;
$gl-text-color-light: #8c8c8c;
$gl-text-color: rgba(0, 0, 0, .85);
$gl-text-color-secondary: rgba(0, 0, 0, .55);
$gl-text-color-disabled: rgba(0, 0, 0, .35);
$gl-text-green: #4a2;
$gl-text-red: #d12f19;
$gl-text-orange: #d90;
$gl-link-color: #3777b0;
$gl-diff-text-color: #555;
$gl-dark-link-color: #333;
$gl-gray-light: #8f8f8f;
$gl-grayish-blue: #7f8fa4;
$gl-gray: $gl-text-color;
$gl-gray-dark: #313236;
$gl-header-color: #4c4e54;
/*
* Lists
*/
$list-font-size: $gl-font-size;
$list-title-color: $gl-title-color;
$list-title-color: $gl-text-color;
$list-text-color: $gl-text-color;
$list-text-disabled-color: #888;
$list-text-disabled-color: $gl-text-color-disabled;
$list-border-light: #eee;
$list-border: rgba(0, 0, 0, 0.05);
$list-text-height: 42px;
......@@ -127,7 +120,6 @@ $list-warning-row-color: #8a6d3b;
/*
* Markdown
*/
$md-text-color: $gl-text-color;
$md-link-color: $gl-link-color;
$md-area-border: #ddd;
......@@ -168,9 +160,7 @@ $btn-side-margin: 10px;
$btn-sm-side-margin: 7px;
$btn-xs-side-margin: 5px;
$issue-status-expired: #cea61b;
$issuable-sidebar-color: #999;
$issuable-avatar-hover-border: #999;
$issuable-clipboard-color: #999;
$issuable-sidebar-color: $gl-text-color-secondary;
$show-aside-bg: #eee;
$show-aside-color: #777;
$show-aside-shadow: #ddd;
......@@ -282,10 +272,8 @@ $btn-active-gray-light: e4e7ed;
/*
* Badges
*/
$badge-bg: #f3f3f3;
$badge-bg-dark: #eee;
$badge-color: #929292;
$badge-color-dark: #8f8f8f;
$badge-bg: #eee;
$badge-color: $gl-text-color-secondary;
/*
* Award emoji
......@@ -304,8 +292,8 @@ $location-icon-color: #e7e9ed;
/*
* Notes
*/
$notes-light-color: #8e8e8e;
$notes-role-color: #8e8e8e;
$notes-light-color: $gl-text-color-secondary;
$notes-role-color: $gl-text-color-secondary;
$note-disabled-comment-color: #b2b2b2;
$note-targe3-outside: #fffff0;
$note-targe3-inside: #ffffd3;
......@@ -330,7 +318,7 @@ $calendar-user-contrib-text: #959494;
$cycle-analytics-box-padding: 30px;
$cycle-analytics-box-text-color: #8c8c8c;
$cycle-analytics-big-font: 19px;
$cycle-analytics-dark-text: $gl-title-color;
$cycle-analytics-dark-text: $gl-text-color;
$cycle-analytics-light-gray: #bfbfbf;
$cycle-analytics-dismiss-icon-color: #b2b2b2;
......@@ -382,7 +370,7 @@ $commit-message-text-area-bg: rgba(0, 0, 0, 0.0);
/*
* Common
*/
$common-gray: $gl-gray;
$common-gray: $gl-text-color;
$common-gray-light: #bbb;
$common-gray-dark: #444;
$common-red: $gl-text-red;
......@@ -537,3 +525,4 @@ Pipeline Graph
*/
$stage-hover-bg: #eaf3fc;
$stage-hover-border: #d1e7fc;
$action-icon-color: #d6d6d6;
.info-well {
background: $gray-light;
color: $gl-gray;
color: $gl-text-color;
border: 1px solid $border-color;
border-radius: $border-radius-default;
......
......@@ -40,7 +40,7 @@
}
.zen-control-full {
color: $gl-gray-light;
color: $gl-text-color-secondary;
&:hover {
color: $gl-link-color;
......
......@@ -3,7 +3,7 @@
/*
* White Syntax Colors
*/
$white-code-color: #333;
$white-code-color: $gl-text-color;
$white-highlight: #fafe3d;
$white-pre-hll-bg: #f8eec7;
$white-hll-bg: #f8f8f8;
......
......@@ -259,7 +259,7 @@
.board-list-count {
padding: 10px 0;
color: $gl-gray-light;
color: $gl-text-color-secondary;
font-size: 13px;
> .fa {
......
......@@ -29,7 +29,7 @@
padding-top: 6px;
padding-bottom: 0;
font-size: 12px;
color: $gl-title-color;
color: $gl-text-color;
display: block;
}
......
......@@ -160,7 +160,7 @@
flex: 1;
a {
color: $gl-gray;
color: $gl-text-color;
&:hover {
color: $gl-link-color;
......@@ -357,7 +357,7 @@
}
.build-light-text {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.build-gutter-toggle {
......
......@@ -18,7 +18,7 @@
}
td {
color: $gl-gray;
color: $gl-text-color;
vertical-align: middle !important;
a {
......
......@@ -19,7 +19,7 @@
.commit-title {
margin: 0;
color: $gl-gray-dark;
color: $gl-text-color;
}
.commit-description {
......@@ -96,14 +96,14 @@
}
.commit-row-message {
color: $gl-dark-link-color;
color: $gl-text-color;
}
}
.text-expander {
display: inline-block;
background: $gray-light;
color: $gl-gray-light;
color: $gl-text-color-secondary;
padding: 0 5px;
cursor: pointer;
border: 1px solid $border-gray-dark;
......@@ -153,7 +153,7 @@
a,
button {
color: $gl-dark-link-color;
color: $gl-text-color;
vertical-align: baseline;
}
......@@ -176,7 +176,7 @@
}
a {
color: $gl-dark-link-color;
color: $gl-text-color;
}
}
......@@ -193,7 +193,7 @@
}
.branch-commit {
color: $gl-gray;
color: $gl-text-color;
.commit-icon {
text-align: center;
......@@ -203,7 +203,7 @@
height: 14px;
width: 14px;
vertical-align: middle;
fill: $gl-gray-light;
fill: $gl-text-color-secondary;
}
}
......@@ -212,6 +212,6 @@
}
.commit-row-message {
color: $gl-gray;
color: $gl-text-color;
}
}
......@@ -111,14 +111,14 @@
line-height: 19px;
font-size: 14px;
font-weight: 600;
color: $gl-title-color;
color: $gl-text-color;
}
&.text {
color: $layout-link-gray;
&.value-col {
color: $gl-title-color;
color: $gl-text-color;
}
}
}
......@@ -260,7 +260,7 @@
.stage-empty,
.not-available {
color: $gl-text-color-light;
color: $gl-text-color-secondary;
}
}
}
......@@ -327,7 +327,7 @@
@include text-overflow();
a {
color: $gl-dark-link-color;
color: $gl-text-color;
}
}
}
......@@ -355,7 +355,7 @@
.issue-link,
.commit-author-link,
.issue-author-link {
color: $gl-dark-link-color;
color: $gl-text-color;
}
// Custom CSS for components
......@@ -396,11 +396,11 @@
}
.item-build-name {
color: $gl-title-color;
color: $gl-text-color;
}
.pipeline-id {
color: $gl-title-color;
color: $gl-text-color;
padding: 0 3px 0 0;
}
......@@ -423,7 +423,7 @@
}
.fa {
color: $gl-text-color-light;
color: $gl-text-color-secondary;
font-size: $code_font_size;
}
}
......@@ -435,7 +435,7 @@
width: 75%;
margin: 0 auto;
padding-top: 130px;
color: $gl-text-color-light;
color: $gl-text-color-secondary;
h4 {
color: $gl-text-color;
......
.detail-page-header {
padding: $gl-padding-top 0;
border-bottom: 1px solid $border-color;
color: $gl-text-color-dark;
color: $gl-text-color;
line-height: 34px;
.author {
color: $gl-text-color-dark;
color: $gl-text-color;
}
.identifier {
color: $gl-text-color-dark;
color: $gl-text-color;
}
.issue_created_ago,
......@@ -22,7 +22,7 @@
.title {
margin: 0 0 16px;
font-size: 2em;
color: $gl-gray-dark;
color: $gl-text-color;
padding: 0 0 0.3em;
border-bottom: 1px solid $white-dark;
}
......
......@@ -14,7 +14,7 @@
background: $gray-light;
border-bottom: 1px solid $border-color;
padding: 10px 16px;
color: $gl-diff-text-color;
color: $gl-text-color;
z-index: 10;
border-radius: 3px 3px 0 0;
......@@ -50,7 +50,7 @@
overflow: auto;
overflow-y: hidden;
background: $white-light;
color: $gl-title-color;
color: $gl-text-color;
border-radius: 0 0 3px 3px;
.unfold {
......@@ -380,7 +380,7 @@
}
cursor: default;
color: $gl-title-color;
color: $gl-text-color;
}
&.disabled {
......
......@@ -72,25 +72,25 @@
.external-url,
.dropdown-new {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.dropdown-menu {
.fa {
margin-right: 6px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
.build-link,
.branch-name {
color: $gl-dark-link-color;
color: $gl-text-color;
}
.stop-env-link,
.external-url {
color: $gl-gray-light;
color: $gl-text-color-secondary;
.stop-env-icon {
font-size: 14px;
......@@ -101,7 +101,7 @@
.build-column {
.build-link {
color: $gl-dark-link-color;
color: $gl-text-color;
}
.avatar {
......
......@@ -21,7 +21,7 @@
}
a {
color: $gl-dark-link-color;
color: $gl-text-color;
}
.avatar {
......
......@@ -13,7 +13,7 @@
.stats {
float: right;
line-height: $list-text-height;
color: $gl-gray;
color: $gl-text-color;
span {
margin-right: 15px;
......
......@@ -103,7 +103,7 @@
}
.edit-link {
color: $gl-gray;
color: $gl-text-color;
&:hover {
color: $md-link-color;
......@@ -139,7 +139,7 @@
}
.btn-clipboard:hover {
color: $gl-gray;
color: $gl-text-color;
}
}
......@@ -174,7 +174,7 @@
}
.no-value {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.sidebar-collapsed-icon {
......@@ -242,7 +242,7 @@
color: $issuable-sidebar-color;
&:hover {
color: $gl-gray;
color: $gl-text-color;
}
span {
......@@ -255,16 +255,16 @@
}
.avatar:hover {
border-color: $issuable-avatar-hover-border;
border-color: $issuable-sidebar-color;
}
.btn-clipboard {
border: none;
color: $issuable-clipboard-color;
color: $issuable-sidebar-color;
&:hover {
background: transparent;
color: $gl-gray;
color: $gl-text-color;
}
}
}
......@@ -338,7 +338,7 @@
margin-left: 5px;
a {
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
......
......@@ -117,7 +117,7 @@
.manage-labels-list {
.btn-action {
color: $gl-dark-link-color;
color: $gl-text-color;
.fa {
font-size: 18px;
......
......@@ -17,14 +17,19 @@
line-height: 1.5;
p {
font-size: 18px;
font-size: 16px;
color: $login-brand-holder-color;
}
h1:first-child {
font-weight: normal;
margin-bottom: 30px;
margin-bottom: 0.68em;
margin-top: 0;
font-size: 34px;
}
h3 {
font-size: 22px;
}
img {
......
......@@ -4,7 +4,7 @@
*/
.mr-state-widget {
background: $gray-light;
color: $gl-gray;
color: $gl-text-color;
border: 1px solid $border-color;
border-radius: 2px;
......@@ -58,7 +58,7 @@
padding-right: 0;
a {
color: $gl-gray;
color: $gl-text-color;
}
}
......@@ -70,7 +70,7 @@
.ci_widget {
border-bottom: 1px solid $well-inner-border;
color: $gl-gray;
color: $gl-text-color;
svg {
margin-right: 4px;
......@@ -94,7 +94,7 @@
}
.normal {
color: $gl-text-color-dark;
color: $gl-text-color;
}
.js-deployment-link {
......@@ -106,7 +106,7 @@
font-weight: 600;
font-size: 16px;
margin: 5px 0;
color: $gl-gray-dark;
color: $gl-text-color;
&.has-conflicts .fa-exclamation-triangle {
color: $gl-warning;
......@@ -190,7 +190,7 @@
}
.label-branch {
color: $gl-gray-dark;
color: $gl-text-color;
font-family: $monospace_font;
font-weight: bold;
overflow: hidden;
......@@ -363,7 +363,7 @@
th {
background-color: $white-light;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
}
}
......
......@@ -102,7 +102,7 @@
margin-top: 7px;
.issuable-number {
color: $gl-gray-light;
color: $gl-text-color-secondary;
margin-right: 5px;
}
......
......@@ -27,6 +27,7 @@
.new-note,
.note-edit-form {
.note-form-actions {
position: relative;
margin-top: $gl-padding;
}
......@@ -44,7 +45,7 @@
.note-textarea {
display: block;
padding: 10px 0;
color: $gl-gray;
color: $gl-text-color;
font-family: $regular_font;
border: 0;
......@@ -204,7 +205,7 @@
.comment-toolbar {
padding-top: $gl-padding-top;
color: $gl-gray-light;
color: $gl-text-color-secondary;
border-top: 1px solid $border-color;
}
......@@ -265,3 +266,18 @@
}
}
}
.note-edit-warning.settings-message {
display: none;
padding: 5px 10px;
position: absolute;
left: 127px;
top: 2px;
@media (max-width: $screen-xs-max) {
position: relative;
top: 0;
left: 0;
margin-bottom: 10px;
}
}
......@@ -345,7 +345,7 @@ ul.notes {
}
.author_link {
color: $gl-gray;
color: $gl-text-color;
}
}
......@@ -588,13 +588,11 @@ ul.notes {
// Merge request notes in diffs
.diff-file {
// Diff is side by side
.notes_content.parallel .note-header .note-headline-light {
display: block;
position: relative;
}
// Diff is inline
.notes_content .note-header .note-headline-light {
display: inline-block;
......
This diff is collapsed.
......@@ -292,7 +292,7 @@
.option-title {
font-weight: normal;
display: inline-block;
color: $gl-gray-dark;
color: $gl-text-color;
}
.option-descr {
......@@ -331,7 +331,7 @@
a.deploy-project-label {
padding: 5px;
margin-right: 5px;
color: $gl-gray;
color: $gl-text-color;
background-color: $row-hover;
&:hover {
......@@ -372,7 +372,7 @@ a.deploy-project-label {
}
a {
color: $gl-dark-link-color;
color: $gl-text-color;
}
.dropdown-menu {
......@@ -426,7 +426,7 @@ a.deploy-project-label {
width: 100%;
height: 100%;
padding-top: $gl-padding;
color: $gl-gray;
color: $gl-text-color;
.caption {
min-height: 30px;
......@@ -552,7 +552,7 @@ pre.light-well {
margin: 0 7px 7px;
h5 {
color: $gl-text-color-dark;
color: $gl-text-color;
}
.light-well {
......@@ -662,7 +662,7 @@ pre.light-well {
}
.commit-row-message {
color: $gl-gray;
color: $gl-text-color;
}
.commit_short_id {
......@@ -750,7 +750,7 @@ pre.light-well {
.protected-branches-list {
a {
color: $gl-gray;
color: $gl-text-color;
&:hover {
color: $gl-link-color;
......
.settings-list-icon {
color: $gl-gray-light;
color: $gl-text-color-secondary;
font-size: $settings-icon-size;
line-height: 42px;
}
......
......@@ -61,15 +61,15 @@
&.ci-canceled,
&.ci-disabled {
color: $gl-gray;
border-color: $gl-gray;
color: $gl-text-color;
border-color: $gl-text-color;
&:not(span):hover {
background-color: rgba($gl-gray, .07);
background-color: rgba($gl-text-color, .07);
}
svg {
fill: $gl-gray;
fill: $gl-text-color;
}
}
......@@ -101,15 +101,15 @@
&.ci-created,
&.ci-skipped {
color: $gl-gray-light;
border-color: $gl-gray-light;
color: $gl-text-color-secondary;
border-color: $gl-text-color-secondary;
&:not(span):hover {
background-color: rgba($gl-gray-light, .07);
background-color: rgba($gl-text-color-secondary, .07);
}
svg {
fill: $gl-gray-light;
fill: $gl-text-color-secondary;
}
}
......
......@@ -90,7 +90,7 @@
}
p {
color: $gl-text-color-dark;
color: $gl-text-color;
}
}
......
......@@ -78,7 +78,7 @@
i,
a {
color: $gl-dark-link-color;
color: $gl-text-color;
}
img {
......@@ -104,21 +104,21 @@
padding-right: 8px;
.commit-author-name {
color: $gl-gray;
color: $gl-text-color;
}
}
.tree-time-ago {
min-width: 135px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.tree-commit {
max-width: 320px;
color: $gl-gray-light;
color: $gl-text-color-secondary;
.tree-commit-link {
color: $gl-gray-light;
color: $gl-text-color-secondary;
&:hover {
text-decoration: underline;
......
......@@ -15,7 +15,7 @@
}
.wiki-last-edit-by {
color: $gl-gray-light;
color: $gl-text-color-secondary;
strong {
color: $gl-text-color;
......@@ -24,7 +24,7 @@
.light {
font-weight: normal;
color: $gl-gray-light;
color: $gl-text-color-secondary;
}
.git-access-header {
......
class MergeRequestDiff < ActiveRecord::Base
include Sortable
include Importable
include EncodingHelper
include Gitlab::Git::EncodingHelper
# Prevent store of diff if commits amount more then 500
COMMITS_SAFE_SIZE = 100
......
-# Renders the content of each li in the dropdown
- subject = local_assigns.fetch(:subject)
- status = subject.detailed_status(current_user)
- klass = "ci-status-icon ci-status-icon-#{status.group}"
- tooltip = "#{subject.name} - #{status.label}"
- if status.has_details?
= link_to status.details_path, class: 'mini-pipeline-graph-dropdown-item', data: { toggle: 'tooltip', title: tooltip } do
%span{ class: klass }= custom_icon(status.icon)
%span.ci-build-text= subject.name
- else
.mini-pipeline-graph-dropdown-item{ data: { toggle: 'tooltip', title: tooltip } }
%span{ class: klass }= custom_icon(status.icon)
%span.ci-build-text= subject.name
- if status.has_action?
= link_to status.action_path, class: 'ci-action-icon-wrapper js-ci-action-icon', method: status.action_method, data: { toggle: 'tooltip', title: status.action_title } do
= icon(status.action_icon, class: status.action_class)
......@@ -31,7 +31,7 @@
= link_to admin_abuse_reports_path, title: "Abuse Reports" do
%span
Abuse Reports
%span.badge.badge-dark.count= number_with_delimiter(AbuseReport.count(:all))
%span.badge.count= number_with_delimiter(AbuseReport.count(:all))
- if askimet_enabled?
= nav_link(controller: :spam_logs) do
......
......@@ -26,13 +26,13 @@
%span
Issues
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
%span.badge.badge-dark.count= number_with_delimiter(issues.count)
%span.badge.count= number_with_delimiter(issues.count)
= nav_link(path: 'groups#merge_requests') do
= link_to merge_requests_group_path(@group), title: 'Merge Requests' do
%span
Merge Requests
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened', non_archived: true).execute
%span.badge.badge-dark.count= number_with_delimiter(merge_requests.count)
%span.badge.count= number_with_delimiter(merge_requests.count)
= nav_link(controller: [:group_members]) do
= link_to group_group_members_path(@group), title: 'Members' do
%span
......
......@@ -61,14 +61,14 @@
%span
Issues
- if @project.default_issues_tracker?
%span.badge.badge-dark.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count)
%span.badge.count.issue_counter= number_with_delimiter(IssuesFinder.new(current_user, project_id: @project.id).execute.opened.count)
- if project_nav_tab? :merge_requests
= nav_link(controller: :merge_requests) do
= link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
%span
Merge Requests
%span.badge.badge-dark.count.merge_counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count)
%span.badge.count.merge_counter= number_with_delimiter(MergeRequestsFinder.new(current_user, project_id: @project.id).execute.opened.count)
- if project_nav_tab? :wiki
= nav_link(controller: :wikis) do
......
......@@ -47,21 +47,18 @@
- icon_status = "#{detailed_status.icon}_borderless"
- status_klass = "ci-status-icon ci-status-icon-#{detailed_status.group}"
.stage-container.mini-pipeline-graph
.dropdown.inline.build-content
%button.has-tooltip.builds-dropdown.js-builds-dropdown-button{ type: 'button', data: { toggle: 'dropdown', title: "#{stage.name}: #{detailed_status.label}", placement: 'top', "stage-endpoint" => stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: stage.name) } }
%span.has-tooltip{ class: status_klass }
%span.mini-pipeline-graph-icon-container
%span{ class: status_klass }= custom_icon(icon_status)
= icon('caret-down', class: 'dropdown-caret')
.stage-container.dropdown.js-mini-pipeline-graph
%button.mini-pipeline-graph-dropdown-toggle.has-tooltip.js-builds-dropdown-button{ class: "ci-status-icon-#{detailed_status.group}", type: 'button', data: { toggle: 'dropdown', title: "#{stage.name}: #{detailed_status.label}", placement: 'top', "stage-endpoint" => stage_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline, stage: stage.name) } }
= custom_icon(icon_status)
= icon('caret-down')
.js-builds-dropdown-container
.dropdown-menu.grouped-pipeline-dropdown
.arrow-up
.js-builds-dropdown-list
%ul.dropdown-menu.mini-pipeline-graph-dropdown-menu.js-builds-dropdown-container
.arrow-up
.js-builds-dropdown-list.scrollable-menu
.js-builds-dropdown-loading.builds-dropdown-loading.hidden
%span.fa.fa-spinner.fa-spin
.js-builds-dropdown-loading.builds-dropdown-loading.hidden
%span.fa.fa-spinner.fa-spin
%td
- if pipeline.duration
......
%ul.content-list.pipelines
%div
- if pipelines.blank?
%li
%div
.nothing-here-block No pipelines to show
- else
.table-holder
.table-holder.pipelines
%table.table.ci-table.js-pipeline-table
%thead
%th.pipeline-status Status
......
.note-edit-form
= form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true, html: { class: 'edit-note common-note-form js-quick-submit' } do |f|
= note_target_fields(note)
= render layout: 'projects/md_preview', locals: { preview_class: 'md-preview' } do
= render 'projects/zen', f: f, attr: :note, classes: 'note-textarea js-note-text js-task-list-field', placeholder: "Write a comment or drag your files here..."
= form_tag '#', method: :put, remote: true, class: 'edit-note common-note-form js-quick-submit' do
= hidden_field_tag :authenticity_token, form_authenticity_token
= hidden_field_tag :target_id, '', class: 'js-form-target-id'
= hidden_field_tag :target_type, '', class: 'js-form-target-type'
= render layout: 'projects/md_preview', locals: { preview_class: 'md-preview', referenced_users: true } do
= render 'projects/zen', attr: 'note[note]', classes: 'note-textarea js-note-text js-task-list-field', placeholder: "Write a comment or drag your files here..."
= render 'projects/notes/hints'
.note-form-actions.clearfix
= f.submit 'Save Comment', class: 'btn btn-nr btn-save js-comment-button'
.settings-message.note-edit-warning.js-edit-warning
Finish editing this message first!
= submit_tag 'Save Comment', class: 'btn btn-nr btn-save js-comment-button'
%button.btn.btn-nr.btn-cancel.note-edit-cancel{ type: 'button' }
Cancel
......@@ -67,7 +67,9 @@
= note.redacted_note_html
= edited_time_ago_with_tooltip(note, placement: 'bottom', html_class: 'note_edited_ago', include_author: true)
- if note_editable
= render 'projects/notes/edit_form', note: note
.original-note-content.hidden{ data: { post_url: namespace_project_note_path(@project.namespace, @project, note), target_id: note.noteable.id, target_type: note.noteable.class.name.underscore } }
#{note.note}
%textarea.hidden.js-task-list-field.original-task-list #{note.note}
.note-awards
= render 'award_emoji/awards_block', awardable: note, inline: false
- if note.system
......
%ul#notes-list.notes.main-notes-list.timeline
= render "projects/notes/notes"
= render 'projects/notes/edit_form'
%ul.notes.notes-form.timeline
%li.timeline-entry
.flash-container.timeline-content
......
%ul
- @stage.statuses.latest.each do |status|
%li.dropdown-build
= render 'ci/status/graph_badge', subject: status
- @stage.statuses.latest.each do |status|
%li
= render 'ci/status/dropdown_graph_badge', subject: status
......@@ -5,9 +5,10 @@
%span.ci-status-text
= name
%span.dropdown-counter-badge= subject.size
.dropdown-menu.grouped-pipeline-dropdown
%ul.dropdown-menu.big-pipeline-graph-dropdown-menu.js-grouped-pipeline-dropdown
.arrow
%ul
.scrollable-menu
- subject.each do |status|
%li.dropdown-build
= render 'ci/status/graph_badge', subject: status
%li
= render 'ci/status/dropdown_graph_badge', subject: status
---
title: Allow group and project paths when transferring projects via the API
merge_request:
author:
---
title: 25701 standardize text colors
merge_request:
author:
---
title: Removes unneeded `window` declaration in environments related code
merge_request: 8456
author:
---
title: Fix Commits API to accept a Project path upon POST
merge_request:
author:
---
title: Removes invalid html and unneed CSS to prevent shaking in the pipelines tab
merge_request: 8411
author:
---
title: Decreases font-size on login page
merge_request:
author:
---
title: Fixes and Improves CSS and HTML problems in mini pipeline graph and builds dropdown
merge_request: 8443
author:
---
title: Refactored note edit form to improve frontend performance on MR and Issues
pages, especially pages with has a lot of discussions in it
merge_request: 8356
author:
......@@ -2,6 +2,12 @@ Rails.application.configure do |config|
config.middleware.use(Gitlab::Middleware::Multipart)
end
# The Gitlab::Middleware::Multipart middleware inserts instances of our
# own ::UploadedFile class in the Rack env of requests. These instances
# will be blocked by the 'strong parameters' feature of ActionController
# unless we somehow whitelist them. At the moment it seems the only way
# to do that is by monkey-patching.
#
module Gitlab
module StrongParameterScalars
GITLAB_PERMITTED_SCALAR_TYPES = [::UploadedFile]
......
......@@ -335,7 +335,7 @@ POST /groups/:id/projects/:project_id
Parameters:
- `id` (required) - The ID or path of a group
- `project_id` (required) - The ID of a project
- `project_id` (required) - The ID or path of a project
## Update group
......
......@@ -58,6 +58,13 @@ GitLab uses Font Awesome icons throughout our interface.
| ![Red](img/color-red.png) | Closed | Delete and other destructive commands |
| ![Grey](img/color-grey.png) | Neutral | Neutral secondary commands |
### Text colors
|||
| :---: | :--- |
| ![Text primary](img/color-textprimary.png) | Used for primary body text, such as issue description and comment |
| ![Text secondary](img/color-textsecondary.png) | Used for secondary body text, such as username and date |
> TODO: Establish a perspective for color in terms of our personality and rationalize with Marketing usage.
---
......
......@@ -12,6 +12,7 @@
* [Panels](#panels)
* [Alerts](#alerts)
* [Forms](#forms)
* [Search box](#search-box)
* [File holders](#file-holders)
* [Data formats](#data-formats)
......@@ -215,6 +216,18 @@ Horizontal form (`form.horizontal-form`) with label rendered inline with input.
---
## Search box
Search boxes across GitLab have a consistent rest, active and text entered state. When text isn't entered in the box, there should be a magnifying glass right aligned with the input field. When text is entered, the magnifying glass should become a x, allowing users to clear their text.
![Search box](img/components-searchbox.png)
If needed, we indicate the scope of the search in the search box.
![Scoped Search box](img/components-searchboxscoped.png)
---
## File holders
A file holder (`.file-holder`) is used to show the contents of a file inline on a page of GitLab.
......
@admin
Feature: Admin Deploy Keys
Background:
Given I sign in as an admin
And there are public deploy keys in system
Scenario: Deploy Keys list
When I visit admin deploy keys page
Then I should see all public deploy keys
Scenario: Deploy Keys new
When I visit admin deploy keys page
And I click 'New Deploy Key'
And I submit new deploy key
Then I should be on admin deploy keys page
And I should see newly created deploy key without write access
Scenario: Deploy Keys new with write access
When I visit admin deploy keys page
And I click 'New Deploy Key'
And I submit new deploy key with write access
Then I should be on admin deploy keys page
And I should see newly created deploy key with write access
class Spinach::Features::AdminDeployKeys < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedAdmin
step 'there are public deploy keys in system' do
create(:deploy_key, public: true)
create(:another_deploy_key, public: true)
end
step 'I should see all public deploy keys' do
DeployKey.are_public.each do |p|
expect(page).to have_content p.title
end
end
step 'I visit admin deploy key page' do
visit admin_deploy_key_path(deploy_key)
end
step 'I visit admin deploy keys page' do
visit admin_deploy_keys_path
end
step 'I click \'New Deploy Key\'' do
click_link 'New Deploy Key'
end
step 'I submit new deploy key' do
fill_in "deploy_key_title", with: "laptop"
fill_in "deploy_key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop"
click_button "Create"
end
step 'I submit new deploy key with write access' do
fill_in "deploy_key_title", with: "server"
fill_in "deploy_key_key", with: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzrEJUIR6Y03TCE9rIJ+GqTBvgb8t1jI9h5UBzCLuK4VawOmkLornPqLDrGbm6tcwM/wBrrLvVOqi2HwmkKEIecVO0a64A4rIYScVsXIniHRS6w5twyn1MD3sIbN+socBDcaldECQa2u1dI3tnNVcs8wi77fiRe7RSxePsJceGoheRQgC8AZ510UdIlO+9rjIHUdVN7LLyz512auAfYsgx1OfablkQ/XJcdEwDNgi9imI6nAXhmoKUm1IPLT2yKajTIC64AjLOnE0YyCh6+7RFMpiMyu1qiOCpdjYwTgBRiciNRZCH8xIedyCoAmiUgkUT40XYHwLuwiPJICpkAzp7Q== user@laptop"
check "deploy_key_can_push"
click_button "Create"
end
step 'I should be on admin deploy keys page' do
expect(current_path).to eq admin_deploy_keys_path
end
step 'I should see newly created deploy key without write access' do
expect(page).to have_content(deploy_key.title)
expect(page).to have_content('No')
end
step 'I should see newly created deploy key with write access' do
expect(page).to have_content(deploy_key.title)
expect(page).to have_content('Yes')
end
def deploy_key
@deploy_key ||= DeployKey.are_public.first
end
end
......@@ -44,7 +44,6 @@ module API
detail 'This feature was introduced in GitLab 8.13'
end
params do
requires :id, type: Integer, desc: 'The project ID'
requires :branch_name, type: String, desc: 'The name of branch'
requires :commit_message, type: String, desc: 'Commit message'
requires :actions, type: Array[Hash], desc: 'Actions to perform in commit'
......
......@@ -156,12 +156,12 @@ module API
success Entities::GroupDetail
end
params do
requires :project_id, type: String, desc: 'The ID of the project'
requires :project_id, type: String, desc: 'The ID or path of the project'
end
post ":id/projects/:project_id" do
authenticated_as_admin!
group = Group.find_by(id: params[:id])
project = Project.find(params[:project_id])
group = find_group!(params[:id])
project = find_project!(params[:project_id])
result = ::Projects::TransferService.new(project, current_user).execute(group)
if result
......
......@@ -543,6 +543,13 @@ module API
type: String,
desc: 'The Mattermost token'
}
],
'slack-slash-commands' => [
{
name: :token,
type: String,
desc: 'The Slack token'
}
]
}.freeze
......
module Gitlab
module Git
# Class for parsing Git attribute files and extracting the attributes for
# file patterns.
#
# Unlike Rugged this parser only needs a single IO call (a call to `open`),
# vastly reducing the time spent in extracting attributes.
#
# This class _only_ supports parsing the attributes file located at
# `$GIT_DIR/info/attributes` as GitLab doesn't use any other files
# (`.gitattributes` is copied to this particular path).
#
# Basic usage:
#
# attributes = Gitlab::Git::Attributes.new(some_repo.path)
#
# attributes.attributes('README.md') # => { "eol" => "lf }
class Attributes
# path - The path to the Git repository.
def initialize(path)
@path = File.expand_path(path)
@patterns = nil
end
# Returns all the Git attributes for the given path.
#
# path - A path to a file for which to get the attributes.
#
# Returns a Hash.
def attributes(path)
full_path = File.join(@path, path)
patterns.each do |pattern, attrs|
return attrs if File.fnmatch?(pattern, full_path)
end
{}
end
# Returns a Hash containing the file patterns and their attributes.
def patterns
@patterns ||= parse_file
end
# Parses an attribute string.
#
# These strings can be in the following formats:
#
# text # => { "text" => true }
# -text # => { "text" => false }
# key=value # => { "key" => "value" }
#
# string - The string to parse.
#
# Returns a Hash containing the attributes and their values.
def parse_attributes(string)
values = {}
dash = '-'
equal = '='
binary = 'binary'
string.split(/\s+/).each do |chunk|
# Data such as "foo = bar" should be treated as "foo" and "bar" being
# separate boolean attributes.
next if chunk == equal
key = chunk
# Input: "-foo"
if chunk.start_with?(dash)
key = chunk.byteslice(1, chunk.length - 1)
value = false
# Input: "foo=bar"
elsif chunk.include?(equal)
key, value = chunk.split(equal, 2)
# Input: "foo"
else
value = true
end
values[key] = value
# When the "binary" option is set the "diff" option should be set to
# the inverse. If "diff" is later set it should overwrite the
# automatically set value.
values['diff'] = false if key == binary && value
end
values
end
# Iterates over every line in the attributes file.
def each_line
full_path = File.join(@path, 'info/attributes')
return unless File.exist?(full_path)
File.open(full_path, 'r') do |handle|
handle.each_line do |line|
break unless line.valid_encoding?
yield line.strip
end
end
end
private
# Parses the Git attributes file.
def parse_file
pairs = []
comment = '#'
each_line do |line|
next if line.start_with?(comment) || line.empty?
pattern, attrs = line.split(/\s+/, 2)
parsed = attrs ? parse_attributes(attrs) : {}
pairs << [File.join(@path, pattern), parsed]
end
# Newer entries take precedence over older entries.
pairs.reverse.to_h
end
end
end
end
require_relative 'encoding_helper'
module Gitlab
module Git
class Blame
include Gitlab::Git::EncodingHelper
attr_reader :lines, :blames
def initialize(repository, sha, path)
@repo = repository
@sha = sha
@path = path
@lines = []
@blames = load_blame
end
def each
@blames.each do |blame|
yield(
Gitlab::Git::Commit.new(blame.commit),
blame.line
)
end
end
private
def load_blame
cmd = %W(git --git-dir=#{@repo.path} blame -p #{@sha} -- #{@path})
# Read in binary mode to ensure ASCII-8BIT
raw_output = IO.popen(cmd, 'rb') {|io| io.read }
output = encode_utf8(raw_output)
process_raw_blame output
end
def process_raw_blame(output)
lines, final = [], []
info, commits = {}, {}
# process the output
output.split("\n").each do |line|
if line[0, 1] == "\t"
lines << line[1, line.size]
elsif m = /^(\w{40}) (\d+) (\d+)/.match(line)
commit_id, old_lineno, lineno = m[1], m[2].to_i, m[3].to_i
commits[commit_id] = nil unless commits.key?(commit_id)
info[lineno] = [commit_id, old_lineno]
end
end
# load all commits in single call
commits.keys.each do |key|
commits[key] = @repo.lookup(key)
end
# get it together
info.sort.each do |lineno, (commit_id, old_lineno)|
commit = commits[commit_id]
final << BlameLine.new(lineno, old_lineno, commit, lines[lineno - 1])
end
@lines = final
end
end
class BlameLine
attr_accessor :lineno, :oldlineno, :commit, :line
def initialize(lineno, oldlineno, commit, line)
@lineno = lineno
@oldlineno = oldlineno
@commit = commit
@line = line
end
end
end
end
This diff is collapsed.
module Gitlab
module Git
class BlobSnippet
include Linguist::BlobHelper
attr_accessor :ref
attr_accessor :lines
attr_accessor :filename
attr_accessor :startline
def initialize(ref, lines, startline, filename)
@ref, @lines, @startline, @filename = ref, lines, startline, filename
end
def data
lines.join("\n") if lines
end
def name
filename
end
def size
data.length
end
def mode
nil
end
end
end
end
module Gitlab
module Git
class Branch < Ref
end
end
end
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment