Commit a4fa44ce authored by Achilleas Pipinellis's avatar Achilleas Pipinellis

Merge branch 'master' into 'docs/change-docs-reviewers'

# Conflicts:
#   doc/development/doc_styleguide.md
parents 5174b7ad 195c1057
...@@ -99,7 +99,7 @@ update-knapsack: ...@@ -99,7 +99,7 @@ update-knapsack:
- export KNAPSACK_REPORT_PATH=knapsack/spinach_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json - export KNAPSACK_REPORT_PATH=knapsack/spinach_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
- export KNAPSACK_GENERATE_REPORT=true - export KNAPSACK_GENERATE_REPORT=true
- cp knapsack/spinach_report.json ${KNAPSACK_REPORT_PATH} - cp knapsack/spinach_report.json ${KNAPSACK_REPORT_PATH}
- knapsack spinach "-r rerun" || retry '[ ! -e tmp/spinach-rerun.txt ] || bundle exec spinach -r rerun $(cat tmp/spinach-rerun.txt)' - knapsack spinach "-r rerun" || retry '[[ -e tmp/spinach-rerun.txt ]] && bundle exec spinach -r rerun $(cat tmp/spinach-rerun.txt)'
artifacts: artifacts:
expire_in: 31d expire_in: 31d
paths: paths:
......
See the general Documentation guidelines http://docs.gitlab.com/ce/development/doc_styleguide.html. See the general Documentation guidelines http://docs.gitlab.com/ce/development/doc_styleguide.html
## What does this MR do? ## What does this MR do?
......
...@@ -61,7 +61,7 @@ linters: ...@@ -61,7 +61,7 @@ linters:
# Separate rule, function, and mixin declarations with empty lines. # Separate rule, function, and mixin declarations with empty lines.
EmptyLineBetweenBlocks: EmptyLineBetweenBlocks:
enabled: false enabled: true
# Reports when you have an empty rule set. # Reports when you have an empty rule set.
EmptyRule: EmptyRule:
...@@ -219,7 +219,7 @@ linters: ...@@ -219,7 +219,7 @@ linters:
# Property values, @extend, @include, and @import directives, and variable # Property values, @extend, @include, and @import directives, and variable
# declarations should always end with a semicolon. # declarations should always end with a semicolon.
TrailingSemicolon: TrailingSemicolon:
enabled: false enabled: true
# Reports lines containing trailing whitespace. # Reports lines containing trailing whitespace.
TrailingWhitespace: TrailingWhitespace:
......
...@@ -4,6 +4,8 @@ v 8.13.0 (unreleased) ...@@ -4,6 +4,8 @@ v 8.13.0 (unreleased)
- Improve Merge When Build Succeeds triggers and execute on pipeline success. (!6675) - Improve Merge When Build Succeeds triggers and execute on pipeline success. (!6675)
- Respond with 404 Not Found for non-existent tags (Linus Thiel) - Respond with 404 Not Found for non-existent tags (Linus Thiel)
- Truncate long labels with ellipsis in labels page - Truncate long labels with ellipsis in labels page
- Improve tabbing usability for sign in page (ClemMakesApps)
- Enforce TrailingSemicolon and EmptyLineBetweenBlocks in scss-lint
- Adding members no longer silently fails when there is extra whitespace - Adding members no longer silently fails when there is extra whitespace
- Update runner version only when updating contacted_at - Update runner version only when updating contacted_at
- Add link from system note to compare with previous version - Add link from system note to compare with previous version
...@@ -14,6 +16,7 @@ v 8.13.0 (unreleased) ...@@ -14,6 +16,7 @@ v 8.13.0 (unreleased)
- Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun) - Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun)
- Updating verbiage on git basics to be more intuitive - Updating verbiage on git basics to be more intuitive
- Clarify documentation for Runners API (Gennady Trafimenkov) - Clarify documentation for Runners API (Gennady Trafimenkov)
- The instrumentation for Banzai::Renderer has been restored
- Change user & group landing page routing from /u/:username to /:username - Change user & group landing page routing from /u/:username to /:username
- Prevent running GfmAutocomplete setup for each diff note !6569 - Prevent running GfmAutocomplete setup for each diff note !6569
- Added documentation for .gitattributes files - Added documentation for .gitattributes files
...@@ -24,6 +27,7 @@ v 8.13.0 (unreleased) ...@@ -24,6 +27,7 @@ v 8.13.0 (unreleased)
- Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar) - Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar)
- Speed-up group milestones show page - Speed-up group milestones show page
- Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps) - Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps)
- Extract project#update_merge_requests and SystemHooks to its own worker from GitPushService
- Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs) - Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs)
- Add tag shortcut from the Commit page. !6543 - Add tag shortcut from the Commit page. !6543
- Keep refs for each deployment - Keep refs for each deployment
...@@ -50,6 +54,7 @@ v 8.13.0 (unreleased) ...@@ -50,6 +54,7 @@ v 8.13.0 (unreleased)
- Add new issue button to each list on Issues Board - Add new issue button to each list on Issues Board
- Added soft wrap button to repository file/blob editor - Added soft wrap button to repository file/blob editor
- Update namespace validation to forbid reserved names (.git and .atom) (Will Starms) - Update namespace validation to forbid reserved names (.git and .atom) (Will Starms)
- Show the time ago a merge request was deployed to an environment
- Add word-wrap to issue title on issue and milestone boards (ClemMakesApps) - Add word-wrap to issue title on issue and milestone boards (ClemMakesApps)
- Fix todos page mobile viewport layout (ClemMakesApps) - Fix todos page mobile viewport layout (ClemMakesApps)
- Fix inconsistent highlighting of already selected activity nav-links (ClemMakesApps) - Fix inconsistent highlighting of already selected activity nav-links (ClemMakesApps)
...@@ -112,10 +117,12 @@ v 8.13.0 (unreleased) ...@@ -112,10 +117,12 @@ v 8.13.0 (unreleased)
- Fixes padding in all clipboard icons that have .btn class - Fixes padding in all clipboard icons that have .btn class
- Fix a typo in doc/api/labels.md - Fix a typo in doc/api/labels.md
- API: all unknown routing will be handled with 404 Not Found - API: all unknown routing will be handled with 404 Not Found
- Add docs for request profiling
- Make guests unable to view MRs on private projects - Make guests unable to view MRs on private projects
v 8.12.7 v 8.12.7
- Use gitlab-markup gem instead of github-markup to fix `.rst` file rendering. !6659 - Use gitlab-markup gem instead of github-markup to fix `.rst` file rendering. !6659
- Fix GFM autocomplete setup being called several times
v 8.12.6 v 8.12.6
- Update mailroom to 0.8.1 in Gemfile.lock !6814 - Update mailroom to 0.8.1 in Gemfile.lock !6814
...@@ -263,6 +270,7 @@ v 8.12.0 ...@@ -263,6 +270,7 @@ v 8.12.0
- Remove prefixes from transition CSS property (ClemMakesApps) - Remove prefixes from transition CSS property (ClemMakesApps)
- Add Sentry logging to API calls - Add Sentry logging to API calls
- Add BroadcastMessage API - Add BroadcastMessage API
- Merge request tabs are fixed when scrolling page
- Use 'git update-ref' for safer web commits !6130 - Use 'git update-ref' for safer web commits !6130
- Sort pipelines requested through the API - Sort pipelines requested through the API
- Automatically expand hidden discussions when accessed by a permalink !5585 (Mike Greiling) - Automatically expand hidden discussions when accessed by a permalink !5585 (Mike Greiling)
...@@ -369,6 +377,7 @@ v 8.11.7 ...@@ -369,6 +377,7 @@ v 8.11.7
- Avoid conflict with admin labels when importing GitHub labels. !6158 - Avoid conflict with admin labels when importing GitHub labels. !6158
- Restores `fieldName` to allow only string values in `gl_dropdown.js`. !6234 - Restores `fieldName` to allow only string values in `gl_dropdown.js`. !6234
- Allow the Rails cookie to be used for API authentication. - Allow the Rails cookie to be used for API authentication.
- Login/Register UX upgrade !6328
v 8.11.6 v 8.11.6
- Fix unnecessary horizontal scroll area in pipeline visualizations. !6005 - Fix unnecessary horizontal scroll area in pipeline visualizations. !6005
......
...@@ -15,18 +15,17 @@ ...@@ -15,18 +15,17 @@
this.hideSidebar = bind(this.hideSidebar, this); this.hideSidebar = bind(this.hideSidebar, this);
this.toggleSidebar = bind(this.toggleSidebar, this); this.toggleSidebar = bind(this.toggleSidebar, this);
this.updateDropdown = bind(this.updateDropdown, this); this.updateDropdown = bind(this.updateDropdown, this);
this.$document = $(document);
clearInterval(Build.interval); clearInterval(Build.interval);
// Init breakpoint checker // Init breakpoint checker
this.bp = Breakpoints.get(); this.bp = Breakpoints.get();
$('.js-build-sidebar').niceScroll(); this.initSidebar();
this.populateJobs(this.build_stage); this.populateJobs(this.build_stage);
this.updateStageDropdownText(this.build_stage); this.updateStageDropdownText(this.build_stage);
this.hideSidebar();
$(document).off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
$(window).off('resize.build').on('resize.build', this.hideSidebar); $(window).off('resize.build').on('resize.build', this.hideSidebar);
$(document).off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown); this.$document.off('click', '.stage-item').on('click', '.stage-item', this.updateDropdown);
$('#js-build-scroll > a').off('click').on('click', this.stepTrace); $('#js-build-scroll > a').off('click').on('click', this.stepTrace);
this.updateArtifactRemoveDate(); this.updateArtifactRemoveDate();
if ($('#build-trace').length) { if ($('#build-trace').length) {
...@@ -62,6 +61,21 @@ ...@@ -62,6 +61,21 @@
} }
} }
Build.prototype.initSidebar = function() {
this.$sidebar = $('.js-build-sidebar');
this.sidebarTranslationLimits = {
min: $('.navbar-gitlab').outerHeight() + $('.layout-nav').outerHeight()
}
this.sidebarTranslationLimits.max = this.sidebarTranslationLimits.min + $('.scrolling-tabs-container').outerHeight();
this.$sidebar.css({
top: this.sidebarTranslationLimits.max
});
this.$sidebar.niceScroll();
this.hideSidebar();
this.$document.off('click', '.js-sidebar-build-toggle').on('click', '.js-sidebar-build-toggle', this.toggleSidebar);
this.$document.off('scroll.translateSidebar').on('scroll.translateSidebar', this.translateSidebar.bind(this));
};
Build.prototype.getInitialBuildTrace = function() { Build.prototype.getInitialBuildTrace = function() {
var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped'] var removeRefreshStatuses = ['success', 'failed', 'canceled', 'skipped']
...@@ -129,15 +143,23 @@ ...@@ -129,15 +143,23 @@
Build.prototype.toggleSidebar = function() { Build.prototype.toggleSidebar = function() {
if (this.shouldHideSidebar()) { if (this.shouldHideSidebar()) {
return $('.js-build-sidebar').toggleClass('right-sidebar-expanded right-sidebar-collapsed'); return this.$sidebar.toggleClass('right-sidebar-expanded right-sidebar-collapsed');
} }
}; };
Build.prototype.translateSidebar = function(e) {
var newPosition = this.sidebarTranslationLimits.max - document.body.scrollTop;
if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min;
this.$sidebar.css({
top: newPosition
});
};
Build.prototype.hideSidebar = function() { Build.prototype.hideSidebar = function() {
if (this.shouldHideSidebar()) { if (this.shouldHideSidebar()) {
return $('.js-build-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); return this.$sidebar.removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed');
} else { } else {
return $('.js-build-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); return this.$sidebar.removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
} }
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
Dispatcher = (function() { Dispatcher = (function() {
function Dispatcher() { function Dispatcher() {
this.initSearch(); this.initSearch();
this.initFieldErrors();
this.initPageScripts(); this.initPageScripts();
} }
...@@ -20,6 +21,9 @@ ...@@ -20,6 +21,9 @@
path = page.split(':'); path = page.split(':');
shortcut_handler = null; shortcut_handler = null;
switch (page) { switch (page) {
case 'sessions:new':
new UsernameValidator();
break;
case 'projects:boards:show': case 'projects:boards:show':
case 'projects:boards:index': case 'projects:boards:index':
shortcut_handler = new ShortcutsNavigation(); shortcut_handler = new ShortcutsNavigation();
...@@ -140,12 +144,12 @@ ...@@ -140,12 +144,12 @@
break; break;
case 'groups:group_members:index': case 'groups:group_members:index':
new gl.MemberExpirationDate(); new gl.MemberExpirationDate();
new GroupMembers(); new gl.Members();
new UsersSelect(); new UsersSelect();
break; break;
case 'projects:project_members:index': case 'projects:project_members:index':
new gl.MemberExpirationDate(); new gl.MemberExpirationDate();
new ProjectMembers(); new gl.Members();
new UsersSelect(); new UsersSelect();
break; break;
case 'groups:new': case 'groups:new':
...@@ -291,6 +295,12 @@ ...@@ -291,6 +295,12 @@
} }
}; };
Dispatcher.prototype.initFieldErrors = function() {
$('.show-gl-field-errors').each((i, form) => {
new gl.GlFieldErrors(form);
});
};
return Dispatcher; return Dispatcher;
})(); })();
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
return function(e) { return function(e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
return _this.input.val('').trigger('keyup').focus(); return _this.input.val('').trigger('input').focus();
}; };
})(this)); })(this));
// Key events // Key events
...@@ -37,28 +37,16 @@ ...@@ -37,28 +37,16 @@
e.preventDefault() e.preventDefault()
} }
}) })
.on('keyup', function(e) { .on('input', function() {
var keyCode;
keyCode = e.which;
if (ARROW_KEY_CODES.indexOf(keyCode) >= 0) {
return;
}
if (this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) { if (this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.addClass(HAS_VALUE_CLASS); $inputContainer.addClass(HAS_VALUE_CLASS);
} else if (this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) { } else if (this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.removeClass(HAS_VALUE_CLASS); $inputContainer.removeClass(HAS_VALUE_CLASS);
} }
if (keyCode === 13 && !options.elIsInput) {
return false;
}
// Only filter asynchronously only if option remote is set // Only filter asynchronously only if option remote is set
if (this.options.remote) { if (this.options.remote) {
clearTimeout(timeout); clearTimeout(timeout);
return timeout = setTimeout(function() { return timeout = setTimeout(function() {
var blurField = this.shouldBlur(keyCode);
if (blurField && this.filterInputBlur) {
this.input.blur();
}
return this.options.query(this.input.val(), function(data) { return this.options.query(this.input.val(), function(data) {
return this.options.callback(data); return this.options.callback(data);
}.bind(this)); }.bind(this));
...@@ -255,7 +243,7 @@ ...@@ -255,7 +243,7 @@
_this.fullData = data; _this.fullData = data;
_this.parseData(_this.fullData); _this.parseData(_this.fullData);
if (_this.options.filterable && _this.filter && _this.filter.input) { if (_this.options.filterable && _this.filter && _this.filter.input) {
return _this.filter.input.trigger('keyup'); return _this.filter.input.trigger('input');
} }
}; };
// Remote data // Remote data
...@@ -487,7 +475,7 @@ ...@@ -487,7 +475,7 @@
// Triggering 'keyup' will re-render the dropdown which is not always required // Triggering 'keyup' will re-render the dropdown which is not always required
// specially if we want to keep the state of the dropdown needed for bulk-assignment // specially if we want to keep the state of the dropdown needed for bulk-assignment
if (!this.options.persistWhenHide) { if (!this.options.persistWhenHide) {
$input.trigger("keyup"); $input.trigger("input");
} }
if (this.dropdown.find(".dropdown-toggle-page").length) { if (this.dropdown.find(".dropdown-toggle-page").length) {
$('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS); $('.dropdown-menu', this.dropdown).removeClass(PAGE_TWO_CLASS);
...@@ -500,14 +488,27 @@ ...@@ -500,14 +488,27 @@
// Render the full menu // Render the full menu
GitLabDropdown.prototype.renderMenu = function(html) { GitLabDropdown.prototype.renderMenu = function(html) {
var menu_html;
menu_html = "";
if (this.options.renderMenu) { if (this.options.renderMenu) {
menu_html = this.options.renderMenu(html); return this.options.renderMenu(html);
} else { } else {
menu_html = $('<ul />').append(html); var ul = document.createElement('ul');
for (var i = 0; i < html.length; i++) {
var el = html[i];
if (el instanceof jQuery) {
el = el.get(0);
}
if (typeof el === 'string') {
ul.innerHTML += el;
} else {
ul.appendChild(el);
}
}
return ul;
} }
return menu_html;
}; };
// Append the menu into the dropdown // Append the menu into the dropdown
...@@ -521,7 +522,7 @@ ...@@ -521,7 +522,7 @@
}; };
GitLabDropdown.prototype.renderItem = function(data, group, index) { GitLabDropdown.prototype.renderItem = function(data, group, index) {
var cssClass, field, fieldName, groupAttrs, html, selected, text, url, value; var field, fieldName, html, selected, text, url, value;
if (group == null) { if (group == null) {
group = false; group = false;
} }
...@@ -529,18 +530,16 @@ ...@@ -529,18 +530,16 @@
// Render the row // Render the row
index = false; index = false;
} }
html = ""; html = document.createElement('li');
// Divider if (data === 'divider' || data === 'separator') {
if (data === "divider") { html.className = data;
return "<li class='divider'></li>"; return html;
}
// Separator is a full-width divider
if (data === "separator") {
return "<li class='separator'></li>";
} }
// Header // Header
if (data.header != null) { if (data.header != null) {
return _.template('<li class="dropdown-header"><%- header %></li>')({ header: data.header }); html.className = 'dropdown-header';
html.innerHTML = data.header;
return html;
} }
if (this.options.renderRow) { if (this.options.renderRow) {
// Call the render function // Call the render function
...@@ -567,24 +566,25 @@ ...@@ -567,24 +566,25 @@
} else { } else {
text = data.text != null ? data.text : ''; text = data.text != null ? data.text : '';
} }
cssClass = "";
if (selected) {
cssClass = "is-active";
}
if (this.highlight) { if (this.highlight) {
text = this.highlightTextMatches(text, this.filterInput.val()); text = this.highlightTextMatches(text, this.filterInput.val());
} }
// Create the list item & the link
var link = document.createElement('a');
link.href = url;
link.innerHTML = text;
if (selected) {
link.className = 'is-active';
}
if (group) { if (group) {
groupAttrs = 'data-group=' + group + ' data-index=' + index; link.dataset.group = group;
} else { link.dataset.index = index;
groupAttrs = '';
} }
html = _.template('<li><a href="<%- url %>" <%- groupAttrs %> class="<%- cssClass %>"><%= text %></a></li>')({
url: url, html.appendChild(link);
groupAttrs: groupAttrs,
cssClass: cssClass,
text: text
});
} }
return html; return html;
}; };
......
((global) => {
/*
* This class overrides the browser's validation error bubbles, displaying custom
* error messages for invalid fields instead. To begin validating any form, add the
* class `show-gl-field-errors` to the form element, and ensure error messages are
* declared in each inputs' title attribute.
*
* Example:
*
* <form class='show-gl-field-errors'>
* <input type='text' name='username' title='Username is required.'/>
*</form>
*
* */
const errorMessageClass = 'gl-field-error';
const inputErrorClass = 'gl-field-error-outline';
class GlFieldError {
constructor({ input, formErrors }) {
this.inputElement = $(input);
this.inputDomElement = this.inputElement.get(0);
this.form = formErrors;
this.errorMessage = this.inputElement.attr('title') || 'This field is required.';
this.fieldErrorElement = $(`<p class='${errorMessageClass} hide'>${ this.errorMessage }</p>`);
this.state = {
valid: false,
empty: true
};
this.initFieldValidation();
}
initFieldValidation() {
// hidden when injected into DOM
this.inputElement.after(this.fieldErrorElement);
this.inputElement.off('invalid').on('invalid', this.handleInvalidSubmit.bind(this));
this.scopedSiblings = this.safelySelectSiblings();
}
safelySelectSiblings() {
// Apply `ignoreSelector` in markup to siblings whose visibility should not be toggled with input validity
const ignoreSelector = '.validation-ignore';
const unignoredSiblings = this.inputElement.siblings(`p:not(${ignoreSelector})`);
const parentContainer = this.inputElement.parent('.form-group');
// Only select siblings when they're scoped within a form-group with one input
const safelyScoped = parentContainer.length && parentContainer.find('input').length === 1;
return safelyScoped ? unignoredSiblings : this.fieldErrorElement;
}
renderValidity() {
this.renderClear();
if (this.state.valid) {
return this.renderValid();
}
if (this.state.empty) {
return this.renderEmpty();
}
if (!this.state.valid) {
return this.renderInvalid();
}
}
handleInvalidSubmit(event) {
event.preventDefault();
const currentValue = this.accessCurrentValue();
this.state.valid = false;
this.state.empty = currentValue === '';
this.renderValidity();
this.form.focusOnFirstInvalid.apply(this.form);
// For UX, wait til after first invalid submission to check each keyup
this.inputElement.off('keyup.field_validator')
.on('keyup.field_validator', this.updateValidity.bind(this));
}
/* Get or set current input value */
accessCurrentValue(newVal) {
return newVal ? this.inputElement.val(newVal) : this.inputElement.val();
}
getInputValidity() {
return this.inputDomElement.validity.valid;
}
updateValidity() {
const inputVal = this.accessCurrentValue();
this.state.empty = !inputVal.length;
this.state.valid = this.getInputValidity();
this.renderValidity();
}
renderValid() {
return this.renderClear();
}
renderEmpty() {
return this.renderInvalid();
}
renderInvalid() {
this.inputElement.addClass(inputErrorClass);
this.scopedSiblings.hide();
return this.fieldErrorElement.show();
}
renderClear() {
const inputVal = this.accessCurrentValue();
if (!inputVal.split(' ').length) {
const trimmedInput = inputVal.trim();
this.accessCurrentValue(trimmedInput);
}
this.inputElement.removeClass(inputErrorClass);
this.scopedSiblings.hide();
this.fieldErrorElement.hide();
}
}
const customValidationFlag = 'no-gl-field-errors';
class GlFieldErrors {
constructor(form) {
this.form = $(form);
this.state = {
inputs: [],
valid: false
};
this.initValidators();
}
initValidators () {
// select all non-hidden inputs in form
this.state.inputs = this.form.find(':input:not([type=hidden])').toArray()
.filter((input) => !input.classList.contains(customValidationFlag))
.map((input) => new GlFieldError({ input, formErrors: this }));
this.form.on('submit', this.catchInvalidFormSubmit);
}
/* Neccessary to prevent intercept and override invalid form submit
* because Safari & iOS quietly allow form submission when form is invalid
* and prevents disabling of invalid submit button by application.js */
catchInvalidFormSubmit (event) {
if (!event.currentTarget.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
}
focusOnFirstInvalid () {
const firstInvalid = this.state.inputs.filter((input) => !input.inputDomElement.validity.valid)[0];
firstInvalid.inputElement.focus();
}
}
global.GlFieldErrors = GlFieldErrors;
})(window.gl || (window.gl = {}));
(function() {
this.GroupMembers = (function() {
function GroupMembers() {
$('li.group_member').bind('ajax:success', function() {
return $(this).fadeOut();
});
}
return GroupMembers;
})();
}).call(this);
...@@ -14,14 +14,18 @@ ...@@ -14,14 +14,18 @@
inputs.datepicker({ inputs.datepicker({
dateFormat: 'yy-mm-dd', dateFormat: 'yy-mm-dd',
minDate: 1, minDate: 1,
onSelect: toggleClearInput onSelect: function () {
$(this).trigger('change');
toggleClearInput.call(this);
}
}); });
inputs.next('.js-clear-input').on('click', function(event) { inputs.next('.js-clear-input').on('click', function(event) {
event.preventDefault(); event.preventDefault();
var input = $(this).closest('.clearable-input').find('.js-access-expiration-date'); var input = $(this).closest('.clearable-input').find('.js-access-expiration-date');
input.datepicker('setDate', null); input.datepicker('setDate', null)
.trigger('change');
toggleClearInput.call(input); toggleClearInput.call(input);
}); });
......
((w) => {
w.gl = w.gl || {};
class Members {
constructor() {
this.addListeners();
}
addListeners() {
$('.project_member, .group_member').off('ajax:success').on('ajax:success', this.removeRow);
$('.js-member-update-control').off('change').on('change', this.formSubmit);
$('.js-edit-member-form').off('ajax:success').on('ajax:success', this.formSuccess);
}
removeRow(e) {
const $target = $(e.target);
if ($target.hasClass('btn-remove')) {
$target.closest('.member')
.fadeOut(function () {
$(this).remove();
});
}
}
formSubmit() {
$(this).closest('form').trigger("submit.rails").end().disable();
}
formSuccess() {
$(this).find('.js-member-update-control').enable();
}
}
gl.Members = Members;
})(window);
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
this._location = location; this._location = location;
this.bindEvents(); this.bindEvents();
this.activateTab(this.opts.action); this.activateTab(this.opts.action);
this.initAffix();
} }
MergeRequestTabs.prototype.bindEvents = function() { MergeRequestTabs.prototype.bindEvents = function() {
...@@ -380,6 +381,46 @@ ...@@ -380,6 +381,46 @@
// Only when sidebar is collapsed // Only when sidebar is collapsed
}; };
MergeRequestTabs.prototype.initAffix = function () {
var $tabs = $('.js-tabs-affix');
// Screen space on small screens is usually very sparse
// So we dont affix the tabs on these
if (Breakpoints.get().getBreakpointSize() === 'xs' || !$tabs.length) return;
var tabsWidth = $tabs.outerWidth(),
$diffTabs = $('#diff-notes-app'),
offsetTop = $tabs.offset().top - ($('.navbar-fixed-top').height() + $('.layout-nav').height());
$tabs.off('affix.bs.affix affix-top.bs.affix')
.affix({
offset: {
top: offsetTop
}
}).on('affix.bs.affix', function () {
$tabs.css({
left: $tabs.offset().left,
width: tabsWidth
});
$diffTabs.css({
marginTop: $tabs.height()
});
}).on('affix-top.bs.affix', function () {
$tabs.css({
left: '',
width: ''
});
$diffTabs.css({
marginTop: ''
});
});
// Fix bug when reloading the page already scrolling
if ($tabs.hasClass('affix')) {
$tabs.trigger('affix.bs.affix');
}
};
return MergeRequestTabs; return MergeRequestTabs;
})(); })();
......
(function() { ((global) => {
var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; var indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
this.MergeRequestWidget = (function() { const DEPLOYMENT_TEMPLATE = `<div class="mr-widget-heading" id="<%- id %>">
<div class="ci_widget ci-success">
<%= ci_success_icon %>
<span>
Deployed to
<a href="<%- url %>" target="_blank" class="environment">
<%- name %>
</a>
<span class="js-environment-timeago" data-toggle="tooltip" data-placement="top" data-title="<%- deployed_at_formatted %>">
<%- deployed_at %>
</span>
<a class="js-environment-link" href="<%- external_url %>" target="_blank">
<i class="fa fa-external-link"></i>
View on <%- external_url_formatted %>
</a>
</span>
</div>
</div>`;
global.MergeRequestWidget = (function() {
function MergeRequestWidget(opts) { function MergeRequestWidget(opts) {
// Initialize MergeRequestWidget behavior // Initialize MergeRequestWidget behavior
// //
...@@ -10,17 +29,23 @@ ...@@ -10,17 +29,23 @@
// ci_status_url - String, URL to use to check CI status // ci_status_url - String, URL to use to check CI status
// //
this.opts = opts; this.opts = opts;
this.$widgetBody = $('.mr-widget-body');
$('#modal_merge_info').modal({ $('#modal_merge_info').modal({
show: false show: false
}); });
this.firstCICheck = true; this.firstCICheck = true;
this.readyForCICheck = false; this.readyForCICheck = false;
this.readyForCIEnvironmentCheck = false;
this.cancel = false; this.cancel = false;
clearInterval(this.fetchBuildStatusInterval); clearInterval(this.fetchBuildStatusInterval);
clearInterval(this.fetchBuildEnvironmentStatusInterval);
this.clearEventListeners(); this.clearEventListeners();
this.addEventListeners(); this.addEventListeners();
this.getCIStatus(false); this.getCIStatus(false);
this.getCIEnvironmentsStatus();
this.retrieveSuccessIcon();
this.pollCIStatus(); this.pollCIStatus();
this.pollCIEnvironmentsStatus();
notifyPermissions(); notifyPermissions();
} }
...@@ -41,6 +66,7 @@ ...@@ -41,6 +66,7 @@
page = $('body').data('page').split(':').last(); page = $('body').data('page').split(':').last();
if (allowedPages.indexOf(page) < 0) { if (allowedPages.indexOf(page) < 0) {
clearInterval(_this.fetchBuildStatusInterval); clearInterval(_this.fetchBuildStatusInterval);
clearInterval(_this.fetchBuildEnvironmentStatusInterval);
_this.cancelPolling(); _this.cancelPolling();
return _this.clearEventListeners(); return _this.clearEventListeners();
} }
...@@ -48,6 +74,12 @@ ...@@ -48,6 +74,12 @@
})(this)); })(this));
}; };
MergeRequestWidget.prototype.retrieveSuccessIcon = function() {
const $ciSuccessIcon = $('.js-success-icon');
this.$ciSuccessIcon = $ciSuccessIcon.html();
$ciSuccessIcon.remove();
}
MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) { MergeRequestWidget.prototype.mergeInProgress = function(deleteSourceBranch) {
if (deleteSourceBranch == null) { if (deleteSourceBranch == null) {
deleteSourceBranch = false; deleteSourceBranch = false;
...@@ -62,7 +94,7 @@ ...@@ -62,7 +94,7 @@
urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : ''; urlSuffix = deleteSourceBranch ? '?deleted_source_branch=true' : '';
return window.location.href = window.location.pathname + urlSuffix; return window.location.href = window.location.pathname + urlSuffix;
} else if (data.merge_error) { } else if (data.merge_error) {
return $('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>"); return this.$widgetBody.html("<h4>" + data.merge_error + "</h4>");
} else { } else {
callback = function() { callback = function() {
return merge_request_widget.mergeInProgress(deleteSourceBranch); return merge_request_widget.mergeInProgress(deleteSourceBranch);
...@@ -118,6 +150,7 @@ ...@@ -118,6 +150,7 @@
if (data.status === '') { if (data.status === '') {
return; return;
} }
if (data.environments && data.environments.length) _this.renderEnvironments(data.environments);
if (_this.firstCICheck || data.status !== _this.opts.ci_status && (data.status != null)) { if (_this.firstCICheck || data.status !== _this.opts.ci_status && (data.status != null)) {
_this.opts.ci_status = data.status; _this.opts.ci_status = data.status;
_this.showCIStatus(data.status); _this.showCIStatus(data.status);
...@@ -150,6 +183,41 @@ ...@@ -150,6 +183,41 @@
})(this)); })(this));
}; };
MergeRequestWidget.prototype.pollCIEnvironmentsStatus = function() {
this.fetchBuildEnvironmentStatusInterval = setInterval(() => {
if (!this.readyForCIEnvironmentCheck) return;
this.getCIEnvironmentsStatus();
this.readyForCIEnvironmentCheck = false;
}, 300000);
};
MergeRequestWidget.prototype.getCIEnvironmentsStatus = function() {
$.getJSON(this.opts.ci_environments_status_url, (environments) => {
if (this.cancel) return;
this.readyForCIEnvironmentCheck = true;
if (environments && environments.length) this.renderEnvironments(environments);
});
};
MergeRequestWidget.prototype.renderEnvironments = function(environments) {
for (let i = 0; i < environments.length; i++) {
const environment = environments[i];
if ($(`.mr-state-widget #${ environment.id }`).length) return;
const $template = $(DEPLOYMENT_TEMPLATE);
if (!environment.external_url || !environment.external_url_formatted) $('.js-environment-link', $template).remove();
if (environment.deployed_at && environment.deployed_at_formatted) {
environment.deployed_at = $.timeago(environment.deployed_at) + '.';
} else {
$('.js-environment-timeago', $template).remove();
environment.name += '.';
}
environment.ci_success_icon = this.$ciSuccessIcon;
const templateString = _.unescape($template[0].outerHTML);
const template = _.template(templateString)(environment)
this.$widgetBody.before(template);
}
};
MergeRequestWidget.prototype.showCIStatus = function(state) { MergeRequestWidget.prototype.showCIStatus = function(state) {
var allowed_states; var allowed_states;
if (state == null) { if (state == null) {
...@@ -190,4 +258,4 @@ ...@@ -190,4 +258,4 @@
})(); })();
}).call(this); })(window.gl || (window.gl = {}));
(function() {
this.ProjectMembers = (function() {
function ProjectMembers() {
$('li.project_member').bind('ajax:success', function() {
return $(this).fadeOut();
});
}
return ProjectMembers;
})();
}).call(this);
...@@ -16,7 +16,13 @@ ...@@ -16,7 +16,13 @@
if (initialQuery.name) this.requestFile(initialQuery); if (initialQuery.name) this.requestFile(initialQuery);
$('.reset-template', this.dropdown.parent()).on('click', () => { $('.reset-template', this.dropdown.parent()).on('click', () => {
if (this.currentTemplate) this.setInputValueToTemplateContent(false); this.setInputValueToTemplateContent();
});
$('.no-template', this.dropdown.parent()).on('click', () => {
this.currentTemplate = '';
this.setInputValueToTemplateContent();
$('.dropdown-toggle-text', this.dropdown).text('Choose a template');
}); });
} }
......
((global) => {
const debounceTimeoutDuration = 1000;
const invalidInputClass = 'gl-field-error-outline';
const successInputClass = 'gl-field-success-outline';
const unavailableMessageSelector = '.username .validation-error';
const successMessageSelector = '.username .validation-success';
const pendingMessageSelector = '.username .validation-pending';
const invalidMessageSelector = '.username .gl-field-error';
class UsernameValidator {
constructor() {
this.inputElement = $('#new_user_username');
this.inputDomElement = this.inputElement.get(0);
this.state = {
available: false,
valid: false,
pending: false,
empty: true
};
const debounceTimeout = _.debounce((username) => {
this.validateUsername(username);
}, debounceTimeoutDuration);
this.inputElement.on('keyup.username_check', () => {
const username = this.inputElement.val();
this.state.valid = this.inputDomElement.validity.valid;
this.state.empty = !username.length;
if (this.state.valid) {
return debounceTimeout(username);
}
this.renderState();
});
// Override generic field validation
this.inputElement.on('invalid', this.interceptInvalid.bind(this));
}
renderState() {
// Clear all state
this.clearFieldValidationState();
if (this.state.valid && this.state.available) {
return this.setSuccessState();
}
if (this.state.empty) {
return this.clearFieldValidationState();
}
if (this.state.pending) {
return this.setPendingState();
}
if (!this.state.available) {
return this.setUnavailableState();
}
if (!this.state.valid) {
return this.setInvalidState();
}
}
interceptInvalid(event) {
event.preventDefault();
event.stopPropagation();
}
validateUsername(username) {
if (this.state.valid) {
this.state.pending = true;
this.state.available = false;
this.renderState();
return $.ajax({
type: 'GET',
url: `/u/${username}/exists`,
dataType: 'json',
success: (res) => this.setAvailabilityState(res.exists)
});
}
}
setAvailabilityState(usernameTaken) {
if (usernameTaken) {
this.state.valid = false;
this.state.available = false;
} else {
this.state.available = true;
}
this.state.pending = false;
this.renderState();
}
clearFieldValidationState() {
this.inputElement.siblings('p').hide();
this.inputElement.removeClass(invalidInputClass)
.removeClass(successInputClass);
}
setUnavailableState() {
const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$usernameUnavailableMessage.show();
}
setSuccessState() {
const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector);
this.inputElement.addClass(successInputClass).removeClass(invalidInputClass);
$usernameSuccessMessage.show();
}
setPendingState() {
const $usernamePendingMessage = $(pendingMessageSelector);
if (this.state.pending) {
$usernamePendingMessage.show();
} else {
$usernamePendingMessage.hide();
}
}
setInvalidState() {
const $inputErrorMessage = $(invalidMessageSelector);
this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
$inputErrorMessage.show();
}
}
global.UsernameValidator = UsernameValidator;
})(window);
...@@ -325,6 +325,10 @@ ...@@ -325,6 +325,10 @@
}; };
UsersSelect.prototype.user = function(user_id, callback) { UsersSelect.prototype.user = function(user_id, callback) {
if(!/^\d+$/.test(user_id)) {
return false;
}
var url; var url;
url = this.buildUrl(this.userPath); url = this.buildUrl(this.userPath);
url = url.replace(':id', user_id); url = url.replace(':id', user_id);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
display: none; display: none;
&.hide { display: block; } &.hide { display: block; }
} }
&.open .content { &.open .content {
display: block; display: block;
&.hide { display: none; } &.hide { display: none; }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
&.diff-collapsed { &.diff-collapsed {
padding: 5px; padding: 5px;
.click-to-expand { .click-to-expand {
cursor: pointer; cursor: pointer;
} }
...@@ -203,6 +204,7 @@ ...@@ -203,6 +204,7 @@
} }
} }
} }
&.user-cover-block { &.user-cover-block {
padding: 24px 0 0; padding: 24px 0 0;
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
&:focus { &:focus {
background-color: $hover-background; background-color: $hover-background;
color: $hover-text; color: $hover-text;
border-color: $hover-border;; border-color: $hover-border;
} }
} }
...@@ -152,7 +152,8 @@ ...@@ -152,7 +152,8 @@
@include btn-blue-medium; @include btn-blue-medium;
} }
&.btn-info { &.btn-info,
&.btn-register {
@include btn-blue; @include btn-blue;
} }
...@@ -240,6 +241,7 @@ ...@@ -240,6 +241,7 @@
width: 100%; width: 100%;
margin: 0; margin: 0;
margin-bottom: 15px; margin-bottom: 15px;
&.btn { &.btn {
padding: 6px 0; padding: 6px 0;
} }
...@@ -321,6 +323,7 @@ ...@@ -321,6 +323,7 @@
.btn-build { .btn-build {
margin-left: 10px; margin-left: 10px;
i { i {
color: $gl-icon-color; color: $gl-icon-color;
} }
...@@ -328,6 +331,7 @@ ...@@ -328,6 +331,7 @@
.clone-dropdown-btn a { .clone-dropdown-btn a {
color: $dropdown-link-color; color: $dropdown-link-color;
&:hover { &:hover {
text-decoration: none; text-decoration: none;
} }
...@@ -337,6 +341,7 @@ ...@@ -337,6 +341,7 @@
background-color: $background-color !important; background-color: $background-color !important;
border: 1px solid lightgrey; border: 1px solid lightgrey;
cursor: default; cursor: default;
&:active { &:active {
-moz-box-shadow: inset 0 0 0 white; -moz-box-shadow: inset 0 0 0 white;
-webkit-box-shadow: inset 0 0 0 white; -webkit-box-shadow: inset 0 0 0 white;
......
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
color: $text-color; color: $text-color;
background: $background-color; background: $background-color;
} }
.bs-callout h4 { .bs-callout h4 {
margin-top: 0; margin-top: 0;
margin-bottom: 5px; margin-bottom: 5px;
} }
.bs-callout p:last-child { .bs-callout p:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
...@@ -27,16 +29,19 @@ ...@@ -27,16 +29,19 @@
border-color: #eed3d7; border-color: #eed3d7;
color: #b94a48; color: #b94a48;
} }
.bs-callout-warning { .bs-callout-warning {
background-color: #faf8f0; background-color: #faf8f0;
border-color: #faebcc; border-color: #faebcc;
color: #8a6d3b; color: #8a6d3b;
} }
.bs-callout-info { .bs-callout-info {
background-color: #f4f8fa; background-color: #f4f8fa;
border-color: #bce8f1; border-color: #bce8f1;
color: #34789a; color: #34789a;
} }
.bs-callout-success { .bs-callout-success {
background-color: #dff0d8; background-color: #dff0d8;
border-color: #5ca64d; border-color: #5ca64d;
......
/** COLORS **/ /** COLORS **/
.cgray { color: $gl-gray; } .cgray { color: $gl-gray; }
.clgray { color: #bbb } .clgray { color: #bbb; }
.cred { color: $gl-text-red; } .cred { color: $gl-text-red; }
.cgreen { color: $gl-text-green; } .cgreen { color: $gl-text-green; }
.cdark { color: #444 } .cdark { color: #444; }
/** COMMON CLASSES **/ /** COMMON CLASSES **/
.prepend-top-0 { margin-top: 0; } .prepend-top-0 { margin-top: 0; }
.prepend-top-5 { margin-top: 5px; } .prepend-top-5 { margin-top: 5px; }
.prepend-top-10 { margin-top: 10px } .prepend-top-10 { margin-top: 10px; }
.prepend-top-default { margin-top: $gl-padding !important; } .prepend-top-default { margin-top: $gl-padding !important; }
.prepend-top-20 { margin-top: 20px } .prepend-top-20 { margin-top: 20px; }
.prepend-left-5 { margin-left: 5px } .prepend-left-5 { margin-left: 5px; }
.prepend-left-10 { margin-left: 10px } .prepend-left-10 { margin-left: 10px; }
.prepend-left-default { margin-left: $gl-padding; } .prepend-left-default { margin-left: $gl-padding; }
.prepend-left-20 { margin-left: 20px } .prepend-left-20 { margin-left: 20px; }
.append-right-5 { margin-right: 5px } .append-right-5 { margin-right: 5px; }
.append-right-10 { margin-right: 10px } .append-right-10 { margin-right: 10px; }
.append-right-default { margin-right: $gl-padding; } .append-right-default { margin-right: $gl-padding; }
.append-right-20 { margin-right: 20px } .append-right-20 { margin-right: 20px; }
.append-bottom-0 { margin-bottom: 0 } .append-bottom-0 { margin-bottom: 0; }
.append-bottom-10 { margin-bottom: 10px } .append-bottom-10 { margin-bottom: 10px; }
.append-bottom-15 { margin-bottom: 15px } .append-bottom-15 { margin-bottom: 15px; }
.append-bottom-20 { margin-bottom: 20px } .append-bottom-20 { margin-bottom: 20px; }
.append-bottom-default { margin-bottom: $gl-padding; } .append-bottom-default { margin-bottom: $gl-padding; }
.inline { display: inline-block } .inline { display: inline-block; }
.center { text-align: center } .center { text-align: center; }
.underlined-link { text-decoration: underline; } .underlined-link { text-decoration: underline; }
.hint { font-style: italic; color: #999; } .hint { font-style: italic; color: #999; }
...@@ -97,6 +97,7 @@ span.update-author { ...@@ -97,6 +97,7 @@ span.update-author {
color: #999; color: #999;
font-weight: normal; font-weight: normal;
font-style: italic; font-style: italic;
strong { strong {
font-weight: bold; font-weight: bold;
font-style: normal; font-style: normal;
...@@ -128,7 +129,7 @@ p.time { ...@@ -128,7 +129,7 @@ p.time {
// Fix issue with notes & lists creating a bunch of bottom borders. // Fix issue with notes & lists creating a bunch of bottom borders.
li.note { li.note {
img { max-width: 100% } img { max-width: 100%; }
.note-title { .note-title {
li { li {
border-bottom: none !important; border-bottom: none !important;
...@@ -172,6 +173,7 @@ li.note { ...@@ -172,6 +173,7 @@ li.note {
@extend .col-md-6; @extend .col-md-6;
text-align: left; text-align: left;
margin-top: 40px; margin-top: 40px;
pre { pre {
background: white; background: white;
border: none; border: none;
...@@ -197,6 +199,7 @@ li.note { ...@@ -197,6 +199,7 @@ li.note {
background: #c67; background: #c67;
color: #fff; color: #fff;
font-weight: bold; font-weight: bold;
a { a {
color: #fff; color: #fff;
text-decoration: underline; text-decoration: underline;
...@@ -227,6 +230,7 @@ li.note { ...@@ -227,6 +230,7 @@ li.note {
&.milestone-closed { &.milestone-closed {
background: $gray-light; background: $gray-light;
} }
.progress { .progress {
margin-bottom: 0; margin-bottom: 0;
margin-top: 4px; margin-top: 4px;
...@@ -286,6 +290,7 @@ table { ...@@ -286,6 +290,7 @@ table {
.footer-links { .footer-links {
margin-bottom: 20px; margin-bottom: 20px;
a { a {
margin-right: 15px; margin-right: 15px;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
.dropdown-menu, .dropdown-menu,
.dropdown-menu-nav { .dropdown-menu-nav {
display: block; display: block;
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
width: 100%; width: 100%;
} }
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
margin-top: -6px; margin-top: -6px;
color: $dropdown-toggle-icon-color; color: $dropdown-toggle-icon-color;
font-size: 10px; font-size: 10px;
&.fa-spinner { &.fa-spinner {
font-size: 16px; font-size: 16px;
margin-top: -8px; margin-top: -8px;
......
...@@ -26,15 +26,6 @@ ...@@ -26,15 +26,6 @@
padding: 10px $gl-padding; padding: 10px $gl-padding;
word-wrap: break-word; word-wrap: break-word;
border-radius: 3px 3px 0 0; border-radius: 3px 3px 0 0;
cursor: pointer;
&:hover {
background-color: $dark-background-color;
}
.diff-toggle-caret {
padding-right: 6px;
}
&.file-title-clear { &.file-title-clear {
padding-left: 0; padding-left: 0;
...@@ -66,6 +57,7 @@ ...@@ -66,6 +57,7 @@
margin-top: -3px; margin-top: -3px;
} }
} }
.file-content { .file-content {
background: #fff; background: #fff;
...@@ -105,22 +97,27 @@ ...@@ -105,22 +97,27 @@
border: none; border: none;
margin: 0; margin: 0;
} }
tr { tr {
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
} }
td { td {
&:first-child { &:first-child {
border-left: none; border-left: none;
} }
&:last-child { &:last-child {
border-right: none; border-right: none;
} }
} }
td.blame-commit { td.blame-commit {
padding: 0 10px; padding: 0 10px;
min-width: 400px; min-width: 400px;
background: $gray-light; background: $gray-light;
} }
td.line-numbers { td.line-numbers {
float: none; float: none;
border-left: 1px solid #ddd; border-left: 1px solid #ddd;
...@@ -130,6 +127,7 @@ ...@@ -130,6 +127,7 @@
margin-right: 0; margin-right: 0;
} }
} }
td.lines { td.lines {
padding: 0; padding: 0;
} }
...@@ -146,8 +144,10 @@ ...@@ -146,8 +144,10 @@
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
margin-bottom: 0; margin-bottom: 0;
background: white; background: white;
li { li {
color: #888; color: #888;
p { p {
margin: 0; margin: 0;
color: #333; color: #333;
......
...@@ -9,7 +9,7 @@ input { ...@@ -9,7 +9,7 @@ input {
input[type='text'].danger { input[type='text'].danger {
background: #f2dede!important; background: #f2dede!important;
border-color: #d66; border-color: #d66;
text-shadow: 0 1px 1px #fff text-shadow: 0 1px 1px #fff;
} }
.datetime-controls { .datetime-controls {
...@@ -73,8 +73,8 @@ label { ...@@ -73,8 +73,8 @@ label {
} }
.form-control { .form-control {
box-shadow: none; @include box-shadow(none);
border-radius: 3px; border-radius: 2px;
padding: $gl-vert-padding $gl-input-padding; padding: $gl-vert-padding $gl-input-padding;
} }
...@@ -117,9 +117,11 @@ label { ...@@ -117,9 +117,11 @@ label {
display: table-cell; display: table-cell;
width: 200px !important; width: 200px !important;
} }
.input-group-addon { .input-group-addon {
background-color: #f7f8fa; background-color: #f7f8fa;
} }
.input-group-addon:not(:first-child):not(:last-child) { .input-group-addon:not(:first-child):not(:last-child) {
border-left: 0; border-left: 0;
border-right: 0; border-right: 0;
...@@ -129,3 +131,8 @@ label { ...@@ -129,3 +131,8 @@ label {
.help-block { .help-block {
margin-bottom: 0; margin-bottom: 0;
} }
.gl-field-error {
color: $red-normal;
}
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
} }
i { i {
color: $white-light color: $white-light;
} }
path, path,
......
...@@ -168,6 +168,7 @@ header { ...@@ -168,6 +168,7 @@ header {
a { a {
color: $gl-text-color; color: $gl-text-color;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
padding-top: 1px; padding-top: 1px;
margin: 0; margin: 0;
color: $gray-dark; color: $gray-dark;
img { img {
position: relative; position: relative;
top: 3px; top: 3px;
...@@ -128,6 +129,10 @@ ul.content-list { ...@@ -128,6 +129,10 @@ ul.content-list {
color: $gl-dark-link-color; color: $gl-dark-link-color;
} }
.member-group-link {
color: $blue-normal;
}
.description { .description {
p { p {
@include str-truncated; @include str-truncated;
...@@ -168,6 +173,14 @@ ul.content-list { ...@@ -168,6 +173,14 @@ ul.content-list {
} }
} }
.member-controls {
float: none;
@media (min-width: $screen-sm-min) {
float: right;
}
}
// When dragging a list item // When dragging a list item
&.ui-sortable-helper { &.ui-sortable-helper {
border-bottom: none; border-bottom: none;
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
0%, 10%, 100% { 0%, 10%, 100% {
fill: lighten($tanuki-yellow, 25%); fill: lighten($tanuki-yellow, 25%);
} }
90% { 90% {
fill: $tanuki-yellow; fill: $tanuki-yellow;
} }
...@@ -48,6 +49,7 @@ ...@@ -48,6 +49,7 @@
10%, 80% { 10%, 80% {
fill: $tanuki-orange; fill: $tanuki-orange;
} }
20%, 90% { 20%, 90% {
fill: lighten($tanuki-orange, 25%); fill: lighten($tanuki-orange, 25%);
} }
...@@ -59,6 +61,7 @@ ...@@ -59,6 +61,7 @@
10%, 80% { 10%, 80% {
fill: $tanuki-red; fill: $tanuki-red;
} }
20%, 90% { 20%, 90% {
fill: lighten($tanuki-red, 25%); fill: lighten($tanuki-red, 25%);
} }
...@@ -70,6 +73,7 @@ ...@@ -70,6 +73,7 @@
20%, 70% { 20%, 70% {
fill: $tanuki-red; fill: $tanuki-red;
} }
30%, 80% { 30%, 80% {
fill: lighten($tanuki-red, 25%); fill: lighten($tanuki-red, 25%);
} }
...@@ -81,6 +85,7 @@ ...@@ -81,6 +85,7 @@
30%, 60% { 30%, 60% {
fill: $tanuki-orange; fill: $tanuki-orange;
} }
40%, 70% { 40%, 70% {
fill: lighten($tanuki-orange, 25%); fill: lighten($tanuki-orange, 25%);
} }
...@@ -92,6 +97,7 @@ ...@@ -92,6 +97,7 @@
30%, 60% { 30%, 60% {
fill: $tanuki-red; fill: $tanuki-red;
} }
40%, 70% { 40%, 70% {
fill: lighten($tanuki-red, 25%); fill: lighten($tanuki-red, 25%);
} }
...@@ -103,6 +109,7 @@ ...@@ -103,6 +109,7 @@
40% { 40% {
fill: $tanuki-yellow; fill: $tanuki-yellow;
} }
60% { 60% {
fill: lighten($tanuki-yellow, 25%); fill: lighten($tanuki-yellow, 25%);
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
&.active { &.active {
background: $gray-light; background: $gray-light;
a { a {
font-weight: 600; font-weight: 600;
} }
......
...@@ -210,6 +210,7 @@ ...@@ -210,6 +210,7 @@
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
padding-bottom: 0; padding-bottom: 0;
width: 100%; width: 100%;
.btn, form, .dropdown, .dropdown-menu-toggle, .form-control { .btn, form, .dropdown, .dropdown-menu-toggle, .form-control {
margin: 0 0 10px; margin: 0 0 10px;
display: block; display: block;
......
...@@ -13,6 +13,11 @@ ...@@ -13,6 +13,11 @@
.dropdown-menu-toggle { .dropdown-menu-toggle {
line-height: 20px; line-height: 20px;
} }
.badge {
margin-top: -2px;
margin-left: 5px;
}
} }
.panel-body { .panel-body {
......
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
background: none; background: none;
.select2-search-field input { .select2-search-field input {
padding: $gl-padding / 2; padding: 5px $gl-padding / 2;
font-size: 13px; font-size: 13px;
height: auto; height: auto;
font-family: inherit; font-family: inherit;
...@@ -101,7 +101,7 @@ ...@@ -101,7 +101,7 @@
} }
.select2-search-choice { .select2-search-choice {
margin: 8px 0 0 8px; margin: 5px 0 0 8px;
box-shadow: none; box-shadow: none;
border-color: $input-border; border-color: $input-border;
color: $gl-text-color; color: $gl-text-color;
...@@ -137,6 +137,7 @@ ...@@ -137,6 +137,7 @@
.select2-results { .select2-results {
max-height: 350px; max-height: 350px;
.select2-highlighted { .select2-highlighted {
background: $gl-primary; background: $gl-primary;
} }
...@@ -212,9 +213,11 @@ ...@@ -212,9 +213,11 @@
.group-image { .group-image {
float: left; float: left;
} }
.group-name { .group-name {
font-weight: bold; font-weight: bold;
} }
.group-path { .group-path {
color: #999; color: #999;
} }
...@@ -239,6 +242,7 @@ ...@@ -239,6 +242,7 @@
color: #aaa; color: #aaa;
font-weight: normal; font-weight: normal;
} }
.namespace-path { .namespace-path {
margin-left: 10px; margin-left: 10px;
font-weight: bolder; font-weight: bolder;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
&:before { &:before {
background: none; background: none;
} }
.timeline-entry .timeline-entry-inner { .timeline-entry .timeline-entry-inner {
.timeline-icon { .timeline-icon {
display: none; display: none;
......
...@@ -48,31 +48,40 @@ ...@@ -48,31 +48,40 @@
.clearfix { .clearfix {
@include clearfix(); @include clearfix();
} }
.center-block { .center-block {
@include center-block(); @include center-block();
} }
.pull-right { .pull-right {
float: right !important; float: right !important;
} }
.pull-left { .pull-left {
float: left !important; float: left !important;
} }
.hide { .hide {
display: none; display: none;
} }
.show { .show {
display: block !important; display: block !important;
} }
.invisible { .invisible {
visibility: hidden; visibility: hidden;
} }
.text-hide { .text-hide {
@include text-hide(); @include text-hide();
} }
.hidden { .hidden {
display: none !important; display: none !important;
visibility: hidden !important; visibility: hidden !important;
} }
.affix { .affix {
position: fixed; position: fixed;
} }
...@@ -146,6 +155,7 @@ ...@@ -146,6 +155,7 @@
padding: 6px 15px; padding: 6px 15px;
font-size: 13px; font-size: 13px;
font-weight: normal; font-weight: normal;
a { a {
color: #777; color: #777;
} }
......
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
@extend .table-bordered; @extend .table-bordered;
margin: 12px 0; margin: 12px 0;
color: #5c5d5e; color: #5c5d5e;
th { th {
background: #f8fafc; background: #f8fafc;
} }
......
...@@ -55,68 +55,68 @@ ...@@ -55,68 +55,68 @@
color: #000 !important; color: #000 !important;
} }
.hll { background-color: #373b41 } .hll { background-color: #373b41; }
.c { color: #969896 } /* Comment */ .c { color: #969896; } /* Comment */
.err { color: #c66 } /* Error */ .err { color: #c66; } /* Error */
.k { color: #b294bb } /* Keyword */ .k { color: #b294bb; } /* Keyword */
.l { color: #de935f } /* Literal */ .l { color: #de935f; } /* Literal */
.n { color: #c5c8c6 } /* Name */ .n { color: #c5c8c6; } /* Name */
.o { color: #8abeb7 } /* Operator */ .o { color: #8abeb7; } /* Operator */
.p { color: #c5c8c6 } /* Punctuation */ .p { color: #c5c8c6; } /* Punctuation */
.cm { color: #969896 } /* Comment.Multiline */ .cm { color: #969896; } /* Comment.Multiline */
.cp { color: #969896 } /* Comment.Preproc */ .cp { color: #969896; } /* Comment.Preproc */
.c1 { color: #969896 } /* Comment.Single */ .c1 { color: #969896; } /* Comment.Single */
.cs { color: #969896 } /* Comment.Special */ .cs { color: #969896; } /* Comment.Special */
.gd { color: #c66 } /* Generic.Deleted */ .gd { color: #c66; } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */ .ge { font-style: italic; } /* Generic.Emph */
.gh { color: #c5c8c6; font-weight: bold } /* Generic.Heading */ .gh { color: #c5c8c6; font-weight: bold; } /* Generic.Heading */
.gi { color: #b5bd68 } /* Generic.Inserted */ .gi { color: #b5bd68; } /* Generic.Inserted */
.gp { color: #969896; font-weight: bold } /* Generic.Prompt */ .gp { color: #969896; font-weight: bold; } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */ .gs { font-weight: bold; } /* Generic.Strong */
.gu { color: #8abeb7; font-weight: bold } /* Generic.Subheading */ .gu { color: #8abeb7; font-weight: bold; } /* Generic.Subheading */
.kc { color: #b294bb } /* Keyword.Constant */ .kc { color: #b294bb; } /* Keyword.Constant */
.kd { color: #b294bb } /* Keyword.Declaration */ .kd { color: #b294bb; } /* Keyword.Declaration */
.kn { color: #8abeb7 } /* Keyword.Namespace */ .kn { color: #8abeb7; } /* Keyword.Namespace */
.kp { color: #b294bb } /* Keyword.Pseudo */ .kp { color: #b294bb; } /* Keyword.Pseudo */
.kr { color: #b294bb } /* Keyword.Reserved */ .kr { color: #b294bb; } /* Keyword.Reserved */
.kt { color: #f0c674 } /* Keyword.Type */ .kt { color: #f0c674; } /* Keyword.Type */
.ld { color: #b5bd68 } /* Literal.Date */ .ld { color: #b5bd68; } /* Literal.Date */
.m { color: #de935f } /* Literal.Number */ .m { color: #de935f; } /* Literal.Number */
.s { color: #b5bd68 } /* Literal.String */ .s { color: #b5bd68; } /* Literal.String */
.na { color: #81a2be } /* Name.Attribute */ .na { color: #81a2be; } /* Name.Attribute */
.nb { color: #c5c8c6 } /* Name.Builtin */ .nb { color: #c5c8c6; } /* Name.Builtin */
.nc { color: #f0c674 } /* Name.Class */ .nc { color: #f0c674; } /* Name.Class */
.no { color: #c66 } /* Name.Constant */ .no { color: #c66; } /* Name.Constant */
.nd { color: #8abeb7 } /* Name.Decorator */ .nd { color: #8abeb7; } /* Name.Decorator */
.ni { color: #c5c8c6 } /* Name.Entity */ .ni { color: #c5c8c6; } /* Name.Entity */
.ne { color: #c66 } /* Name.Exception */ .ne { color: #c66; } /* Name.Exception */
.nf { color: #81a2be } /* Name.Function */ .nf { color: #81a2be; } /* Name.Function */
.nl { color: #c5c8c6 } /* Name.Label */ .nl { color: #c5c8c6; } /* Name.Label */
.nn { color: #f0c674 } /* Name.Namespace */ .nn { color: #f0c674; } /* Name.Namespace */
.nx { color: #81a2be } /* Name.Other */ .nx { color: #81a2be; } /* Name.Other */
.py { color: #c5c8c6 } /* Name.Property */ .py { color: #c5c8c6; } /* Name.Property */
.nt { color: #8abeb7 } /* Name.Tag */ .nt { color: #8abeb7; } /* Name.Tag */
.nv { color: #c66 } /* Name.Variable */ .nv { color: #c66; } /* Name.Variable */
.ow { color: #8abeb7 } /* Operator.Word */ .ow { color: #8abeb7; } /* Operator.Word */
.w { color: #c5c8c6 } /* Text.Whitespace */ .w { color: #c5c8c6; } /* Text.Whitespace */
.mf { color: #de935f } /* Literal.Number.Float */ .mf { color: #de935f; } /* Literal.Number.Float */
.mh { color: #de935f } /* Literal.Number.Hex */ .mh { color: #de935f; } /* Literal.Number.Hex */
.mi { color: #de935f } /* Literal.Number.Integer */ .mi { color: #de935f; } /* Literal.Number.Integer */
.mo { color: #de935f } /* Literal.Number.Oct */ .mo { color: #de935f; } /* Literal.Number.Oct */
.sb { color: #b5bd68 } /* Literal.String.Backtick */ .sb { color: #b5bd68; } /* Literal.String.Backtick */
.sc { color: #c5c8c6 } /* Literal.String.Char */ .sc { color: #c5c8c6; } /* Literal.String.Char */
.sd { color: #969896 } /* Literal.String.Doc */ .sd { color: #969896; } /* Literal.String.Doc */
.s2 { color: #b5bd68 } /* Literal.String.Double */ .s2 { color: #b5bd68; } /* Literal.String.Double */
.se { color: #de935f } /* Literal.String.Escape */ .se { color: #de935f; } /* Literal.String.Escape */
.sh { color: #b5bd68 } /* Literal.String.Heredoc */ .sh { color: #b5bd68; } /* Literal.String.Heredoc */
.si { color: #de935f } /* Literal.String.Interpol */ .si { color: #de935f; } /* Literal.String.Interpol */
.sx { color: #b5bd68 } /* Literal.String.Other */ .sx { color: #b5bd68; } /* Literal.String.Other */
.sr { color: #b5bd68 } /* Literal.String.Regex */ .sr { color: #b5bd68; } /* Literal.String.Regex */
.s1 { color: #b5bd68 } /* Literal.String.Single */ .s1 { color: #b5bd68; } /* Literal.String.Single */
.ss { color: #b5bd68 } /* Literal.String.Symbol */ .ss { color: #b5bd68; } /* Literal.String.Symbol */
.bp { color: #c5c8c6 } /* Name.Builtin.Pseudo */ .bp { color: #c5c8c6; } /* Name.Builtin.Pseudo */
.vc { color: #c66 } /* Name.Variable.Class */ .vc { color: #c66; } /* Name.Variable.Class */
.vg { color: #c66 } /* Name.Variable.Global */ .vg { color: #c66; } /* Name.Variable.Global */
.vi { color: #c66 } /* Name.Variable.Instance */ .vi { color: #c66; } /* Name.Variable.Instance */
.il { color: #de935f } /* Literal.Number.Integer.Long */ .il { color: #de935f; } /* Literal.Number.Integer.Long */
} }
...@@ -55,65 +55,65 @@ ...@@ -55,65 +55,65 @@
color: #000 !important; color: #000 !important;
} }
.hll { background-color: #49483e } .hll { background-color: #49483e; }
.c { color: #75715e } /* Comment */ .c { color: #75715e; } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */ .err { color: #960050; background-color: #1e0010; } /* Error */
.k { color: #66d9ef } /* Keyword */ .k { color: #66d9ef; } /* Keyword */
.l { color: #ae81ff } /* Literal */ .l { color: #ae81ff; } /* Literal */
.n { color: #f8f8f2 } /* Name */ .n { color: #f8f8f2; } /* Name */
.o { color: #f92672 } /* Operator */ .o { color: #f92672; } /* Operator */
.p { color: #f8f8f2 } /* Punctuation */ .p { color: #f8f8f2; } /* Punctuation */
.cm { color: #75715e } /* Comment.Multiline */ .cm { color: #75715e; } /* Comment.Multiline */
.cp { color: #75715e } /* Comment.Preproc */ .cp { color: #75715e; } /* Comment.Preproc */
.c1 { color: #75715e } /* Comment.Single */ .c1 { color: #75715e; } /* Comment.Single */
.cs { color: #75715e } /* Comment.Special */ .cs { color: #75715e; } /* Comment.Special */
.ge { font-style: italic } /* Generic.Emph */ .ge { font-style: italic; } /* Generic.Emph */
.gs { font-weight: bold } /* Generic.Strong */ .gs { font-weight: bold; } /* Generic.Strong */
.kc { color: #66d9ef } /* Keyword.Constant */ .kc { color: #66d9ef; } /* Keyword.Constant */
.kd { color: #66d9ef } /* Keyword.Declaration */ .kd { color: #66d9ef; } /* Keyword.Declaration */
.kn { color: #f92672 } /* Keyword.Namespace */ .kn { color: #f92672; } /* Keyword.Namespace */
.kp { color: #66d9ef } /* Keyword.Pseudo */ .kp { color: #66d9ef; } /* Keyword.Pseudo */
.kr { color: #66d9ef } /* Keyword.Reserved */ .kr { color: #66d9ef; } /* Keyword.Reserved */
.kt { color: #66d9ef } /* Keyword.Type */ .kt { color: #66d9ef; } /* Keyword.Type */
.ld { color: #e6db74 } /* Literal.Date */ .ld { color: #e6db74; } /* Literal.Date */
.m { color: #ae81ff } /* Literal.Number */ .m { color: #ae81ff; } /* Literal.Number */
.s { color: #e6db74 } /* Literal.String */ .s { color: #e6db74; } /* Literal.String */
.na { color: #a6e22e } /* Name.Attribute */ .na { color: #a6e22e; } /* Name.Attribute */
.nb { color: #f8f8f2 } /* Name.Builtin */ .nb { color: #f8f8f2; } /* Name.Builtin */
.nc { color: #a6e22e } /* Name.Class */ .nc { color: #a6e22e; } /* Name.Class */
.no { color: #66d9ef } /* Name.Constant */ .no { color: #66d9ef; } /* Name.Constant */
.nd { color: #a6e22e } /* Name.Decorator */ .nd { color: #a6e22e; } /* Name.Decorator */
.ni { color: #f8f8f2 } /* Name.Entity */ .ni { color: #f8f8f2; } /* Name.Entity */
.ne { color: #a6e22e } /* Name.Exception */ .ne { color: #a6e22e; } /* Name.Exception */
.nf { color: #a6e22e } /* Name.Function */ .nf { color: #a6e22e; } /* Name.Function */
.nl { color: #f8f8f2 } /* Name.Label */ .nl { color: #f8f8f2; } /* Name.Label */
.nn { color: #f8f8f2 } /* Name.Namespace */ .nn { color: #f8f8f2; } /* Name.Namespace */
.nx { color: #a6e22e } /* Name.Other */ .nx { color: #a6e22e; } /* Name.Other */
.py { color: #f8f8f2 } /* Name.Property */ .py { color: #f8f8f2; } /* Name.Property */
.nt { color: #f92672 } /* Name.Tag */ .nt { color: #f92672; } /* Name.Tag */
.nv { color: #f8f8f2 } /* Name.Variable */ .nv { color: #f8f8f2; } /* Name.Variable */
.ow { color: #f92672 } /* Operator.Word */ .ow { color: #f92672; } /* Operator.Word */
.w { color: #f8f8f2 } /* Text.Whitespace */ .w { color: #f8f8f2; } /* Text.Whitespace */
.mf { color: #ae81ff } /* Literal.Number.Float */ .mf { color: #ae81ff; } /* Literal.Number.Float */
.mh { color: #ae81ff } /* Literal.Number.Hex */ .mh { color: #ae81ff; } /* Literal.Number.Hex */
.mi { color: #ae81ff } /* Literal.Number.Integer */ .mi { color: #ae81ff; } /* Literal.Number.Integer */
.mo { color: #ae81ff } /* Literal.Number.Oct */ .mo { color: #ae81ff; } /* Literal.Number.Oct */
.sb { color: #e6db74 } /* Literal.String.Backtick */ .sb { color: #e6db74; } /* Literal.String.Backtick */
.sc { color: #e6db74 } /* Literal.String.Char */ .sc { color: #e6db74; } /* Literal.String.Char */
.sd { color: #e6db74 } /* Literal.String.Doc */ .sd { color: #e6db74; } /* Literal.String.Doc */
.s2 { color: #e6db74 } /* Literal.String.Double */ .s2 { color: #e6db74; } /* Literal.String.Double */
.se { color: #ae81ff } /* Literal.String.Escape */ .se { color: #ae81ff; } /* Literal.String.Escape */
.sh { color: #e6db74 } /* Literal.String.Heredoc */ .sh { color: #e6db74; } /* Literal.String.Heredoc */
.si { color: #e6db74 } /* Literal.String.Interpol */ .si { color: #e6db74; } /* Literal.String.Interpol */
.sx { color: #e6db74 } /* Literal.String.Other */ .sx { color: #e6db74; } /* Literal.String.Other */
.sr { color: #e6db74 } /* Literal.String.Regex */ .sr { color: #e6db74; } /* Literal.String.Regex */
.s1 { color: #e6db74 } /* Literal.String.Single */ .s1 { color: #e6db74; } /* Literal.String.Single */
.ss { color: #e6db74 } /* Literal.String.Symbol */ .ss { color: #e6db74; } /* Literal.String.Symbol */
.bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .bp { color: #f8f8f2; } /* Name.Builtin.Pseudo */
.vc { color: #f8f8f2 } /* Name.Variable.Class */ .vc { color: #f8f8f2; } /* Name.Variable.Class */
.vg { color: #f8f8f2 } /* Name.Variable.Global */ .vg { color: #f8f8f2; } /* Name.Variable.Global */
.vi { color: #f8f8f2 } /* Name.Variable.Instance */ .vi { color: #f8f8f2; } /* Name.Variable.Instance */
.il { color: #ae81ff } /* Literal.Number.Integer.Long */ .il { color: #ae81ff; } /* Literal.Number.Integer.Long */
.gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
.gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
.gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
......
...@@ -72,72 +72,72 @@ ...@@ -72,72 +72,72 @@
green #859900 operators, other keywords green #859900 operators, other keywords
*/ */
.c { color: #586e75 } /* Comment */ .c { color: #586e75; } /* Comment */
.err { color: #93a1a1 } /* Error */ .err { color: #93a1a1; } /* Error */
.g { color: #93a1a1 } /* Generic */ .g { color: #93a1a1; } /* Generic */
.k { color: #859900 } /* Keyword */ .k { color: #859900; } /* Keyword */
.l { color: #93a1a1 } /* Literal */ .l { color: #93a1a1; } /* Literal */
.n { color: #93a1a1 } /* Name */ .n { color: #93a1a1; } /* Name */
.o { color: #859900 } /* Operator */ .o { color: #859900; } /* Operator */
.x { color: #cb4b16 } /* Other */ .x { color: #cb4b16; } /* Other */
.p { color: #93a1a1 } /* Punctuation */ .p { color: #93a1a1; } /* Punctuation */
.cm { color: #586e75 } /* Comment.Multiline */ .cm { color: #586e75; } /* Comment.Multiline */
.cp { color: #859900 } /* Comment.Preproc */ .cp { color: #859900; } /* Comment.Preproc */
.c1 { color: #586e75 } /* Comment.Single */ .c1 { color: #586e75; } /* Comment.Single */
.cs { color: #859900 } /* Comment.Special */ .cs { color: #859900; } /* Comment.Special */
.gd { color: #2aa198 } /* Generic.Deleted */ .gd { color: #2aa198; } /* Generic.Deleted */
.ge { color: #93a1a1; font-style: italic } /* Generic.Emph */ .ge { color: #93a1a1; font-style: italic; } /* Generic.Emph */
.gr { color: #dc322f } /* Generic.Error */ .gr { color: #dc322f; } /* Generic.Error */
.gh { color: #cb4b16 } /* Generic.Heading */ .gh { color: #cb4b16; } /* Generic.Heading */
.gi { color: #859900 } /* Generic.Inserted */ .gi { color: #859900; } /* Generic.Inserted */
.go { color: #93a1a1 } /* Generic.Output */ .go { color: #93a1a1; } /* Generic.Output */
.gp { color: #93a1a1 } /* Generic.Prompt */ .gp { color: #93a1a1; } /* Generic.Prompt */
.gs { color: #93a1a1; font-weight: bold } /* Generic.Strong */ .gs { color: #93a1a1; font-weight: bold; } /* Generic.Strong */
.gu { color: #cb4b16 } /* Generic.Subheading */ .gu { color: #cb4b16; } /* Generic.Subheading */
.gt { color: #93a1a1 } /* Generic.Traceback */ .gt { color: #93a1a1; } /* Generic.Traceback */
.kc { color: #cb4b16 } /* Keyword.Constant */ .kc { color: #cb4b16; } /* Keyword.Constant */
.kd { color: #268bd2 } /* Keyword.Declaration */ .kd { color: #268bd2; } /* Keyword.Declaration */
.kn { color: #859900 } /* Keyword.Namespace */ .kn { color: #859900; } /* Keyword.Namespace */
.kp { color: #859900 } /* Keyword.Pseudo */ .kp { color: #859900; } /* Keyword.Pseudo */
.kr { color: #268bd2 } /* Keyword.Reserved */ .kr { color: #268bd2; } /* Keyword.Reserved */
.kt { color: #dc322f } /* Keyword.Type */ .kt { color: #dc322f; } /* Keyword.Type */
.ld { color: #93a1a1 } /* Literal.Date */ .ld { color: #93a1a1; } /* Literal.Date */
.m { color: #2aa198 } /* Literal.Number */ .m { color: #2aa198; } /* Literal.Number */
.s { color: #2aa198 } /* Literal.String */ .s { color: #2aa198; } /* Literal.String */
.na { color: #93a1a1 } /* Name.Attribute */ .na { color: #93a1a1; } /* Name.Attribute */
.nb { color: #b58900 } /* Name.Builtin */ .nb { color: #b58900; } /* Name.Builtin */
.nc { color: #268bd2 } /* Name.Class */ .nc { color: #268bd2; } /* Name.Class */
.no { color: #cb4b16 } /* Name.Constant */ .no { color: #cb4b16; } /* Name.Constant */
.nd { color: #268bd2 } /* Name.Decorator */ .nd { color: #268bd2; } /* Name.Decorator */
.ni { color: #cb4b16 } /* Name.Entity */ .ni { color: #cb4b16; } /* Name.Entity */
.ne { color: #cb4b16 } /* Name.Exception */ .ne { color: #cb4b16; } /* Name.Exception */
.nf { color: #268bd2 } /* Name.Function */ .nf { color: #268bd2; } /* Name.Function */
.nl { color: #93a1a1 } /* Name.Label */ .nl { color: #93a1a1; } /* Name.Label */
.nn { color: #93a1a1 } /* Name.Namespace */ .nn { color: #93a1a1; } /* Name.Namespace */
.nx { color: #93a1a1 } /* Name.Other */ .nx { color: #93a1a1; } /* Name.Other */
.py { color: #93a1a1 } /* Name.Property */ .py { color: #93a1a1; } /* Name.Property */
.nt { color: #268bd2 } /* Name.Tag */ .nt { color: #268bd2; } /* Name.Tag */
.nv { color: #268bd2 } /* Name.Variable */ .nv { color: #268bd2; } /* Name.Variable */
.ow { color: #859900 } /* Operator.Word */ .ow { color: #859900; } /* Operator.Word */
.w { color: #93a1a1 } /* Text.Whitespace */ .w { color: #93a1a1; } /* Text.Whitespace */
.mf { color: #2aa198 } /* Literal.Number.Float */ .mf { color: #2aa198; } /* Literal.Number.Float */
.mh { color: #2aa198 } /* Literal.Number.Hex */ .mh { color: #2aa198; } /* Literal.Number.Hex */
.mi { color: #2aa198 } /* Literal.Number.Integer */ .mi { color: #2aa198; } /* Literal.Number.Integer */
.mo { color: #2aa198 } /* Literal.Number.Oct */ .mo { color: #2aa198; } /* Literal.Number.Oct */
.sb { color: #586e75 } /* Literal.String.Backtick */ .sb { color: #586e75; } /* Literal.String.Backtick */
.sc { color: #2aa198 } /* Literal.String.Char */ .sc { color: #2aa198; } /* Literal.String.Char */
.sd { color: #93a1a1 } /* Literal.String.Doc */ .sd { color: #93a1a1; } /* Literal.String.Doc */
.s2 { color: #2aa198 } /* Literal.String.Double */ .s2 { color: #2aa198; } /* Literal.String.Double */
.se { color: #cb4b16 } /* Literal.String.Escape */ .se { color: #cb4b16; } /* Literal.String.Escape */
.sh { color: #93a1a1 } /* Literal.String.Heredoc */ .sh { color: #93a1a1; } /* Literal.String.Heredoc */
.si { color: #2aa198 } /* Literal.String.Interpol */ .si { color: #2aa198; } /* Literal.String.Interpol */
.sx { color: #2aa198 } /* Literal.String.Other */ .sx { color: #2aa198; } /* Literal.String.Other */
.sr { color: #dc322f } /* Literal.String.Regex */ .sr { color: #dc322f; } /* Literal.String.Regex */
.s1 { color: #2aa198 } /* Literal.String.Single */ .s1 { color: #2aa198; } /* Literal.String.Single */
.ss { color: #2aa198 } /* Literal.String.Symbol */ .ss { color: #2aa198; } /* Literal.String.Symbol */
.bp { color: #268bd2 } /* Name.Builtin.Pseudo */ .bp { color: #268bd2; } /* Name.Builtin.Pseudo */
.vc { color: #268bd2 } /* Name.Variable.Class */ .vc { color: #268bd2; } /* Name.Variable.Class */
.vg { color: #268bd2 } /* Name.Variable.Global */ .vg { color: #268bd2; } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */ .vi { color: #268bd2; } /* Name.Variable.Instance */
.il { color: #2aa198 } /* Literal.Number.Integer.Long */ .il { color: #2aa198; } /* Literal.Number.Integer.Long */
} }
...@@ -78,72 +78,72 @@ ...@@ -78,72 +78,72 @@
green #859900 operators, other keywords green #859900 operators, other keywords
*/ */
.c { color: #93a1a1 } /* Comment */ .c { color: #93a1a1; } /* Comment */
.err { color: #586e75 } /* Error */ .err { color: #586e75; } /* Error */
.g { color: #586e75 } /* Generic */ .g { color: #586e75; } /* Generic */
.k { color: #859900 } /* Keyword */ .k { color: #859900; } /* Keyword */
.l { color: #586e75 } /* Literal */ .l { color: #586e75; } /* Literal */
.n { color: #586e75 } /* Name */ .n { color: #586e75; } /* Name */
.o { color: #859900 } /* Operator */ .o { color: #859900; } /* Operator */
.x { color: #cb4b16 } /* Other */ .x { color: #cb4b16; } /* Other */
.p { color: #586e75 } /* Punctuation */ .p { color: #586e75; } /* Punctuation */
.cm { color: #93a1a1 } /* Comment.Multiline */ .cm { color: #93a1a1; } /* Comment.Multiline */
.cp { color: #859900 } /* Comment.Preproc */ .cp { color: #859900; } /* Comment.Preproc */
.c1 { color: #93a1a1 } /* Comment.Single */ .c1 { color: #93a1a1; } /* Comment.Single */
.cs { color: #859900 } /* Comment.Special */ .cs { color: #859900; } /* Comment.Special */
.gd { color: #2aa198 } /* Generic.Deleted */ .gd { color: #2aa198; } /* Generic.Deleted */
.ge { color: #586e75; font-style: italic } /* Generic.Emph */ .ge { color: #586e75; font-style: italic; } /* Generic.Emph */
.gr { color: #dc322f } /* Generic.Error */ .gr { color: #dc322f; } /* Generic.Error */
.gh { color: #cb4b16 } /* Generic.Heading */ .gh { color: #cb4b16; } /* Generic.Heading */
.gi { color: #859900 } /* Generic.Inserted */ .gi { color: #859900; } /* Generic.Inserted */
.go { color: #586e75 } /* Generic.Output */ .go { color: #586e75; } /* Generic.Output */
.gp { color: #586e75 } /* Generic.Prompt */ .gp { color: #586e75; } /* Generic.Prompt */
.gs { color: #586e75; font-weight: bold } /* Generic.Strong */ .gs { color: #586e75; font-weight: bold; } /* Generic.Strong */
.gu { color: #cb4b16 } /* Generic.Subheading */ .gu { color: #cb4b16; } /* Generic.Subheading */
.gt { color: #586e75 } /* Generic.Traceback */ .gt { color: #586e75; } /* Generic.Traceback */
.kc { color: #cb4b16 } /* Keyword.Constant */ .kc { color: #cb4b16; } /* Keyword.Constant */
.kd { color: #268bd2 } /* Keyword.Declaration */ .kd { color: #268bd2; } /* Keyword.Declaration */
.kn { color: #859900 } /* Keyword.Namespace */ .kn { color: #859900; } /* Keyword.Namespace */
.kp { color: #859900 } /* Keyword.Pseudo */ .kp { color: #859900; } /* Keyword.Pseudo */
.kr { color: #268bd2 } /* Keyword.Reserved */ .kr { color: #268bd2; } /* Keyword.Reserved */
.kt { color: #dc322f } /* Keyword.Type */ .kt { color: #dc322f; } /* Keyword.Type */
.ld { color: #586e75 } /* Literal.Date */ .ld { color: #586e75; } /* Literal.Date */
.m { color: #2aa198 } /* Literal.Number */ .m { color: #2aa198; } /* Literal.Number */
.s { color: #2aa198 } /* Literal.String */ .s { color: #2aa198; } /* Literal.String */
.na { color: #586e75 } /* Name.Attribute */ .na { color: #586e75; } /* Name.Attribute */
.nb { color: #b58900 } /* Name.Builtin */ .nb { color: #b58900; } /* Name.Builtin */
.nc { color: #268bd2 } /* Name.Class */ .nc { color: #268bd2; } /* Name.Class */
.no { color: #cb4b16 } /* Name.Constant */ .no { color: #cb4b16; } /* Name.Constant */
.nd { color: #268bd2 } /* Name.Decorator */ .nd { color: #268bd2; } /* Name.Decorator */
.ni { color: #cb4b16 } /* Name.Entity */ .ni { color: #cb4b16; } /* Name.Entity */
.ne { color: #cb4b16 } /* Name.Exception */ .ne { color: #cb4b16; } /* Name.Exception */
.nf { color: #268bd2 } /* Name.Function */ .nf { color: #268bd2; } /* Name.Function */
.nl { color: #586e75 } /* Name.Label */ .nl { color: #586e75; } /* Name.Label */
.nn { color: #586e75 } /* Name.Namespace */ .nn { color: #586e75; } /* Name.Namespace */
.nx { color: #586e75 } /* Name.Other */ .nx { color: #586e75; } /* Name.Other */
.py { color: #586e75 } /* Name.Property */ .py { color: #586e75; } /* Name.Property */
.nt { color: #268bd2 } /* Name.Tag */ .nt { color: #268bd2; } /* Name.Tag */
.nv { color: #268bd2 } /* Name.Variable */ .nv { color: #268bd2; } /* Name.Variable */
.ow { color: #859900 } /* Operator.Word */ .ow { color: #859900; } /* Operator.Word */
.w { color: #586e75 } /* Text.Whitespace */ .w { color: #586e75; } /* Text.Whitespace */
.mf { color: #2aa198 } /* Literal.Number.Float */ .mf { color: #2aa198; } /* Literal.Number.Float */
.mh { color: #2aa198 } /* Literal.Number.Hex */ .mh { color: #2aa198; } /* Literal.Number.Hex */
.mi { color: #2aa198 } /* Literal.Number.Integer */ .mi { color: #2aa198; } /* Literal.Number.Integer */
.mo { color: #2aa198 } /* Literal.Number.Oct */ .mo { color: #2aa198; } /* Literal.Number.Oct */
.sb { color: #93a1a1 } /* Literal.String.Backtick */ .sb { color: #93a1a1; } /* Literal.String.Backtick */
.sc { color: #2aa198 } /* Literal.String.Char */ .sc { color: #2aa198; } /* Literal.String.Char */
.sd { color: #586e75 } /* Literal.String.Doc */ .sd { color: #586e75; } /* Literal.String.Doc */
.s2 { color: #2aa198 } /* Literal.String.Double */ .s2 { color: #2aa198; } /* Literal.String.Double */
.se { color: #cb4b16 } /* Literal.String.Escape */ .se { color: #cb4b16; } /* Literal.String.Escape */
.sh { color: #586e75 } /* Literal.String.Heredoc */ .sh { color: #586e75; } /* Literal.String.Heredoc */
.si { color: #2aa198 } /* Literal.String.Interpol */ .si { color: #2aa198; } /* Literal.String.Interpol */
.sx { color: #2aa198 } /* Literal.String.Other */ .sx { color: #2aa198; } /* Literal.String.Other */
.sr { color: #dc322f } /* Literal.String.Regex */ .sr { color: #dc322f; } /* Literal.String.Regex */
.s1 { color: #2aa198 } /* Literal.String.Single */ .s1 { color: #2aa198; } /* Literal.String.Single */
.ss { color: #2aa198 } /* Literal.String.Symbol */ .ss { color: #2aa198; } /* Literal.String.Symbol */
.bp { color: #268bd2 } /* Name.Builtin.Pseudo */ .bp { color: #268bd2; } /* Name.Builtin.Pseudo */
.vc { color: #268bd2 } /* Name.Variable.Class */ .vc { color: #268bd2; } /* Name.Variable.Class */
.vg { color: #268bd2 } /* Name.Variable.Global */ .vg { color: #268bd2; } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */ .vi { color: #268bd2; } /* Name.Variable.Instance */
.il { color: #2aa198 } /* Literal.Number.Integer.Long */ .il { color: #2aa198; } /* Literal.Number.Integer.Long */
} }
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
background-color: #fafe3d !important; background-color: #fafe3d !important;
} }
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8; }
.c { color: #998; font-style: italic; } .c { color: #998; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
.k { font-weight: bold; } .k { font-weight: bold; }
......
...@@ -78,7 +78,7 @@ span.highlight_word { ...@@ -78,7 +78,7 @@ span.highlight_word {
background-color: #fafe3d !important; background-color: #fafe3d !important;
} }
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8; }
.c { color: #998; font-style: italic; } .c { color: #998; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
.k { font-weight: bold; } .k { font-weight: bold; }
......
...@@ -2,22 +2,28 @@ img { ...@@ -2,22 +2,28 @@ img {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
} }
p.details { p.details {
font-style: italic; font-style: italic;
color: #777 color: #777;
} }
.footer > p { .footer > p {
font-size: small; font-size: small;
color: #777 color: #777;
} }
pre.commit-message { pre.commit-message {
white-space: pre-wrap; white-space: pre-wrap;
} }
.file-stats > a { .file-stats > a {
text-decoration: none; text-decoration: none;
> .new-file { > .new-file {
color: #090; color: #090;
} }
> .deleted-file { > .deleted-file {
color: #b00; color: #b00;
} }
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
.admin-filter form { .admin-filter form {
.select2-container { .select2-container {
width: 100% width: 100%;
} }
.controls { .controls {
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
.form-actions { .form-actions {
padding-left: 130px; padding-left: 130px;
background: #fff background: #fff;
} }
.visibility-levels { .visibility-levels {
...@@ -106,26 +106,33 @@ ...@@ -106,26 +106,33 @@
.table { .table {
table-layout: fixed; table-layout: fixed;
} }
.subheading { .subheading {
padding-bottom: $gl-padding; padding-bottom: $gl-padding;
} }
.message { .message {
word-wrap: break-word; word-wrap: break-word;
} }
.btn { .btn {
white-space: normal; white-space: normal;
padding: $gl-btn-padding; padding: $gl-btn-padding;
} }
th { th {
width: 15%; width: 15%;
&.wide { &.wide {
width: 55%; width: 55%;
} }
} }
@media (max-width: $screen-sm-max) { @media (max-width: $screen-sm-max) {
th { th {
width: 100%; width: 100%;
} }
td { td {
width: 100%; width: 100%;
float: left; float: left;
...@@ -137,6 +144,7 @@ ...@@ -137,6 +144,7 @@
margin-left: $btn-side-margin; margin-left: $btn-side-margin;
margin-top: 3px; margin-top: 3px;
} }
span { span {
font-size: 19px; font-size: 19px;
} }
......
...@@ -137,6 +137,7 @@ ...@@ -137,6 +137,7 @@
.retry-link { .retry-link {
color: $gl-link-color; color: $gl-link-color;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
...@@ -218,6 +219,7 @@ ...@@ -218,6 +219,7 @@
.build-detail-row { .build-detail-row {
margin-bottom: 5px; margin-bottom: 5px;
&:last-of-type { &:last-of-type {
margin-bottom: 0; margin-bottom: 0;
} }
...@@ -233,3 +235,9 @@ ...@@ -233,3 +235,9 @@
right: 0; right: 0;
margin-top: -17px; margin-top: -17px;
} }
@media (min-width: $screen-md-min) {
.sub-nav.build {
width: calc(100% + #{$gutter_width});
}
}
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
margin-left: 4px; margin-left: 4px;
} }
} }
.commit-committer-link, .commit-committer-link,
.commit-author-link { .commit-author-link {
color: $gl-gray; color: $gl-gray;
...@@ -108,21 +109,25 @@ ...@@ -108,21 +109,25 @@
line-height: 20px; line-height: 20px;
} }
} }
.new-file { .new-file {
a { a {
color: $gl-text-green; color: $gl-text-green;
} }
} }
.renamed-file { .renamed-file {
a { a {
color: $gl-text-orange; color: $gl-text-orange;
} }
} }
.deleted-file { .deleted-file {
a { a {
color: $gl-text-red; color: $gl-text-red;
} }
} }
.edit-file { .edit-file {
a { a {
color: $gl-text-color; color: $gl-text-color;
...@@ -158,6 +163,7 @@ ...@@ -158,6 +163,7 @@
position: absolute; position: absolute;
z-index: 1; z-index: 1;
} }
> textarea { > textarea {
background-color: rgba(0, 0, 0, 0.0); background-color: rgba(0, 0, 0, 0.0);
font-family: inherit; font-family: inherit;
......
...@@ -161,6 +161,7 @@ ...@@ -161,6 +161,7 @@
.branch-commit { .branch-commit {
color: $gl-gray; color: $gl-gray;
.commit-id, .commit-row-message { .commit-id, .commit-row-message {
color: $gl-gray; color: $gl-gray;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
background: $background-color; background: $background-color;
border-top-left-radius: 0; border-top-left-radius: 0;
} }
border-top-left-radius: 0; border-top-left-radius: 0;
} }
} }
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
float: left; float: left;
@extend .col-md-2; @extend .col-md-2;
} }
.btn { .btn {
margin-left: 5px; margin-left: 5px;
float: left; float: left;
......
...@@ -33,6 +33,19 @@ ...@@ -33,6 +33,19 @@
font-size: smaller; font-size: smaller;
} }
} }
.file-title {
cursor: pointer;
&:hover {
background-color: $dark-background-color;
}
.diff-toggle-caret {
padding-right: 6px;
}
}
.diff-content { .diff-content {
overflow: auto; overflow: auto;
overflow-y: hidden; overflow-y: hidden;
...@@ -123,15 +136,18 @@ ...@@ -123,15 +136,18 @@
max-width: 50px; max-width: 50px;
width: 35px; width: 35px;
@include user-select(none); @include user-select(none);
a { a {
float: left; float: left;
width: 35px; width: 35px;
font-weight: normal; font-weight: normal;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
} }
.line_content { .line_content {
display: block; display: block;
margin: 0; margin: 0;
...@@ -151,10 +167,12 @@ ...@@ -151,10 +167,12 @@
white-space: pre-wrap; white-space: pre-wrap;
} }
} }
.image { .image {
background: #ddd; background: #ddd;
text-align: center; text-align: center;
padding: 30px; padding: 30px;
.wrap { .wrap {
display: inline-block; display: inline-block;
} }
...@@ -163,6 +181,7 @@ ...@@ -163,6 +181,7 @@
display: inline-block; display: inline-block;
background-color: #fff; background-color: #fff;
line-height: 0; line-height: 0;
img { img {
border: 1px solid #fff; border: 1px solid #fff;
background-image: linear-gradient(45deg, #e5e5e5 25%, transparent 25%, transparent 75%, #e5e5e5 75%, #e5e5e5 100%), background-image: linear-gradient(45deg, #e5e5e5 25%, transparent 25%, transparent 75%, #e5e5e5 75%, #e5e5e5 100%),
...@@ -171,6 +190,7 @@ ...@@ -171,6 +190,7 @@
background-position: 0 0, 5px 5px; background-position: 0 0, 5px 5px;
max-width: 100%; max-width: 100%;
} }
&.deleted { &.deleted {
border: 1px solid $deleted; border: 1px solid $deleted;
} }
...@@ -179,6 +199,7 @@ ...@@ -179,6 +199,7 @@
border: 1px solid $added; border: 1px solid $added;
} }
} }
.image-info { .image-info {
font-size: 12px; font-size: 12px;
margin: 5px 0 0; margin: 5px 0 0;
...@@ -193,6 +214,7 @@ ...@@ -193,6 +214,7 @@
margin: auto; margin: auto;
position: relative; position: relative;
} }
.swipe-wrap { .swipe-wrap {
overflow: hidden; overflow: hidden;
border-left: 1px solid #999; border-left: 1px solid #999;
...@@ -201,10 +223,12 @@ ...@@ -201,10 +223,12 @@
top: 13px; top: 13px;
right: 7px; right: 7px;
} }
.frame { .frame {
top: 0; top: 0;
right: 0; right: 0;
position: absolute; position: absolute;
&.deleted { &.deleted {
margin: 0; margin: 0;
display: block; display: block;
...@@ -212,6 +236,7 @@ ...@@ -212,6 +236,7 @@
right: 7px; right: 7px;
} }
} }
.swipe-bar { .swipe-bar {
display: block; display: block;
height: 100%; height: 100%;
...@@ -219,14 +244,17 @@ ...@@ -219,14 +244,17 @@
z-index: 100; z-index: 100;
position: absolute; position: absolute;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
.top-handle { .top-handle {
background-position: -15px 3px; background-position: -15px 3px;
} }
.bottom-handle { .bottom-handle {
background-position: -15px -11px; background-position: -15px -11px;
} }
} }
.top-handle { .top-handle {
display: block; display: block;
height: 14px; height: 14px;
...@@ -235,6 +263,7 @@ ...@@ -235,6 +263,7 @@
top: 0; top: 0;
background: image-url('swipemode_sprites.gif') 0 3px no-repeat; background: image-url('swipemode_sprites.gif') 0 3px no-repeat;
} }
.bottom-handle { .bottom-handle {
display: block; display: block;
height: 14px; height: 14px;
...@@ -252,12 +281,14 @@ ...@@ -252,12 +281,14 @@
margin: auto; margin: auto;
position: relative; position: relative;
} }
.frame.added, .frame.deleted { .frame.added, .frame.deleted {
position: absolute; position: absolute;
display: block; display: block;
top: 0; top: 0;
left: 0; left: 0;
} }
.controls { .controls {
display: block; display: block;
height: 14px; height: 14px;
...@@ -311,6 +342,7 @@ ...@@ -311,6 +342,7 @@
} }
//.view.onion-skin //.view.onion-skin
} }
.view-modes { .view-modes {
padding: 10px; padding: 10px;
text-align: center; text-align: center;
...@@ -328,19 +360,24 @@ ...@@ -328,19 +360,24 @@
border-left: 1px solid #c1c1c1; border-left: 1px solid #c1c1c1;
padding: 0 12px 0 16px; padding: 0 12px 0 16px;
cursor: pointer; cursor: pointer;
&:first-child { &:first-child {
border-left: none; border-left: none;
} }
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
&.active { &.active {
&:hover { &:hover {
text-decoration: none; text-decoration: none;
} }
cursor: default; cursor: default;
color: #333; color: #333;
} }
&.disabled { &.disabled {
display: none; display: none;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
.cancel-btn { .cancel-btn {
color: #b94a48; color: #b94a48;
&:hover { &:hover {
color: #b94a48; color: #b94a48;
} }
...@@ -70,16 +71,20 @@ ...@@ -70,16 +71,20 @@
.soft-wrap-toggle { .soft-wrap-toggle {
margin: 0 $btn-side-margin; margin: 0 $btn-side-margin;
.soft-wrap { .soft-wrap {
display: block; display: block;
} }
.no-wrap { .no-wrap {
display: none; display: none;
} }
&.soft-wrap-active { &.soft-wrap-active {
.soft-wrap { .soft-wrap {
display: none; display: none;
} }
.no-wrap { .no-wrap {
display: block; display: block;
} }
......
...@@ -52,13 +52,13 @@ ...@@ -52,13 +52,13 @@
} }
} }
.table.builds.environments { .table.ci-table.environments {
.icon-container { .icon-container {
width: 20px; width: 20px;
text-align: center; text-align: center;
} }
.branch-commit { .branch-commit {
.commit-id { .commit-id {
margin-right: 0; margin-right: 0;
......
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
margin-bottom: 0; margin-bottom: 0;
} }
} }
.event-note-icon { .event-note-icon {
color: #777; color: #777;
float: left; float: left;
...@@ -86,6 +87,7 @@ ...@@ -86,6 +87,7 @@
margin-right: 5px; margin-right: 5px;
} }
} }
.event_icon { .event_icon {
position: relative; position: relative;
float: right; float: right;
...@@ -95,12 +97,13 @@ ...@@ -95,12 +97,13 @@
background: $gray-light; background: $gray-light;
margin-left: 10px; margin-left: 10px;
top: -6px; top: -6px;
img { img {
width: 20px; width: 20px;
} }
} }
&:last-child { border: none } &:last-child { border: none; }
.event_commits { .event_commits {
li { li {
...@@ -109,6 +112,7 @@ ...@@ -109,6 +112,7 @@
padding: 3px; padding: 3px;
padding-left: 0; padding-left: 0;
border: none; border: none;
.commit-row-title { .commit-row-title {
font-size: $gl-font-size; font-size: $gl-font-size;
} }
...@@ -117,6 +121,7 @@ ...@@ -117,6 +121,7 @@
&.commits-stat { &.commits-stat {
display: block; display: block;
padding: 0 3px 0 0; padding: 0 3px 0 0;
&:hover { &:hover {
background: none; background: none;
} }
...@@ -158,6 +163,7 @@ ...@@ -158,6 +163,7 @@
overflow: visible; overflow: visible;
max-width: 100%; max-width: 100%;
} }
.avatar { .avatar {
display: none; display: none;
} }
......
.member-search-form {
float: left;
input[type='search'] {
width: 225px;
vertical-align: bottom;
@media (max-width: $screen-xs-max) {
width: 100px;
vertical-align: bottom;
}
}
}
.milestone-row { .milestone-row {
@include str-truncated(90%); @include str-truncated(90%);
} }
...@@ -48,6 +34,7 @@ ...@@ -48,6 +34,7 @@
.group-right-buttons { .group-right-buttons {
position: absolute; position: absolute;
right: 16px; right: 16px;
.btn { .btn {
@include btn-gray; @include btn-gray;
padding: 3px 10px; padding: 3px 10px;
......
...@@ -23,28 +23,28 @@ ...@@ -23,28 +23,28 @@
color: #555; color: #555;
tbody:first-child tr:first-child { tbody:first-child tr:first-child {
padding-top: 0 padding-top: 0;
} }
th { th {
padding-top: 15px; padding-top: 15px;
line-height: 1.5; line-height: 1.5;
color: #333; color: #333;
text-align: left text-align: left;
} }
td { td {
padding-top: 3px; padding-top: 3px;
padding-bottom: 3px; padding-bottom: 3px;
vertical-align: top; vertical-align: top;
line-height: 20px line-height: 20px;
} }
.shortcut { .shortcut {
padding-right: 10px; padding-right: 10px;
color: #999; color: #999;
text-align: right; text-align: right;
white-space: nowrap white-space: nowrap;
} }
.key { .key {
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
margin-right: 5px; margin-right: 5px;
margin-bottom: 5px; margin-bottom: 5px;
display: inline-block; display: inline-block;
.color-label { .color-label {
padding: 6px 10px; padding: 6px 10px;
} }
...@@ -128,7 +129,7 @@ ...@@ -128,7 +129,7 @@
} }
.selectbox { .selectbox {
display: none display: none;
} }
.btn-clipboard { .btn-clipboard {
...@@ -199,7 +200,7 @@ ...@@ -199,7 +200,7 @@
display: none; display: none;
/* Small devices (tablets, 768px and up) */ /* Small devices (tablets, 768px and up) */
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
display: block display: block;
} }
width: $sidebar_collapsed_width; width: $sidebar_collapsed_width;
...@@ -276,7 +277,7 @@ ...@@ -276,7 +277,7 @@
} }
&.btn-primary { &.btn-primary {
@extend .btn-primary @extend .btn-primary;
} }
} }
...@@ -400,6 +401,7 @@ ...@@ -400,6 +401,7 @@
.js-issuable-selector { .js-issuable-selector {
width: 100%; width: 100%;
} }
@media (max-width: $screen-sm-max) { @media (max-width: $screen-sm-max) {
margin-bottom: $gl-padding; margin-bottom: $gl-padding;
} }
......
...@@ -37,6 +37,7 @@ ul.related-merge-requests > li { ...@@ -37,6 +37,7 @@ ul.related-merge-requests > li {
display: -ms-flexbox; display: -ms-flexbox;
display: -webkit-flex; display: -webkit-flex;
display: flex; display: flex;
.merge-request-id { .merge-request-id {
flex-shrink: 0; flex-shrink: 0;
} }
......
.suggest-colors { .suggest-colors {
margin-top: 5px; margin-top: 5px;
a { a {
border-radius: 4px; border-radius: 4px;
width: 30px; width: 30px;
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
font-size: 19px; font-size: 19px;
color: red; color: red;
} }
.correct-syntax { .correct-syntax {
font-size: 19px; font-size: 19px;
color: #47a447; color: #47a447;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
line-height: 1.5; line-height: 1.5;
p { p {
font-size: 18px;
color: #888; color: #888;
} }
...@@ -36,10 +37,14 @@ ...@@ -36,10 +37,14 @@
} }
} }
.login-box { p {
background: #fafafa; font-size: 13px;
border-radius: 10px; }
box-shadow: 0 0 2px #ccc;
.login-box, .omniauth-container {
box-shadow: 0 0 0 1px $border-color;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
padding: 15px; padding: 15px;
.login-heading h3 { .login-heading h3 {
...@@ -58,42 +63,127 @@ ...@@ -58,42 +63,127 @@
a.forgot { a.forgot {
float: right; float: right;
padding-top: 6px padding-top: 6px;
} }
.nav .active a { .nav .active a {
background: transparent; background: transparent;
} }
}
.form-control { // Styles the glowing border of focused input for username async validation
font-size: 14px; .login-body {
padding: 10px 8px; font-size: 13px;
width: 100%;
height: auto;
input + p {
&.top { margin-top: 5px;
border-radius: 5px 5px 0 0; }
margin-bottom: 0;
.gl-field-success-outline {
border: 1px solid $green-normal;
&:focus {
box-shadow: 0 0 0 1px $green-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 $green-normal;
border: 0 none;
}
}
.gl-field-error-outline {
border: 1px solid $red-normal;
&:focus {
box-shadow: 0 0 0 1px $red-normal inset, 0 1px 1px rgba(0, 0, 0, 0.075) inset, 0 0 4px 0 rgba(210, 40, 82, 0.6);
border: 0 none;
}
}
.username .validation-success,
.gl-field-success-message {
color: $green-normal;
}
.username .validation-error,
.gl-field-error-message {
color: $red-normal;
}
.gl-field-hint {
color: $gl-text-color;
}
} }
}
&.bottom { .omniauth-container {
border-radius: 0 0 5px 5px; p {
border-top: 0; margin: 0;
margin-bottom: 20px;
} }
}
.new-session-tabs {
display: -webkit-flex;
display: flex;
box-shadow: 0 0 0 1px $border-color;
border-top-right-radius: 2px;
border-top-left-radius: 2px;
li {
flex: 1;
text-align: center;
&:last-of-type {
border-left: 1px solid $border-color;
}
&:not(.active) {
background-color: $gray-light;
}
a {
width: 100%;
font-size: 18px;
&.middle { &:hover {
border-top: 0; border: 1px solid transparent;
margin-bottom: 0; }
border-radius: 0; }
&.active {
border-bottom: 1px solid $border-color;
a {
border: none;
border-bottom: 2px solid $link-underline-blue;
color: $black;
&:hover {
border-bottom: 2px solid $link-underline-blue;
}
}
}
} }
}
.form-control {
&:active, &:focus { &:active, &:focus {
background-color: #fff; background-color: #fff;
} }
} }
label {
font-weight: normal;
}
.submit-container {
margin-top: 16px;
}
input[type="submit"] {
@extend .btn-block;
margin-bottom: 0;
}
.devise-errors { .devise-errors {
h2 { h2 {
margin-top: 0; margin-top: 0;
...@@ -101,14 +191,6 @@ ...@@ -101,14 +191,6 @@
color: #a00; color: #a00;
} }
} }
.remember-me {
margin-top: -10px;
label {
font-weight: normal;
}
}
} }
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
...@@ -127,3 +209,35 @@ ...@@ -127,3 +209,35 @@
height: 32px; height: 32px;
} }
} }
.devise-layout-html {
margin: 0;
padding: 0;
height: 100%;
}
// Fixes footer container to bottom of viewport
.devise-layout-html body {
// offset height of fixed header + 1 to avoid scroll
height: calc(100% - 51px);
margin: 0;
padding: 0;
.page-wrap {
min-height: 100%;
position: relative;
}
.footer-container, hr.footer-fixed {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: $white-light;
}
.navless-container {
padding: 65px; // height of footer + bottom padding of email confirmation link
}
}
.project-members-title {
padding-bottom: 10px;
border-bottom: 1px solid $border-color;
}
.member {
.list-item-name {
@media (min-width: $screen-sm-min) {
float: left;
width: 50%;
}
strong {
font-weight: 600;
}
}
.controls {
@media (min-width: $screen-sm-min) {
display: -webkit-flex;
display: flex;
width: 400px;
max-width: 50%;
}
}
.form-horizontal {
margin-top: 5px;
@media (min-width: $screen-sm-min) {
display: -webkit-flex;
display: flex;
width: 100%;
margin-top: 3px;
}
}
.btn-remove {
width: 100%;
@media (min-width: $screen-sm-min) {
width: auto;
}
}
}
.member-form-control {
@media (max-width: $screen-xs-max) {
padding: 5px 0;
margin-left: 0;
margin-right: 0;
}
@media (min-width: $screen-sm-min) {
width: 50%;
}
}
.member-access-text {
margin-left: auto;
line-height: 43px;
}
.member.existing-title {
@media (min-width: $screen-sm-min) {
float: left;
}
}
.member-search-form {
position: relative;
@media (min-width: $screen-sm-min) {
float: right;
}
.form-control {
width: 100%;
padding-right: 35px;
@media (min-width: $screen-sm-min) {
width: 350px;
}
}
}
.member-search-btn {
position: absolute;
right: 0;
top: 0;
height: 35px;
padding-left: 10px;
padding-right: 10px;
color: $gray-darkest;
background: transparent;
border: 0;
outline: 0;
}
...@@ -131,6 +131,7 @@ $colors: ( ...@@ -131,6 +131,7 @@ $colors: (
} }
} }
} }
&.head { &.head {
background-color: map-get($colors, #{$color}_header_head_neutral); background-color: map-get($colors, #{$color}_header_head_neutral);
border-color: map-get($colors, #{$color}_header_head_neutral); border-color: map-get($colors, #{$color}_header_head_neutral);
...@@ -174,6 +175,7 @@ $colors: ( ...@@ -174,6 +175,7 @@ $colors: (
background-color: map-get($colors, #{$color}_line_not_chosen); background-color: map-get($colors, #{$color}_line_not_chosen);
} }
} }
&.head { &.head {
background-color: map-get($colors, #{$color}_line_head_neutral); background-color: map-get($colors, #{$color}_line_head_neutral);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
form { form {
margin-bottom: 0; margin-bottom: 0;
.clearfix { .clearfix {
margin-bottom: 0; margin-bottom: 0;
} }
...@@ -46,6 +47,7 @@ ...@@ -46,6 +47,7 @@
&.right { &.right {
float: right; float: right;
a { a {
color: $gl-gray; color: $gl-gray;
} }
...@@ -121,6 +123,10 @@ ...@@ -121,6 +123,10 @@
color: #5c5d5e; color: #5c5d5e;
} }
.js-deployment-link {
display: inline-block;
}
.mr-widget-body { .mr-widget-body {
h4 { h4 {
font-weight: 600; font-weight: 600;
...@@ -188,6 +194,7 @@ ...@@ -188,6 +194,7 @@
padding-top: 2px; padding-top: 2px;
padding-bottom: 2px; padding-bottom: 2px;
list-style: none; list-style: none;
&:hover { &:hover {
background: none; background: none;
} }
...@@ -211,6 +218,7 @@ ...@@ -211,6 +218,7 @@
padding-top: 20px; padding-top: 20px;
padding-bottom: 10px; padding-bottom: 10px;
} }
svg { svg {
width: 230px; width: 230px;
} }
...@@ -276,12 +284,6 @@ ...@@ -276,12 +284,6 @@
line-height: 31px; line-height: 31px;
} }
.builds {
.table-holder {
overflow-x: auto;
}
}
.panel-new-merge-request { .panel-new-merge-request {
.panel-heading { .panel-heading {
padding: 5px 10px; padding: 5px 10px;
...@@ -369,7 +371,7 @@ ...@@ -369,7 +371,7 @@
} }
.table-holder { .table-holder {
.builds { .ci-table {
th { th {
background-color: $white-light; background-color: $white-light;
...@@ -433,3 +435,12 @@ ...@@ -433,3 +435,12 @@
margin-bottom: 20px; margin-bottom: 20px;
} }
} }
.merge-request-tabs {
background-color: #fff;
&.affix {
top: 100px;
z-index: 9;
}
}
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
color: $gl-placeholder-color; color: $gl-placeholder-color;
margin-right: 5px; margin-right: 5px;
} }
.avatar { .avatar {
float: none; float: none;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
filter: alpha(opacity=100); filter: alpha(opacity=100);
} }
} }
.diff-file, .diff-file,
.discussion { .discussion {
.new-note { .new-note {
...@@ -194,6 +195,7 @@ ...@@ -194,6 +195,7 @@
min-height: 140px; min-height: 140px;
max-height: 500px; max-height: 500px;
} }
.note-form-actions { .note-form-actions {
background: transparent; background: transparent;
} }
......
...@@ -147,9 +147,18 @@ ul.notes { ...@@ -147,9 +147,18 @@ ul.notes {
// Diff code in discussion view // Diff code in discussion view
.discussion-body .diff-file { .discussion-body .diff-file {
.file-title {
cursor: default;
&:hover {
background-color: $gray-light;
}
}
.diff-header > span { .diff-header > span {
margin-right: 10px; margin-right: 10px;
} }
.line_content { .line_content {
white-space: pre-wrap; white-space: pre-wrap;
} }
...@@ -345,6 +354,7 @@ ul.notes { ...@@ -345,6 +354,7 @@ ul.notes {
width: 32px; width: 32px;
// "hide" it by default // "hide" it by default
display: none; display: none;
&:hover { &:hover {
background: $gl-info; background: $gl-info;
color: #fff; color: #fff;
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
margin: 4px; margin: 4px;
} }
.table.builds { .table.ci-table {
min-width: 1200px; min-width: 1200px;
.branch-commit { .branch-commit {
...@@ -44,13 +44,20 @@ ...@@ -44,13 +44,20 @@
overflow: auto; overflow: auto;
} }
.table.builds { .table.ci-table {
min-width: 900px; min-width: 900px;
&.pipeline { &.pipeline {
min-width: 650px; min-width: 650px;
} }
&.builds-page {
tr {
height: 71px;
}
}
tr { tr {
th { th {
padding: 16px 8px; padding: 16px 8px;
...@@ -176,7 +183,7 @@ ...@@ -176,7 +183,7 @@
&::after { &::after {
content: ''; content: '';
width: 8px; width: 8px;
position: absolute;; position: absolute;
right: -7px; right: -7px;
bottom: 8px; bottom: 8px;
border-bottom: 2px solid $border-color; border-bottom: 2px solid $border-color;
...@@ -353,6 +360,7 @@ ...@@ -353,6 +360,7 @@
&:hover { &:hover {
background-color: $gray-lighter; background-color: $gray-lighter;
.dropdown-menu-toggle { .dropdown-menu-toggle {
background-color: transparent; background-color: transparent;
} }
...@@ -536,6 +544,7 @@ ...@@ -536,6 +544,7 @@
height: 29px; height: 29px;
top: -9px; top: -9px;
} }
.curve { .curve {
display: block; display: block;
} }
...@@ -621,19 +630,31 @@ ...@@ -621,19 +630,31 @@
} }
} }
.pipelines.tab-pane { .tab-pane {
.content-list.pipelines { &.pipelines {
overflow: auto;
}
.stage { .content-list.pipelines {
max-width: 100px; overflow: auto;
width: 100px; }
.stage {
max-width: 100px;
width: 100px;
}
.pipeline-actions {
min-width: initial;
}
} }
.pipeline-actions { &.builds {
min-width: initial;
.ci-table {
tr {
height: 71px;
}
}
} }
} }
......
...@@ -243,6 +243,7 @@ ...@@ -243,6 +243,7 @@
.btn { .btn {
-webkit-flex-grow: 1; -webkit-flex-grow: 1;
flex-grow: 1; flex-grow: 1;
&:first-child { &:first-child {
margin-left: 0; margin-left: 0;
} }
......
...@@ -17,34 +17,43 @@ ...@@ -17,34 +17,43 @@
&.features .control-label { &.features .control-label {
font-weight: normal; font-weight: normal;
} }
.form-group { .form-group {
margin-bottom: 5px; margin-bottom: 5px;
} }
&> .form-group { &> .form-group {
padding-left: 0; padding-left: 0;
} }
} }
.help-block { .help-block {
margin-bottom: 10px; margin-bottom: 10px;
} }
.project-path { .project-path {
padding-right: 0; padding-right: 0;
.form-control { .form-control {
border-radius: $border-radius-base; border-radius: $border-radius-base;
} }
} }
.input-group > div { .input-group > div {
&:last-child { &:last-child {
padding-right: 0; padding-right: 0;
} }
} }
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
.input-group > div { .input-group > div {
margin-bottom: 14px; margin-bottom: 14px;
&:last-child { &:last-child {
margin-bottom: 0; margin-bottom: 0;
} }
} }
fieldset > .form-group:first-child { fieldset > .form-group:first-child {
padding-right: 0; padding-right: 0;
} }
...@@ -56,6 +65,7 @@ ...@@ -56,6 +65,7 @@
border-radius: 3px; border-radius: 3px;
border: 1px solid #e5e5e5; border: 1px solid #e5e5e5;
} }
&+ .select2 a { &+ .select2 a {
border-top-left-radius: 0; border-top-left-radius: 0;
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
...@@ -201,6 +211,7 @@ ...@@ -201,6 +211,7 @@
pointer-events: none; pointer-events: none;
} }
} }
.count { .count {
@include btn-gray; @include btn-gray;
display: inline-block; display: inline-block;
...@@ -361,10 +372,12 @@ a.deploy-project-label { ...@@ -361,10 +372,12 @@ a.deploy-project-label {
margin: $gl-padding; margin: $gl-padding;
text-align: center; text-align: center;
width: 169px; width: 169px;
&:hover, &.forked { &:hover, &.forked {
background-color: $row-hover; background-color: $row-hover;
border-color: $row-hover-border; border-color: $row-hover-border;
} }
.no-avatar { .no-avatar {
width: 100px; width: 100px;
height: 100px; height: 100px;
...@@ -372,17 +385,20 @@ a.deploy-project-label { ...@@ -372,17 +385,20 @@ a.deploy-project-label {
border: 1px solid $gray-dark; border: 1px solid $gray-dark;
margin: 0 auto; margin: 0 auto;
border-radius: 50%; border-radius: 50%;
i { i {
font-size: 100px; font-size: 100px;
color: $gray-dark; color: $gray-dark;
} }
} }
a { a {
display: block; display: block;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding-top: $gl-padding; padding-top: $gl-padding;
color: $gl-gray; color: $gl-gray;
.caption { .caption {
min-height: 30px; min-height: 30px;
padding: $gl-padding 0; padding: $gl-padding 0;
...@@ -644,6 +660,7 @@ pre.light-well { ...@@ -644,6 +660,7 @@ pre.light-well {
.clone-options { .clone-options {
display: table-cell; display: table-cell;
a.btn { a.btn {
width: 100%; width: 100%;
} }
...@@ -832,6 +849,7 @@ pre.light-well { ...@@ -832,6 +849,7 @@ pre.light-well {
.form-control { .form-control {
min-width: 100px; min-width: 100px;
} }
.select2-choice { .select2-choice {
border-top-right-radius: 0; border-top-right-radius: 0;
border-bottom-right-radius: 0; border-bottom-right-radius: 0;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
&.runner-state-shared { &.runner-state-shared {
background: #32b186; background: #32b186;
} }
&.runner-state-specific { &.runner-state-specific {
background: #3498db; background: #3498db;
} }
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
.ci-status-icon-success { .ci-status-icon-success {
color: $gl-success; color: $gl-success;
} }
.ci-status-icon-failed { .ci-status-icon-failed {
color: $gl-danger; color: $gl-danger;
} }
...@@ -77,6 +78,7 @@ ...@@ -77,6 +78,7 @@
.ci-status-icon-running { .ci-status-icon-running {
color: $blue-normal; color: $blue-normal;
} }
.ci-status-icon-canceled, .ci-status-icon-canceled,
.ci-status-icon-disabled, .ci-status-icon-disabled,
.ci-status-icon-not-found, .ci-status-icon-not-found,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
.file-finder { .file-finder {
width: 50%; width: 50%;
.file-finder-input { .file-finder-input {
width: 95%; width: 95%;
display: inline-block; display: inline-block;
......
This diff is collapsed.
...@@ -45,6 +45,10 @@ class ApplicationController < ActionController::Base ...@@ -45,6 +45,10 @@ class ApplicationController < ActionController::Base
redirect_to request.referer.present? ? :back : default, options redirect_to request.referer.present? ? :back : default, options
end end
def not_found
render_404
end
protected protected
# This filter handles both private tokens and personal access tokens # This filter handles both private tokens and personal access tokens
......
class Projects::GroupLinksController < Projects::ApplicationController class Projects::GroupLinksController < Projects::ApplicationController
layout 'project_settings' layout 'project_settings'
before_action :authorize_admin_project! before_action :authorize_admin_project!
before_action :authorize_admin_project_member!, only: [:update]
def index def index
@group_links = project.project_group_links.all @group_links = project.project_group_links.all
...@@ -27,9 +28,26 @@ class Projects::GroupLinksController < Projects::ApplicationController ...@@ -27,9 +28,26 @@ class Projects::GroupLinksController < Projects::ApplicationController
redirect_to namespace_project_group_links_path(project.namespace, project) redirect_to namespace_project_group_links_path(project.namespace, project)
end end
def update
@group_link = @project.project_group_links.find(params[:id])
@group_link.update_attributes(group_link_params)
end
def destroy def destroy
project.project_group_links.find(params[:id]).destroy project.project_group_links.find(params[:id]).destroy
redirect_to namespace_project_group_links_path(project.namespace, project) respond_to do |format|
format.html do
redirect_to namespace_project_group_links_path(project.namespace, project)
end
format.js { head :ok }
end
end
protected
def group_link_params
params.require(:group_link).permit(:group_access, :expires_at)
end end
end end
...@@ -10,7 +10,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -10,7 +10,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
before_action :module_enabled before_action :module_enabled
before_action :merge_request, only: [ before_action :merge_request, only: [
:edit, :update, :show, :diffs, :commits, :conflicts, :builds, :pipelines, :merge, :merge_check, :edit, :update, :show, :diffs, :commits, :conflicts, :builds, :pipelines, :merge, :merge_check,
:ci_status, :toggle_subscription, :cancel_merge_when_build_succeeds, :remove_wip, :resolve_conflicts, :assign_related_issues :ci_status, :ci_environments_status, :toggle_subscription, :cancel_merge_when_build_succeeds, :remove_wip, :resolve_conflicts, :assign_related_issues
] ]
before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds, :pipelines] before_action :validates_merge_request, only: [:show, :diffs, :commits, :builds, :pipelines]
before_action :define_show_vars, only: [:show, :diffs, :commits, :conflicts, :builds, :pipelines] before_action :define_show_vars, only: [:show, :diffs, :commits, :conflicts, :builds, :pipelines]
...@@ -403,6 +403,30 @@ class Projects::MergeRequestsController < Projects::ApplicationController ...@@ -403,6 +403,30 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render json: response render json: response
end end
def ci_environments_status
environments =
begin
@merge_request.environments.map do |environment|
next unless can?(current_user, :read_environment, environment)
project = environment.project
deployment = environment.first_deployment_for(@merge_request.diff_head_commit)
{
id: environment.id,
name: environment.name,
url: namespace_project_environment_path(project.namespace, project, environment),
external_url: environment.external_url,
external_url_formatted: environment.formatted_external_url,
deployed_at: deployment.try(:created_at),
deployed_at_formatted: deployment.try(:formatted_deployment_time)
}
end.compact
end
render json: environments
end
protected protected
def selected_target_project def selected_target_project
......
...@@ -5,34 +5,23 @@ class Projects::ProjectMembersController < Projects::ApplicationController ...@@ -5,34 +5,23 @@ class Projects::ProjectMembersController < Projects::ApplicationController
before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access] before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access]
def index def index
@group_links = @project.project_group_links
@project_members = @project.project_members @project_members = @project.project_members
@project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project) @project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project)
if params[:search].present? if params[:search].present?
users = @project.users.search(params[:search]).to_a users = @project.users.search(params[:search]).to_a
@project_members = @project_members.where(user_id: users) @project_members = @project_members.where(user_id: users)
end
@project_members = @project_members.order('access_level DESC')
@group = @project.group
if @group
@group_members = @group.group_members
@group_members = @group_members.non_invite unless can?(current_user, :admin_group, @group)
if params[:search].present?
users = @group.users.search(params[:search]).to_a
@group_members = @group_members.where(user_id: users)
end
@group_members = @group_members.order('access_level DESC') @group_links = @project.project_group_links.where(group_id: @project.invited_groups.search(params[:search]).select(:id))
end end
@project_members = @project_members.order(access_level: :desc).page(params[:page])
@requesters = AccessRequestsFinder.new(@project).execute(current_user) @requesters = AccessRequestsFinder.new(@project).execute(current_user)
@project_member = @project.project_members.new @project_member = @project.project_members.new
@project_group_links = @project.project_group_links
end end
def create def create
...@@ -43,6 +32,21 @@ class Projects::ProjectMembersController < Projects::ApplicationController ...@@ -43,6 +32,21 @@ class Projects::ProjectMembersController < Projects::ApplicationController
current_user: current_user current_user: current_user
) )
if params[:group_ids].present?
group_ids = params[:group_ids].split(',')
groups = Group.where(id: group_ids)
groups.each do |group|
next unless can?(current_user, :read_group, group)
project.project_group_links.create(
group: group,
group_access: params[:access_level],
expires_at: params[:expires_at]
)
end
end
redirect_to namespace_project_project_members_path(@project.namespace, @project) redirect_to namespace_project_project_members_path(@project.namespace, @project)
end end
......
class UsersController < ApplicationController class UsersController < ApplicationController
skip_before_action :authenticate_user! skip_before_action :authenticate_user!
before_action :user before_action :user, except: [:exists]
before_action :authorize_read_user!, only: [:show] before_action :authorize_read_user!, only: [:show]
def show def show
...@@ -85,6 +85,10 @@ class UsersController < ApplicationController ...@@ -85,6 +85,10 @@ class UsersController < ApplicationController
render 'calendar_activities', layout: false render 'calendar_activities', layout: false
end end
def exists
render json: { exists: Namespace.where(path: params[:username].downcase).any? }
end
private private
def authorize_read_user! def authorize_read_user!
......
module Ci module Ci
class Build < CommitStatus class Build < CommitStatus
include TokenAuthenticatable include TokenAuthenticatable
include AfterCommitQueue
belongs_to :runner, class_name: 'Ci::Runner' belongs_to :runner, class_name: 'Ci::Runner'
belongs_to :trigger_request, class_name: 'Ci::TriggerRequest' belongs_to :trigger_request, class_name: 'Ci::TriggerRequest'
...@@ -75,25 +76,20 @@ module Ci ...@@ -75,25 +76,20 @@ module Ci
state_machine :status do state_machine :status do
after_transition pending: :running do |build| after_transition pending: :running do |build|
build.execute_hooks build.run_after_commit do
BuildHooksWorker.perform_async(id)
end
end end
after_transition any => [:success, :failed, :canceled] do |build| after_transition any => [:success, :failed, :canceled] do |build|
build.update_coverage build.run_after_commit do
build.execute_hooks BuildFinishedWorker.perform_async(id)
end
end end
after_transition any => [:success] do |build| after_transition any => [:success] do |build|
if build.environment.present? build.run_after_commit do
service = CreateDeploymentService.new( BuildSuccessWorker.perform_async(id)
build.project, build.user,
environment: build.environment,
sha: build.sha,
ref: build.ref,
tag: build.tag,
options: build.options.to_h[:environment],
variables: build.variables)
service.execute(build)
end end
end end
end end
......
...@@ -76,7 +76,11 @@ module Ci ...@@ -76,7 +76,11 @@ module Ci
end end
after_transition do |pipeline, transition| after_transition do |pipeline, transition|
pipeline.execute_hooks unless transition.loopback? next if transition.loopback?
pipeline.run_after_commit do
PipelineHooksWorker.perform_async(id)
end
end end
end end
......
...@@ -84,6 +84,10 @@ class Deployment < ActiveRecord::Base ...@@ -84,6 +84,10 @@ class Deployment < ActiveRecord::Base
take take
end end
def formatted_deployment_time
created_at.to_time.in_time_zone.to_s(:medium)
end
private private
def ref_path def ref_path
......
...@@ -48,7 +48,22 @@ class Environment < ActiveRecord::Base ...@@ -48,7 +48,22 @@ class Environment < ActiveRecord::Base
self.name == "production" self.name == "production"
end end
def first_deployment_for(commit)
ref = project.repository.ref_name_for_sha(ref_path, commit.sha)
return nil unless ref
deployment_id = ref.split('/').last
deployments.find(deployment_id)
end
def ref_path def ref_path
"refs/environments/#{Shellwords.shellescape(name)}" "refs/environments/#{Shellwords.shellescape(name)}"
end end
def formatted_external_url
return nil unless external_url
external_url.gsub(/\A.*?:\/\//, '')
end
end end
...@@ -688,12 +688,15 @@ class MergeRequest < ActiveRecord::Base ...@@ -688,12 +688,15 @@ class MergeRequest < ActiveRecord::Base
def environments def environments
return [] unless diff_head_commit return [] unless diff_head_commit
environments = source_project.environments_for( @environments ||=
source_branch, diff_head_commit) begin
environments += target_project.environments_for( environments = source_project.environments_for(
target_branch, diff_head_commit, with_tags: true) source_branch, diff_head_commit)
environments += target_project.environments_for(
environments.uniq target_branch, diff_head_commit, with_tags: true)
environments.uniq
end
end end
def state_human_name def state_human_name
......
...@@ -490,7 +490,7 @@ class Project < ActiveRecord::Base ...@@ -490,7 +490,7 @@ class Project < ActiveRecord::Base
end end
def import_url def import_url
if import_data && super if import_data && super.present?
import_url = Gitlab::UrlSanitizer.new(super, credentials: import_data.credentials) import_url = Gitlab::UrlSanitizer.new(super, credentials: import_data.credentials)
import_url.full_url import_url.full_url
else else
...@@ -829,11 +829,6 @@ class Project < ActiveRecord::Base ...@@ -829,11 +829,6 @@ class Project < ActiveRecord::Base
end end
end end
def update_merge_requests(oldrev, newrev, ref, user)
MergeRequests::RefreshService.new(self, user).
execute(oldrev, newrev, ref)
end
def valid_repo? def valid_repo?
repository.exists? repository.exists?
rescue rescue
......
...@@ -719,6 +719,14 @@ class Repository ...@@ -719,6 +719,14 @@ class Repository
end end
end end
def ref_name_for_sha(ref_path, sha)
args = %W(#{Gitlab.config.git.bin_path} for-each-ref --count=1 #{ref_path} --contains #{sha})
# Not found -> ["", 0]
# Found -> ["b8d95eb4969eefacb0a58f6a28f6803f8070e7b9 commit\trefs/environments/production/77\n", 0]
Gitlab::Popen.popen(args, path_to_repo).first.split.last
end
def refs_contains_sha(ref_type, sha) def refs_contains_sha(ref_type, sha)
args = %W(#{Gitlab.config.git.bin_path} #{ref_type} --contains #{sha}) args = %W(#{Gitlab.config.git.bin_path} #{ref_type} --contains #{sha})
names = Gitlab::Popen.popen(args, path_to_repo).first names = Gitlab::Popen.popen(args, path_to_repo).first
......
...@@ -2,25 +2,35 @@ require_relative 'base_service' ...@@ -2,25 +2,35 @@ require_relative 'base_service'
class CreateDeploymentService < BaseService class CreateDeploymentService < BaseService
def execute(deployable = nil) def execute(deployable = nil)
environment = find_or_create_environment return unless executable?
deployment = project.deployments.create( ActiveRecord::Base.transaction do
environment: environment, @deployable = deployable
@environment = prepare_environment
deploy.tap do |deployment|
deployment.update_merge_request_metrics!
end
end
end
private
def executable?
project && name.present?
end
def deploy
project.deployments.create(
environment: @environment,
ref: params[:ref], ref: params[:ref],
tag: params[:tag], tag: params[:tag],
sha: params[:sha], sha: params[:sha],
user: current_user, user: current_user,
deployable: deployable deployable: @deployable)
)
deployment.update_merge_request_metrics!
deployment
end end
private def prepare_environment
def find_or_create_environment
project.environments.find_or_create_by(name: expanded_name) do |environment| project.environments.find_or_create_by(name: expanded_name) do |environment|
environment.external_url = expanded_url environment.external_url = expanded_url
end end
......
...@@ -63,13 +63,12 @@ class GitPushService < BaseService ...@@ -63,13 +63,12 @@ class GitPushService < BaseService
protected protected
def update_merge_requests def update_merge_requests
@project.update_merge_requests(params[:oldrev], params[:newrev], params[:ref], current_user) UpdateMergeRequestsWorker.perform_async(@project.id, current_user.id, params[:oldrev], params[:newrev], params[:ref])
EventCreateService.new.push(@project, current_user, build_push_data) EventCreateService.new.push(@project, current_user, build_push_data)
SystemHooksService.new.execute_hooks(build_push_data_system_hook.dup, :push_hooks)
@project.execute_hooks(build_push_data.dup, :push_hooks) @project.execute_hooks(build_push_data.dup, :push_hooks)
@project.execute_services(build_push_data.dup, :push_hooks) @project.execute_services(build_push_data.dup, :push_hooks)
Ci::CreatePipelineService.new(project, current_user, build_push_data).execute Ci::CreatePipelineService.new(@project, current_user, build_push_data).execute
ProjectCacheWorker.perform_async(@project.id) ProjectCacheWorker.perform_async(@project.id)
end end
...@@ -148,16 +147,6 @@ class GitPushService < BaseService ...@@ -148,16 +147,6 @@ class GitPushService < BaseService
push_commits) push_commits)
end end
def build_push_data_system_hook
@push_data_system ||= Gitlab::DataBuilder::Push.build(
@project,
current_user,
params[:oldrev],
params[:newrev],
params[:ref],
[])
end
def push_to_existing_branch? def push_to_existing_branch?
# Return if this is not a push to a branch (e.g. new commits) # Return if this is not a push to a branch (e.g. new commits)
Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev]) Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev])
......
- page_title "Preview | Appearance" = render 'devise/shared/tab_single', tab_title: 'Sign in preview'
.login-box .login-box
.login-heading %form.show-gl-field-errors
%h3 Existing user? Sign in .form-group
%form = label_tag :login
= text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email" = text_field_tag :login, nil, class: "form-control top", title: 'Please provide your username or email address.'
= password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password" .form-group
= button_tag "Sign in", class: "btn-create btn" = label_tag :password
= password_field_tag :password, nil, class: "form-control bottom", title: 'This field is required.'
.form-group
= button_tag "Sign in", class: "btn-create btn"
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
.col-md-6 .col-md-6
%h4 Recent builds served by this Runner %h4 Recent builds served by this Runner
%table.table.builds.runner-builds %table.table.ci-table.runner-builds
%thead %thead
%tr %tr
%th Build %th Build
......
= render 'devise/shared/tab_single', tab_title: 'Resend confirmation instructions'
.login-box .login-box
.login-heading
%h3 Resend confirmation instructions
.login-body .login-body
= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| = form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post, class: 'show-gl-field-errors' }) do |f|
.devise-errors .devise-errors
= devise_error_messages! = devise_error_messages!
.clearfix.append-bottom-20 .form-group
= f.email_field :email, placeholder: 'Email', class: "form-control", required: true = f.label :email
= f.email_field :email, class: "form-control", required: true, title: 'Please provide a valid email address.'
.clearfix .clearfix
= f.submit "Resend confirmation instructions", class: 'btn btn-success' = f.submit "Resend", class: 'btn btn-success'
.clearfix.prepend-top-20 .clearfix.prepend-top-20
= render 'devise/shared/sign_in_link' = render 'devise/shared/sign_in_link'
= render 'devise/shared/tab_single', tab_title:'Change your password'
.login-box .login-box
.login-heading
%h3 Change your password
.login-body .login-body
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put, class: 'show-gl-field-errors' }) do |f|
.devise-errors .devise-errors
= devise_error_messages! = devise_error_messages!
= f.hidden_field :reset_password_token = f.hidden_field :reset_password_token
%div .form-group
= f.password_field :password, class: "form-control top", placeholder: "New password", required: true = f.label 'New password', for: :password
%div = f.password_field :password, class: "form-control top", required: true, title: 'This field is required'
= f.password_field :password_confirmation, class: "form-control bottom", placeholder: "Confirm new password", required: true .form-group
= f.label 'Confirm new password', for: :password_confirmation
= f.password_field :password_confirmation, class: "form-control bottom", title: 'This field is required', required: true
.clearfix .clearfix
= f.submit "Change your password", class: "btn btn-primary" = f.submit "Change your password", class: "btn btn-primary"
.clearfix.prepend-top-20 .clearfix.prepend-top-20
%p %p
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %span.light Didn't receive a confirmation email?
= render 'devise/shared/sign_in_link' = link_to "Request a new one", new_confirmation_path(resource_name)
= render 'devise/shared/sign_in_link'
= render 'devise/shared/tab_single', tab_title: 'Reset Password'
.login-box .login-box
.login-heading
%h3 Reset password
.login-body .login-body
= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| = form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: 'show-gl-field-errors' }) do |f|
.devise-errors .devise-errors
= devise_error_messages! = devise_error_messages!
.clearfix.append-bottom-20 .form-group
= f.email_field :email, placeholder: "Email", class: "form-control", required: true, value: params[:user_email], autofocus: true = f.label :email
= f.email_field :email, class: "form-control", required: true, value: params[:user_email], autofocus: true, title: 'Please provide a valid email address.'
.clearfix .clearfix
= f.submit "Reset password", class: "btn-primary btn" = f.submit "Reset password", class: "btn-primary btn"
......
= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| = form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: 'new_user show-gl-field-errors', 'aria-live' => 'assertive'}) do |f|
= f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off" %div.form-group
= f.password_field :password, class: "form-control bottom", placeholder: "Password" = f.label "Username or email", for: :login
= f.text_field :login, class: "form-control top", autofocus: "autofocus", autocapitalize: "off", autocorrect: "off", required: true, title: "This field is required."
%div.form-group
= f.label :password
= f.password_field :password, class: "form-control bottom", required: true, title: "This field is required."
- if devise_mapping.rememberable? - if devise_mapping.rememberable?
.remember-me.checkbox .remember-me.checkbox
%label{for: "user_remember_me"} %label{for: "user_remember_me"}
...@@ -8,5 +12,5 @@ ...@@ -8,5 +12,5 @@
%span Remember me %span Remember me
.pull-right .pull-right
= link_to "Forgot your password?", new_password_path(resource_name) = link_to "Forgot your password?", new_password_path(resource_name)
%div %div.submit-container
= f.submit "Sign in", class: "btn btn-save" = f.submit "Sign in", class: "btn btn-save"
= form_tag(omniauth_authorize_path(:user, :crowd), id: 'new_crowd_user' ) do = form_tag(omniauth_authorize_path(:user, :crowd), id: 'new_crowd_user', class: 'show-gl-field-errors') do
= text_field_tag :username, nil, {class: "form-control top", placeholder: "Username", autofocus: "autofocus"} .form-group
= password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} = label_tag 'Username or email', for: :username
= text_field_tag :username, nil, {class: "form-control top", title: "This field is required", autofocus: "autofocus", required: true }
.form-group
= label_tag :password
= password_field_tag :password, nil, { class: "form-control bottom", title: "This field is required.", required: true }
- if devise_mapping.rememberable? - if devise_mapping.rememberable?
.remember-me.checkbox .remember-me.checkbox
%label{for: "remember_me"} %label{for: "remember_me"}
......
= form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user') do = form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "show-gl-field-errors") do
= text_field_tag :username, nil, {class: "form-control top", placeholder: "#{server['label']} Login", autofocus: "autofocus"} .form-group
= password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"} = label_tag "#{server['label']} Login", for: :username
= text_field_tag :username, nil, {class: "form-control top", title: "This field is required.", autofocus: "autofocus", required: true }
.form-group
= label_tag :password
= password_field_tag :password, nil, { class: "form-control bottom", title: "This field is required.", required: true }
- if devise_mapping.rememberable? - if devise_mapping.rememberable?
.remember-me.checkbox .remember-me.checkbox
%label{for: "remember_me"} %label{for: "remember_me"}
......
- page_title "Sign in" - page_title "Sign in"
%div %div
- if signin_enabled? || ldap_enabled? || crowd_enabled? - if form_based_providers.any?
= render 'devise/shared/signin_box' = render 'devise/shared/tabs_ldap'
- else
= render 'devise/shared/tabs_normal'
.tab-content
- if signin_enabled? || ldap_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
-# Omniauth fits between signin/ldap signin and signup and does not have a surrounding box -# Signup only makes sense if you can also sign-in
- if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled? - if signin_enabled? && signup_enabled?
.clearfix.prepend-top-20
= render 'devise/shared/omniauth_box'
-# Signup only makes sense if you can also sign-in
- if signin_enabled? && signup_enabled?
.prepend-top-20
= render 'devise/shared/signup_box' = render 'devise/shared/signup_box'
-# Show a message if none of the mechanisms above are enabled -# Show a message if none of the mechanisms above are enabled
- if !signin_enabled? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?) - if !signin_enabled? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div %div
No authentication methods configured. No authentication methods configured.
- if omniauth_enabled? && devise_mapping.omniauthable? && button_based_providers_enabled?
.clearfix
= render 'devise/shared/omniauth_box'
...@@ -3,20 +3,19 @@ ...@@ -3,20 +3,19 @@
= page_specific_javascript_tag('u2f.js') = page_specific_javascript_tag('u2f.js')
%div %div
= render 'devise/shared/tab_single', tab_title: 'Two-Factor Authentication'
.login-box .login-box
.login-heading
%h3 Two-Factor Authentication
.login-body .login-body
- if @user.two_factor_otp_enabled? - if @user.two_factor_otp_enabled?
%h5 Authenticate via Two-Factor App = form_for(resource, as: resource_name, url: session_path(resource_name), method: :post, html: { class: 'edit_user show-gl-field-errors' }) do |f|
= form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f|
- resource_params = params[resource_name].presence || params - resource_params = params[resource_name].presence || params
= f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0) = f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0)
= f.text_field :otp_attempt, class: 'form-control', placeholder: 'Two-Factor Authentication code', required: true, autofocus: true, autocomplete: 'off' .form-group
%p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes. = f.label 'Two-Factor Authentication code', name: :otp_attempt
.prepend-top-20 = f.text_field :otp_attempt, class: 'form-control', required: true, autofocus: true, autocomplete: 'off', title: 'This field is required.'
= f.submit "Verify code", class: "btn btn-save" %p.help-block.hint Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.
.prepend-top-20
= f.submit "Verify code", class: "btn btn-save"
- if @user.two_factor_u2f_enabled? - if @user.two_factor_u2f_enabled?
%hr
= render "u2f/authenticate", locals: { params: params, resource: resource, resource_name: resource_name } = render "u2f/authenticate", locals: { params: params, resource: resource, resource_name: resource_name }
%p %div.omniauth-container
%span.light %p
Sign in with &nbsp;
- providers = enabled_button_based_providers
- providers.each do |provider|
%span.light %span.light
- has_icon = provider_has_icon?(provider) Sign in with &nbsp;
= link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true" - providers = enabled_button_based_providers
- providers.each do |provider|
%span.light
- has_icon = provider_has_icon?(provider)
= link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true"
%p %p
%span.light %span.light
Already have login and password? Already have login and password?
%strong
= link_to "Sign in", new_session_path(resource_name) = link_to "Sign in", new_session_path(resource_name)
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.
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.
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