Commit a2eff1a8 authored by Phil Hughes's avatar Phil Hughes

Merge branch 'master' into issue-board-sidebar

parents 13f170fc 3d174c71
......@@ -210,7 +210,7 @@ rake brakeman: *exec
rake flay: *exec
license_finder: *exec
rake downtime_check: *exec
rake ce_to_ee_merge_check:
rake ee_compat_check:
<<: *exec
only:
- branches
......@@ -279,16 +279,20 @@ bundler:audit:
migration paths:
stage: test
<<: *use-db
variables:
SETUP_DB: "false"
only:
- master@gitlab-org/gitlab-ce
script:
- git checkout HEAD .
- git fetch --tags
- git checkout v8.5.9
- 'echo test: unix:/var/opt/gitlab/redis/redis.socket > config/resque.yml'
- cp config/resque.yml.example config/resque.yml
- sed -i 's/localhost/redis/g' config/resque.yml
- bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}" --retry=3
- rake db:drop db:create db:schema:load db:seed_fu
- git checkout $CI_BUILD_REF
- source scripts/prepare_build.sh
- rake db:migrate
coverage:
......
......@@ -5,7 +5,7 @@ require:
inherit_from: .rubocop_todo.yml
AllCops:
TargetRubyVersion: 2.3
TargetRubyVersion: 2.1
# Cop names are not d§splayed in offense messages by default. Change behavior
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
# option.
......
......@@ -172,7 +172,7 @@ linters:
# Split selectors onto separate lines after each comma, and have each
# individual selector occupy a single line.
SingleLinePerSelector:
enabled: false
enabled: true
# Commas in lists should be followed by a space.
SpaceAfterComma:
......@@ -191,7 +191,7 @@ linters:
# Variables should be formatted with a single space separating the colon
# from the variable's value.
SpaceAfterVariableColon:
enabled: false
enabled: true
# Variables should be formatted with no space between the name and the
# colon.
......@@ -201,7 +201,7 @@ linters:
# Operators should be formatted with a single space on both sides of an
# infix operator.
SpaceAroundOperator:
enabled: false
enabled: true
# Opening braces should be preceded by a single space.
SpaceBeforeBrace:
......@@ -223,7 +223,7 @@ linters:
# Reports lines containing trailing whitespace.
TrailingWhitespace:
enabled: false
enabled: true
# Don't write trailing zeros for numeric values with a decimal point.
TrailingZero:
......
......@@ -2,11 +2,39 @@ Please view this file on the master branch, on stable branches it's out of date.
## 8.14.0 (2016-11-22)
- Adds user project membership expired event to clarify why user was removed (Callum Dryden)
- Trim leading and trailing whitespace on project_path (Linus Thiel)
- Prevent award emoji via notes for issues/MRs authored by user (barthc)
- Adds an optional path parameter to the Commits API to filter commits by path (Luis HGO)
- Fix extra space on Build sidebar on Firefox !7060
- Fix HipChat notifications rendering (airatshigapov, eisnerd)
- Add hover to trash icon in notes !7008 (blackst0ne)
- Escape ref and path for relative links !6050 (winniehell)
- Simpler arguments passed to named_route on toggle_award_url helper method
- Fix: Backup restore doesn't clear cache
- Replace jquery.cookie plugin with js.cookie !7085
- Use MergeRequestsClosingIssues cache data on Issue#closed_by_merge_requests method
- Fix Sign in page 'Forgot your password?' link overlaps on medium-large screens
- Fix documents and comments on Build API `scope`
- Refactor email, use setter method instead AR callbacks for email attribute (Semyon Pupkov)
## 8.13.1 (unreleased)
- Fix bug where labels would be assigned to issues that were moved
- Fix error in generating labels
- Fix reply-by-email not working due to queue name mismatch
- Fixed hidden pipeline graph on commit and MR page !6895
- Expire and build repository cache after project import
- Reduce overhead of LabelFinder by avoiding #presence call !7094
- Fix 404 for group pages when GitLab setup uses relative url
- Simpler arguments passed to named_route on toggle_award_url helper method
- Fix unauthorized users dragging on issue boards
- Better handle when no users were selected for adding to group or project. (Linus Thiel)
- Only show register tab if signup enabled.
- Only schedule ProjectCacheWorker jobs when needed
## 8.13.0 (2016-10-22)
- Removes extra line for empty issue description. (!7045)
- Fix save button on project pipeline settings page. (!6955)
- All Sidekiq workers now use their own queue
- Avoid race condition when asynchronously removing expired artifacts. (!6881)
- Improve Merge When Build Succeeds triggers and execute on pipeline success. (!6675)
- Respond with 404 Not Found for non-existent tags (Linus Thiel)
......@@ -22,27 +50,35 @@ Please view this file on the master branch, on stable branches it's out of date.
- Add `/projects/visible` API endpoint (Ben Boeckel)
- Fix centering of custom header logos (Ashley Dumaine)
- Keep around commits only pipeline creation as pipeline data doesn't change over time
- Update duration at the end of pipeline
- ExpireBuildArtifactsWorker query builds table without ordering enqueuing one job per build to cleanup
- Add group level labels. (!6425)
- Fix Cycle analytics not showing correct data when filtering by date. !6906
- Add an example for testing a phoenix application with Gitlab CI in the docs (Manthan Mallikarjun)
- Cancelled pipelines could be retried. !6927
- Updating verbiage on git basics to be more intuitive
- Fix project_feature record not generated on project creation
- 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
- Fixed issue boards user link when in subdirectory
- Added documentation for .gitattributes files
- Move Pipeline Metrics to separate worker
- AbstractReferenceFilter caches project_refs on RequestStore when active
- Replaced the check sign to arrow in the show build view. !6501
- Add a /wip slash command to toggle the Work In Progress status of a merge request. !6259 (tbalthazar)
- ProjectCacheWorker updates caches at most once per 15 minutes per project
- Fix Error 500 when viewing old merge requests with bad diff data
- Create a new /templates namespace for the /licenses, /gitignores and /gitlab_ci_ymls API endpoints. !5717 (tbalthazar)
- Fix viewing merged MRs when the source project has been removed !6991
- Speed-up group milestones show page
- Fix inconsistent options dropdown caret on mobile viewports (ClemMakesApps)
- Extract project#update_merge_requests and SystemHooks to its own worker from GitPushService
- Fix discussion thread from emails for merge requests. !7010
- Don't include archived projects when creating group milestones. !4940 (Jeroen Jacobs)
- Add tag shortcut from the Commit page. !6543
- Keep refs for each deployment
- Close open tooltips on page navigation (Linus Thiel)
- Allow browsing branches that end with '.atom'
- Log LDAP lookup errors and don't swallow unrelated exceptions. !6103 (Markus Koller)
- Replace unique keyframes mixin with keyframe mixin with specific names (ClemMakesApps)
......@@ -70,12 +106,14 @@ Please view this file on the master branch, on stable branches it's out of date.
- Add RTL support to markdown renderer (Ebrahim Byagowi)
- Add word-wrap to issue title on issue and milestone boards (ClemMakesApps)
- Fix todos page mobile viewport layout (ClemMakesApps)
- Make issues search less finicky
- Fix inconsistent highlighting of already selected activity nav-links (ClemMakesApps)
- Remove redundant mixins (ClemMakesApps)
- Added 'Download' button to the Snippets page (Justin DiPierro)
- Add visibility level to project repository
- Fix robots.txt disallowing access to groups starting with "s" (Matt Harrison)
- Close open merge request without source project (Katarzyna Kobierska Ula Budziszewska)
- Fix showing commits from source project for merge request !6658
- Fix that manual jobs would no longer block jobs in the next stage. !6604
- Add configurable email subject suffix (Fu Xu)
- Use defined colour for a language when available !6748 (nilsding)
......@@ -136,6 +174,7 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fix buggy iOS tooltip layering behavior.
- Make guests unable to view MRs on private projects
- Fix broken Project API docs (Takuya Noguchi)
- Migrate invalid project members (owner -> master)
## 8.12.7
......@@ -369,6 +408,7 @@ Please view this file on the master branch, on stable branches it's out of date.
- Fix inconsistent checkbox alignment (ClemMakesApps)
- Use the default branch for displaying the project icon instead of master !5792 (Hannes Rosenögger)
- Adds response mime type to transaction metric action when it's not HTML
- Fix branch protection API !6215
- Fix hover leading space bug in pipeline graph !5980
- Avoid conflict with admin labels when importing GitHub labels
- User can edit closed MR with deleted fork (Katarzyna Kobierska Ula Budziszewska) !5496
......
......@@ -24,9 +24,7 @@
var filter = sender.attr("id").split("_")[0];
$('.event-filter .active').removeClass("active");
$.cookie("event_filter", filter, {
path: gon.relative_url_root || '/'
});
Cookies.set("event_filter", filter);
sender.closest('li').toggleClass("active");
};
......
......@@ -11,13 +11,13 @@
/*= require jquery-ui/effect-highlight */
/*= require jquery-ui/sortable */
/*= require jquery_ujs */
/*= require jquery.cookie */
/*= require jquery.endless-scroll */
/*= require jquery.highlight */
/*= require jquery.waitforimages */
/*= require jquery.atwho */
/*= require jquery.scrollTo */
/*= require jquery.turbolinks */
/*= require js.cookie */
/*= require turbolinks */
/*= require autosave */
/*= require bootstrap/affix */
......@@ -83,14 +83,15 @@
};
// Disable button if text field is empty
window.disableButtonIfEmptyField = function(field_selector, button_selector) {
window.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
event_name = event_name || 'input';
var closest_submit, field;
field = $(field_selector);
closest_submit = field.closest('form').find(button_selector);
if (rstrip(field.val()) === "") {
closest_submit.disable();
}
return field.on('input', function() {
return field.on(event_name, function() {
if (rstrip($(this).val()) === "") {
return closest_submit.disable();
} else {
......@@ -123,15 +124,11 @@
return str.replace(/<(?:.|\n)*?>/gm, '');
};
window.unbindEvents = function() {
return $(document).off('scroll');
};
window.shiftWindow = function() {
return scrollBy(0, -100);
};
document.addEventListener("page:fetch", unbindEvents);
document.addEventListener("page:fetch", gl.utils.cleanupBeforeFetch);
window.addEventListener("hashchange", shiftWindow);
......@@ -148,6 +145,10 @@
$document = $(document);
$window = $(window);
$body = $('body');
// Set the default path for all cookies to GitLab's root directory
Cookies.defaults.path = gon.relative_url_root || '/';
gl.utils.preventDisabledButtons();
bootstrapBreakpoint = bp.getBreakpointSize();
$(".nav-sidebar").niceScroll({
......
......@@ -322,21 +322,18 @@
var frequentlyUsedEmojis;
frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
frequentlyUsedEmojis.push(emoji);
return $.cookie('frequently_used_emojis', frequentlyUsedEmojis.join(','), {
path: gon.relative_url_root || '/',
expires: 365
});
Cookies.set('frequently_used_emojis', frequentlyUsedEmojis.join(','), { expires: 365 });
};
AwardsHandler.prototype.getFrequentlyUsedEmojis = function() {
var frequentlyUsedEmojis;
frequentlyUsedEmojis = ($.cookie('frequently_used_emojis') || '').split(',');
frequentlyUsedEmojis = (Cookies.get('frequently_used_emojis') || '').split(',');
return _.compact(_.uniq(frequentlyUsedEmojis));
};
AwardsHandler.prototype.renderFrequentlyUsedBlock = function() {
var emoji, frequentlyUsedEmojis, i, len, ul;
if ($.cookie('frequently_used_emojis')) {
if (Cookies.get('frequently_used_emojis')) {
frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
ul = $("<ul class='clearfix emoji-menu-list frequent-emojis'>");
for (i = 0, len = frequentlyUsedEmojis.length; i < len; i++) {
......
......@@ -68,14 +68,10 @@
// To be implemented on the extending class
// e.g.
// Api.gitignoreText item.name, @requestFileSuccess.bind(@)
requestFileSuccess(file, { skipFocus, append } = {}) {
requestFileSuccess(file, { skipFocus } = {}) {
const oldValue = this.editor.getValue();
let newValue = file.content;
if (append && oldValue.length && oldValue !== newValue) {
newValue = oldValue + '\n\n' + newValue;
}
this.editor.setValue(newValue, 1);
if (!skipFocus) this.editor.focus();
......@@ -99,4 +95,3 @@
global.TemplateSelector = TemplateSelector;
})(window.gl || ( window.gl = {}));
......@@ -61,12 +61,12 @@
removeBlankState () {
this.removeList('blank');
$.cookie('issue_board_welcome_hidden', 'true', {
Cookies.set('issue_board_welcome_hidden', 'true', {
expires: 365 * 10
});
},
welcomeIsHidden () {
return $.cookie('issue_board_welcome_hidden') === 'true';
return Cookies.get('issue_board_welcome_hidden') === 'true';
},
removeList (id, type = 'blank') {
const list = this.findList('id', id, type);
......
......@@ -148,7 +148,7 @@
};
Build.prototype.translateSidebar = function(e) {
var newPosition = this.sidebarTranslationLimits.max - document.body.scrollTop;
var newPosition = this.sidebarTranslationLimits.max - (document.body.scrollTop || document.documentElement.scrollTop);
if (newPosition < this.sidebarTranslationLimits.min) newPosition = this.sidebarTranslationLimits.min;
this.$sidebar.css({
top: newPosition
......
......@@ -6,7 +6,7 @@
const store = gl.cycleAnalyticsStore = {
isLoading: true,
hasError: false,
isHelpDismissed: $.cookie(COOKIE_NAME),
isHelpDismissed: Cookies.get(COOKIE_NAME),
analytics: {}
};
......@@ -36,7 +36,11 @@
method: 'GET',
dataType: 'json',
contentType: 'application/json',
data: { start_date: options.startDate }
data: {
cycle_analytics: {
start_date: options.startDate
}
}
}).done((data) => {
this.decorateData(data);
this.initDropdown();
......@@ -71,9 +75,7 @@
dismissLanding() {
store.isHelpDismissed = true;
$.cookie(COOKIE_NAME, true, {
path: gon.relative_url_root || '/'
});
Cookies.set(COOKIE_NAME, true);
}
initDropdown() {
......
......@@ -117,6 +117,9 @@
new ZenMode();
shortcut_handler = new ShortcutsNavigation();
break;
case 'projects:commit:builds':
new gl.Pipelines();
break;
case 'projects:commits:show':
case 'projects:activity':
shortcut_handler = new ShortcutsNavigation();
......
Element.prototype.matches = Element.prototype.matches || Element.prototype.msMatches;
Element.prototype.closest = function closest(selector, selectedElement = this) {
if (!selectedElement) return;
return selectedElement.matches(selector) ? selectedElement : Element.prototype.closest(selector, selectedElement.parentElement);
};
......@@ -137,8 +137,11 @@
}
initValidators () {
// select all non-hidden inputs in form
this.state.inputs = this.form.find(':input:not([type=hidden])').toArray()
// register selectors here as needed
const validateSelectors = [':text', ':password', '[type=email]']
.map((selector) => `input${selector}`).join(',');
this.state.inputs = this.form.find(validateSelectors).toArray()
.filter((input) => !input.classList.contains(customValidationFlag))
.map((input) => new GlFieldError({ input, formErrors: this }));
......
......@@ -15,16 +15,61 @@
return Issuable.labelRow = _.template('<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>');
},
initSearch: function() {
const $searchInput = $('#issuable_search');
Issuable.initSearchState($searchInput);
// `immediate` param set to false debounces on the `trailing` edge, lets user finish typing
const debouncedExecSearch = _.debounce(Issuable.executeSearch, 500, false);
const debouncedExecSearch = _.debounce(Issuable.executeSearch, 1000, false);
$('#issuable_search').off('keyup').on('keyup', debouncedExecSearch);
$searchInput.off('keyup').on('keyup', debouncedExecSearch);
// ensures existing filters are preserved when manually submitted
$('#issue_search_form').on('submit', (e) => {
$('#issuable_search_form').on('submit', (e) => {
e.preventDefault();
debouncedExecSearch(e);
});
},
initSearchState: function($searchInput) {
const currentSearchVal = $searchInput.val();
Issuable.searchState = {
elem: $searchInput,
current: currentSearchVal
};
Issuable.maybeFocusOnSearch();
},
accessSearchPristine: function(set) {
// store reference to previous value to prevent search on non-mutating keyup
const state = Issuable.searchState;
const currentSearchVal = state.elem.val();
if (set) {
state.current = currentSearchVal;
} else {
return state.current === currentSearchVal;
}
},
maybeFocusOnSearch: function() {
const currentSearchVal = Issuable.searchState.current;
if (currentSearchVal && currentSearchVal !== '') {
const queryLength = currentSearchVal.length;
const $searchInput = Issuable.searchState.elem;
/* The following ensures that the cursor is initially placed at
* the end of search input when focus is applied. It accounts
* for differences in browser implementations of `setSelectionRange`
* and cursor placement for elements in focus.
*/
$searchInput.focus();
if ($searchInput.setSelectionRange) {
$searchInput.setSelectionRange(queryLength, queryLength);
} else {
$searchInput.val(currentSearchVal);
}
}
},
executeSearch: function(e) {
const $search = $('#issuable_search');
......@@ -32,6 +77,11 @@
const $searchValue = $search.val();
const $filtersForm = $('.js-filter-form');
const $input = $(`input[name='${$searchName}']`, $filtersForm);
const isPristine = Issuable.accessSearchPristine();
if (isPristine) {
return;
}
if (!$input.length) {
$filtersForm.append(`<input type='hidden' name='${$searchName}' value='${_.escape($searchValue)}'/>`);
......
......@@ -43,6 +43,14 @@
parser.href = url;
return parser;
};
gl.utils.cleanupBeforeFetch = function() {
// Unbind scroll events
$(document).off('scroll');
// Close any open tooltips
$('.has-tooltip, [data-toggle="tooltip"]').tooltip('destroy');
};
return jQuery.timefor = function(time, suffix, expiredLabel) {
var suffixFromNow, timefor;
if (!time) {
......
......@@ -10,6 +10,7 @@
$('.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);
disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
}
removeRow(e) {
......
((global) => {
global.mergeConflicts = global.mergeConflicts || {};
const diffViewType = $.cookie('diff_view');
const diffViewType = Cookies.get('diff_view');
const HEAD_HEADER_TEXT = 'HEAD//our changes';
const ORIGIN_HEADER_TEXT = 'origin//their changes';
const HEAD_BUTTON_TITLE = 'Use ours';
......@@ -180,9 +180,7 @@
this.state.diffView = viewType;
this.state.isParallel = viewType === VIEW_TYPES.PARALLEL;
$.cookie('diff_view', viewType, {
path: gon.relative_url_root || '/'
});
Cookies.set('diff_view', viewType);
},
getHeadHeaderLine(id) {
......
......@@ -3,7 +3,7 @@
// Handles persisting and restoring the current tab selection and lazily-loading
// content on the MergeRequests#show page.
//
/*= require jquery.cookie */
/*= require js.cookie */
//
// ### Example Markup
......@@ -282,6 +282,7 @@
document.querySelector("div#builds").innerHTML = data.html;
gl.utils.localTimeAgo($('.js-timeago', 'div#builds'));
_this.buildsLoaded = true;
if (!this.pipelines) this.pipelines = new gl.Pipelines();
return _this.scrollToElement("#builds");
};
})(this)
......@@ -367,7 +368,7 @@
MergeRequestTabs.prototype.expandView = function() {
var $gutterIcon;
if ($.cookie('collapsed_gutter') === 'true') {
if (Cookies.get('collapsed_gutter') === 'true') {
return;
}
$gutterIcon = $('.js-sidebar-toggle i:visible');
......@@ -388,28 +389,25 @@
// 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());
var $diffTabs = $('#diff-notes-app'),
$fixedNav = $('.navbar-fixed-top'),
$layoutNav = $('.layout-nav');
$tabs.off('affix.bs.affix affix-top.bs.affix')
.affix({
offset: {
top: offsetTop
top: function () {
var tabsTop = $diffTabs.offset().top - $tabs.height();
tabsTop = tabsTop - ($fixedNav.height() + $layoutNav.height());
return tabsTop;
}
}
}).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: ''
});
......
......@@ -2,36 +2,39 @@
class Pipelines {
constructor() {
$(document).off('click', '.toggle-pipeline-btn').on('click', '.toggle-pipeline-btn', this.toggleGraph);
this.initGraphToggle();
this.addMarginToBuildColumns();
}
toggleGraph() {
const $pipelineBtn = $(this).closest('.toggle-pipeline-btn');
const $pipelineGraph = $(this).closest('.row-content-block').next('.pipeline-graph');
const $btnText = $(this).find('.toggle-btn-text');
const graphCollapsed = $pipelineGraph.hasClass('graph-collapsed');
$($pipelineBtn).add($pipelineGraph).toggleClass('graph-collapsed');
initGraphToggle() {
this.pipelineGraph = document.querySelector('.pipeline-graph');
this.toggleButton = document.querySelector('.toggle-pipeline-btn');
this.toggleButtonText = this.toggleButton.querySelector('.toggle-btn-text');
this.toggleButton.addEventListener('click', this.toggleGraph.bind(this));
}
graphCollapsed ? $btnText.text('Hide') : $btnText.text('Expand')
toggleGraph() {
const graphCollapsed = this.pipelineGraph.classList.contains('graph-collapsed');
this.toggleButton.classList.toggle('graph-collapsed');
this.pipelineGraph.classList.toggle('graph-collapsed');
this.toggleButtonText.textContent = graphCollapsed ? 'Hide' : 'Expand';
}
addMarginToBuildColumns() {
const $secondChildBuildNode = $('.build:nth-child(2)');
if ($secondChildBuildNode.length) {
const $firstChildBuildNode = $secondChildBuildNode.prev('.build');
const $multiBuildColumn = $secondChildBuildNode.closest('.stage-column');
const $previousColumn = $multiBuildColumn.prev('.stage-column');
$multiBuildColumn.addClass('left-margin');
$firstChildBuildNode.addClass('left-connector');
$previousColumn.each(function() {
$this = $(this);
if ($('.build', $this).length === 1) $this.addClass('no-margin');
});
const secondChildBuildNodes = this.pipelineGraph.querySelectorAll('.build:nth-child(2)');
for (buildNodeIndex in secondChildBuildNodes) {
const buildNode = secondChildBuildNodes[buildNodeIndex];
const firstChildBuildNode = buildNode.previousElementSibling;
if (!firstChildBuildNode || !firstChildBuildNode.matches('.build')) continue;
const multiBuildColumn = buildNode.closest('.stage-column');
const previousColumn = multiBuildColumn.previousElementSibling;
if (!previousColumn || !previousColumn.matches('.stage-column')) continue;
multiBuildColumn.classList.add('left-margin');
firstChildBuildNode.classList.add('left-connector');
const columnBuilds = previousColumn.querySelectorAll('.build');
if (columnBuilds.length === 1) previousColumn.classList.add('no-margin');
}
$('.pipeline-graph').removeClass('hidden');
this.pipelineGraph.classList.remove('hidden');
}
}
......
......@@ -23,16 +23,12 @@
return $(this).parents('form').submit();
});
$('.hide-no-ssh-message').on('click', function(e) {
$.cookie('hide_no_ssh_message', 'false', {
path: gon.relative_url_root || '/'
});
Cookies.set('hide_no_ssh_message', 'false');
$(this).parents('.no-ssh-key-message').remove();
return e.preventDefault();
});
$('.hide-no-password-message').on('click', function(e) {
$.cookie('hide_no_password_message', 'false', {
path: gon.relative_url_root || '/'
});
Cookies.set('hide_no_password_message', 'false');
$(this).parents('.no-password-message').remove();
return e.preventDefault();
});
......
......@@ -38,9 +38,7 @@
$('.page-with-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded');
}
if (!triggered) {
return $.cookie("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'), {
path: gon.relative_url_root || '/'
});
return Cookies.set("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'));
}
});
return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo);
......
......@@ -28,7 +28,7 @@
}
init() {
this.isPinned = $.cookie(pinnedStateCookie) === 'true';
this.isPinned = Cookies.get(pinnedStateCookie) === 'true';
this.isExpanded = (
window.innerWidth >= sidebarBreakpoint &&
$(pageSelector).hasClass(expandedPageClass)
......@@ -62,10 +62,7 @@
if (!this.isPinned) {
this.isExpanded = false;
}
$.cookie(pinnedStateCookie, this.isPinned ? 'true' : 'false', {
path: gon.relative_url_root || '/',
expires: 3650
});
Cookies.set(pinnedStateCookie, this.isPinned ? 'true' : 'false', { expires: 3650 });
this.renderState();
}
......
......@@ -32,24 +32,22 @@
this.currentTemplate = currentTemplate;
if (err) return; // Error handled by global AJAX error handler
this.stopLoadingSpinner();
this.setInputValueToTemplateContent(true);
this.setInputValueToTemplateContent();
});
return;
}
setInputValueToTemplateContent(append) {
setInputValueToTemplateContent() {
// `this.requestFileSuccess` sets the value of the description input field
// to the content of the template selected. If `append` is true, the
// template content will be appended to the previous value of the field,
// separated by a blank line if the previous value is non-empty.
// to the content of the template selected.
if (this.titleInput.val() === '') {
// If the title has not yet been set, focus the title input and
// skip focusing the description input by setting `true` as the
// `skipFocus` option to `requestFileSuccess`.
this.requestFileSuccess(this.currentTemplate, {skipFocus: true, append});
this.requestFileSuccess(this.currentTemplate, {skipFocus: true});
this.titleInput.focus();
} else {
this.requestFileSuccess(this.currentTemplate, {skipFocus: false, append});
this.requestFileSuccess(this.currentTemplate, {skipFocus: false});
}
return;
}
......
......@@ -23,10 +23,7 @@
hideProjectLimitMessage() {
$('.hide-project-limit-message').on('click', e => {
e.preventDefault();
const path = gon.relative_url_root || '/';
$.cookie('hide_project_limit_message', 'false', {
path: path
});
Cookies.set('hide_project_limit_message', 'false');
$(this).parents('.project-limit-message').remove();
});
}
......
......@@ -37,7 +37,8 @@
}
@include keyframes(pulse) {
from, to {
from,
to {
@include webkit-prefix(transform, scale3d(1, 1, 1));
}
......
......@@ -128,7 +128,8 @@
position: relative;
.avatar-holder {
.avatar, .identicon {
.avatar,
.identicon {
margin: 0 auto;
float: none;
}
......
......@@ -213,7 +213,8 @@
top: 2px;
}
svg, .fa {
svg,
.fa {
&:not(:last-child) {
margin-right: 3px;
}
......
......@@ -143,7 +143,8 @@ li.note {
}
}
.wiki_content code, .readme code {
.wiki_content code,
.readme code {
background-color: inherit;
}
......@@ -350,7 +351,8 @@ table {
margin-right: 10px;
}
.alert, .progress {
.alert,
.progress {
margin-bottom: $gl-padding;
}
......@@ -372,3 +374,5 @@ table {
margin-right: -$gl-padding;
border-top: 1px solid $border-color;
}
.hide-bottom-border { border-bottom: none !important; }
......@@ -275,7 +275,8 @@
a {
padding-left: 25px;
&.is-indeterminate, &.is-active {
&.is-indeterminate,
&.is-active {
&::before {
position: absolute;
left: 5px;
......@@ -373,7 +374,8 @@
}
}
.dropdown-input-field, .default-dropdown-input {
.dropdown-input-field,
.default-dropdown-input {
width: 100%;
min-height: 30px;
padding: 0 7px;
......@@ -402,7 +404,7 @@
.dropdown-content {
max-height: 215px;
overflow-y: scroll;
overflow-y: auto;
}
.dropdown-footer {
......
......@@ -18,7 +18,8 @@
margin: 0;
}
.flash-notice, .flash-alert {
.flash-notice,
.flash-alert {
border-radius: $border-radius-default;
.container-fluid,
......@@ -30,7 +31,8 @@
&.flash-container-page {
margin-bottom: 0;
.flash-notice, .flash-alert {
.flash-notice,
.flash-alert {
border-radius: 0;
}
}
......
......@@ -25,7 +25,9 @@
a {
color: $color-light;
&:hover, &:focus, &:active {
&:hover,
&:focus,
&:active {
background: $color-dark;
}
......
......@@ -15,7 +15,8 @@ header {
margin: 8px 0;
text-align: center;
.tanuki-logo, img {
.tanuki-logo,
img {
height: 36px;
}
}
......@@ -54,7 +55,9 @@ header {
line-height: 28px;
text-align: center;
&:hover, &:focus, &:active {
&:hover,
&:focus,
&:active {
background-color: $background-color;
}
......@@ -125,7 +128,8 @@ header {
left: -50%;
}
svg, img {
svg,
img {
height: 36px;
}
......@@ -222,7 +226,8 @@ header {
margin: 0;
float: none !important;
.visible-xs, .visable-sm {
.visible-xs,
.visable-sm {
display: table-cell !important;
}
}
......
......@@ -76,14 +76,16 @@
/** light list with border-bottom between li **/
ul.bordered-list, ul.unstyled-list {
ul.bordered-list,
ul.unstyled-list {
@include basic-list;
&.top-list {
li:first-child {
padding-top: 0;
h4, h5 {
h4,
h5 {
margin-top: 0;
}
}
......
......@@ -79,7 +79,8 @@
padding-left: 15px !important;
}
.nav-links, .nav-links {
.nav-links,
.nav-links {
li a {
font-size: 14px;
padding: 19px 10px;
......@@ -99,18 +100,21 @@
@media (max-width: $screen-sm-max) {
.issues-filters {
.milestone-filter, .labels-filter {
.milestone-filter,
.labels-filter {
display: none;
}
}
.page-title {
.note-created-ago, .new-issue-link {
.note-created-ago,
.new-issue-link {
display: none;
}
}
.issue_edited_ago, .note_edited_ago {
.issue_edited_ago,
.note_edited_ago {
display: none;
}
......
......@@ -3,7 +3,7 @@
padding: 15px;
.form-actions {
margin: -$gl-padding+1;
margin: -$gl-padding + 1;
margin-top: 15px;
}
......
......@@ -54,7 +54,9 @@
color: #959494;
border-bottom: 2px solid transparent;
&:hover, &:active, &:focus {
&:hover,
&:active,
&:focus {
text-decoration: none;
outline: none;
}
......@@ -211,7 +213,11 @@
padding-bottom: 0;
width: 100%;
.btn, form, .dropdown, .dropdown-menu-toggle, .form-control {
.btn,
form,
.dropdown,
.dropdown-menu-toggle,
.form-control {
margin: 0 0 10px;
display: block;
width: 100%;
......@@ -245,7 +251,8 @@
}
&.adjust {
.nav-text, .nav-controls {
.nav-text,
.nav-controls {
width: auto;
}
}
......@@ -309,13 +316,15 @@
padding-top: 10px;
}
a, i {
a,
i {
color: $layout-link-gray;
}
&.active {
a, i {
a,
i {
color: $black;
}
......@@ -328,7 +337,8 @@
}
&:hover {
a, i {
a,
i {
color: $black;
}
}
......
......@@ -3,7 +3,8 @@
width: 100% !important;
}
.select2-container, .select2-container.select2-drop-above {
.select2-container,
.select2-container.select2-drop-above {
.select2-choice {
background: #fff;
border-color: $input-border;
......@@ -71,7 +72,8 @@
}
.select2-container-active {
.select2-choice, .select2-choices {
.select2-choice,
.select2-choices {
box-shadow: none;
}
}
......
......@@ -185,6 +185,10 @@ header.header-sidebar-pinned {
@media (min-width: $screen-sm-min) {
padding-right: $sidebar_collapsed_width;
.merge-request-tabs-holder.affix {
right: $sidebar_collapsed_width;
}
}
.sidebar-collapsed-icon {
......@@ -207,6 +211,10 @@ header.header-sidebar-pinned {
@media (min-width: $screen-md-min) {
padding-right: $gutter_width;
.merge-request-tabs-holder.affix {
right: $gutter_width;
}
}
&.with-overlay {
......
......@@ -23,7 +23,8 @@ table {
}
tr {
td, th {
td,
th {
padding: 10px $gl-padding;
line-height: 20px;
vertical-align: middle;
......
......@@ -126,7 +126,8 @@
box-shadow: none;
.panel-body {
form, pre {
form,
pre {
margin: 0;
}
......
......@@ -131,12 +131,14 @@
font-weight: inherit;
}
ul, ol {
ul,
ol {
padding: 0;
margin: 3px 0 3px 28px !important;
}
ul:dir(rtl), ol:dir(rtl) {
ul:dir(rtl),
ol:dir(rtl) {
margin: 3px 28px 3px 0 !important;
}
......@@ -144,7 +146,8 @@
line-height: 1.6em;
}
a[href*="/uploads/"], a[href*="storage.googleapis.com/google-code-attachments/"] {
a[href*="/uploads/"],
a[href*="storage.googleapis.com/google-code-attachments/"] {
&:before {
margin-right: 4px;
......@@ -167,7 +170,12 @@
}
/* Link to current header. */
h1, h2, h3, h4, h5, h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
a.anchor {
......@@ -215,7 +223,12 @@ body {
margin: 12px 7px;
}
h1, h2, h3, h4, h5, h6 {
h1,
h2,
h3,
h4,
h5,
h6 {
color: $gl-title-color;
font-weight: 600;
}
......@@ -273,7 +286,10 @@ a > code {
text-decoration: line-through;
}
h1, h2, h3, h4 {
h1,
h2,
h3,
h4 {
small {
color: $gl-gray;
}
......
/* https://github.com/MozMorris/tomorrow-pygments */
.code.dark {
// Line numbers
.line-numbers, .diff-line-num {
.line-numbers,
.diff-line-num {
background-color: #1d1f21;
}
.diff-line-num, .diff-line-num a {
.diff-line-num,
.diff-line-num a {
color: rgba(255, 255, 255, 0.3);
}
// Code itself
pre.code, .diff-line-num {
pre.code,
.diff-line-num {
border-color: #666;
}
&, pre.code, .line_holder .line_content {
&,
pre.code,
.line_holder .line_content {
background-color: #1d1f21;
color: #c5c8c6;
}
......@@ -31,11 +36,13 @@
border-color: darken(#557, 15%);
}
.diff-line-num.new, .line_content.new {
.diff-line-num.new,
.line_content.new {
@include diff_background(rgba(51, 255, 51, 0.1), rgba(51, 255, 51, 0.2), #808080);
}
.diff-line-num.old, .line_content.old {
.diff-line-num.old,
.line_content.old {
@include diff_background(rgba(255, 51, 51, 0.2), rgba(255, 51, 51, 0.25), #808080);
}
......
/* https://github.com/richleland/pygments-css/blob/master/monokai.css */
.code.monokai {
// Line numbers
.line-numbers, .diff-line-num {
.line-numbers,
.diff-line-num {
background-color: #272822;
}
.diff-line-num, .diff-line-num a {
.diff-line-num,
.diff-line-num a {
color: rgba(255, 255, 255, 0.3);
}
// Code itself
pre.code, .diff-line-num {
pre.code,
.diff-line-num {
border-color: #555;
}
&, pre.code, .line_holder .line_content {
&,
pre.code,
.line_holder .line_content {
background-color: #272822;
color: #f8f8f2;
}
......@@ -31,11 +36,13 @@
border-color: darken(#49483e, 15%);
}
.diff-line-num.new, .line_content.new {
.diff-line-num.new,
.line_content.new {
@include diff_background(rgba(166, 226, 46, 0.1), rgba(166, 226, 46, 0.15), #808080);
}
.diff-line-num.old, .line_content.old {
.diff-line-num.old,
.line_content.old {
@include diff_background(rgba(254, 147, 140, 0.15), rgba(254, 147, 140, 0.2), #808080);
}
......
/* https://gist.github.com/qguv/7936275 */
.code.solarized-dark {
// Line numbers
.line-numbers, .diff-line-num {
.line-numbers,
.diff-line-num {
background-color: #002b36;
}
.diff-line-num, .diff-line-num a {
.diff-line-num,
.diff-line-num a {
color: rgba(255, 255, 255, 0.3);
}
// Code itself
pre.code, .diff-line-num {
pre.code,
.diff-line-num {
border-color: #113b46;
}
&, pre.code, .line_holder .line_content {
&,
pre.code,
.line_holder .line_content {
background-color: #002b36;
color: #93a1a1;
}
......@@ -31,11 +36,13 @@
border-color: darken(#174652, 15%);
}
.diff-line-num.new, .line_content.new {
.diff-line-num.new,
.line_content.new {
@include diff_background(rgba(133, 153, 0, 0.15), rgba(133, 153, 0, 0.25), #113b46);
}
.diff-line-num.old, .line_content.old {
.diff-line-num.old,
.line_content.old {
@include diff_background(rgba(220, 50, 47, 0.3), rgba(220, 50, 47, 0.25), #113b46);
}
......
......@@ -7,20 +7,25 @@
.code.solarized-light {
// Line numbers
.line-numbers, .diff-line-num {
.line-numbers,
.diff-line-num {
background-color: #fdf6e3;
}
.diff-line-num, .diff-line-num a {
.diff-line-num,
.diff-line-num a {
color: $black-transparent;
}
// Code itself
pre.code, .diff-line-num {
pre.code,
.diff-line-num {
border-color: #c5d0d4;
}
&, pre.code, .line_holder .line_content {
&,
pre.code,
.line_holder .line_content {
background-color: #fdf6e3;
color: #586e75;
}
......@@ -37,11 +42,13 @@
border-color: darken(#ddd8c5, 15%);
}
.diff-line-num.new, .line_content.new {
.diff-line-num.new,
.line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.25), #c5d0d4);
}
.diff-line-num.old, .line_content.old {
.diff-line-num.old,
.line_content.old {
@include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.25), #c5d0d4);
}
......
......@@ -7,20 +7,25 @@
.code.white {
// Line numbers
.line-numbers, .diff-line-num {
.line-numbers,
.diff-line-num {
background-color: $background-color;
}
.diff-line-num, .diff-line-num a {
.diff-line-num,
.diff-line-num a {
color: $black-transparent;
}
// Code itself
pre.code, .diff-line-num {
pre.code,
.diff-line-num {
border-color: $table-border-gray;
}
&, pre.code, .line_holder .line_content {
&,
pre.code,
.line_holder .line_content {
background-color: #fff;
color: #333;
}
......
......@@ -56,7 +56,8 @@
padding: 10px;
text-align: center;
> div, p {
> div,
p {
display: inline;
margin: 0;
......
......@@ -12,7 +12,8 @@
border-color: $border-color;
}
th, td {
th,
td {
padding: 10px $gl-padding;
}
......
......@@ -2,14 +2,16 @@
display: block;
}
.commit-author, .commit-committer {
.commit-author,
.commit-committer {
display: block;
color: #999;
font-weight: normal;
font-style: italic;
}
.commit-author strong, .commit-committer strong {
.commit-author strong,
.commit-committer strong {
font-weight: bold;
font-style: normal;
}
......
......@@ -63,7 +63,8 @@
display: inline-block;
}
.btn-clipboard, .btn-transparent {
.btn-clipboard,
.btn-transparent {
padding-left: 0;
padding-right: 0;
}
......@@ -162,7 +163,8 @@
.branch-commit {
color: $gl-gray;
.commit-id, .commit-row-message {
.commit-id,
.commit-row-message {
color: $gl-gray;
}
}
......
......@@ -2,7 +2,12 @@
margin-bottom: 20px;
border-bottom: 1px solid #eee;
> h1, h2, h3, h4, h5, h6 {
> h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 400;
}
......@@ -10,7 +15,8 @@
margin-bottom: 20px;
}
ul, ol {
ul,
ol {
padding-left: 0;
}
......
......@@ -13,7 +13,8 @@
color: #5c5d5e;
}
.issue_created_ago, .author_link {
.issue_created_ago,
.author_link {
white-space: nowrap;
}
}
......
......@@ -124,7 +124,8 @@
}
}
.old_line, .new_line {
.old_line,
.new_line {
margin: 0;
padding: 0;
border: none;
......@@ -281,7 +282,8 @@
position: relative;
}
.frame.added, .frame.deleted {
.frame.added,
.frame.deleted {
position: absolute;
display: block;
top: 0;
......@@ -347,7 +349,8 @@
text-align: center;
background: #eee;
ul, li {
ul,
li {
list-style: none;
margin: 0;
padding: 0;
......
......@@ -91,7 +91,9 @@
}
}
.gitignore-selector, .license-selector, .gitlab-ci-yml-selector {
.gitignore-selector,
.license-selector,
.gitlab-ci-yml-selector {
.dropdown {
line-height: 21px;
}
......
......@@ -2,7 +2,9 @@
max-width: 400px;
margin: 0 auto;
h1, h2, h3 {
h1,
h2,
h3 {
text-align: center;
}
......
......@@ -43,7 +43,8 @@ ul.related-merge-requests > li {
}
}
.merge-requests-title, .related-branches-title {
.merge-requests-title,
.related-branches-title {
font-size: 16px;
font-weight: 600;
}
......
......@@ -41,7 +41,8 @@
font-size: 13px;
}
.login-box, .omniauth-container {
.login-box,
.omniauth-container {
box-shadow: 0 0 0 1px $border-color;
border-bottom-right-radius: 2px;
border-bottom-left-radius: 2px;
......@@ -53,6 +54,7 @@
margin: 0 0 10px;
}
.login-footer {
margin-top: 10px;
......@@ -142,6 +144,7 @@
&:not(.active) {
background-color: $gray-light;
border-left: 1px solid $border-color;
}
a {
......@@ -169,9 +172,35 @@
}
}
// Ldap configurations may need more tabs & the tab labels are user generated (arbitrarily long).
// These styles prevent this from breaking the layout, and only applied when providers are configured.
.new-session-tabs.custom-provider-tabs {
flex-wrap: wrap;
li {
min-width: 85px;
flex-basis: auto;
// This styles tab elements that have wrapped to a second line. We cannot easily predict when this will happen.
// We are making somewhat of an assumption about the configuration here: that users do not have more than
// 3 LDAP servers configured (in addition to standard login) and they are not using especially long names for any
// of them. If either condition is false, this will work as expected. If both are true, there may be a missing border
// above one of the bottom row elements. If you know a better way, please implement it!
&:nth-child(n+5) {
border-top: 1px solid $border-color;
}
}
a {
font-size: 16px;
}
}
.form-control {
&:active, &:focus {
&:active,
&:focus {
background-color: #fff;
}
}
......@@ -202,6 +231,7 @@
.login-page {
.col-sm-5.pull-right {
float: none !important;
margin-bottom: 45px;
}
}
}
......@@ -233,7 +263,8 @@
position: relative;
}
.footer-container, hr.footer-fixed {
.footer-container,
hr.footer-fixed {
position: absolute;
bottom: 0;
left: 0;
......@@ -243,6 +274,34 @@
}
.navless-container {
padding: 65px; // height of footer + bottom padding of email confirmation link
padding: 65px 15px; // height of footer + bottom padding of email confirmation link
@media (max-width: $screen-xs-max) {
padding: 0 15px 65px;
}
}
}
// For sign in pane only, to improve tab order, the following removes the submit button from
// normal document flow and pins it to the bottom of the form. For context, see !6867 & !6928
.login-box {
.new_user {
position: relative;
padding-bottom: 35px;
@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
.forgot-password {
float: none !important;
margin-top: 5px;
}
}
}
.move-submit-down {
position: absolute;
width: 100%;
bottom: 0;
}
}
......@@ -101,7 +101,8 @@ $colors: (
@mixin color-scheme($color) {
.header.line_content, .diff-line-num {
.header.line_content,
.diff-line-num {
&.origin {
background-color: map-get($colors, #{$color}_header_origin_neutral);
border-color: map-get($colors, #{$color}_header_origin_neutral);
......
......@@ -438,11 +438,18 @@
}
}
.merge-request-tabs {
.merge-request-tabs-holder {
background-color: #fff;
&.affix {
top: 100px;
left: 0;
z-index: 9;
transition: right .15s;
}
&:not(.affix) .container-fluid {
padding-left: 0;
padding-right: 0;
}
}
......@@ -50,7 +50,8 @@
}
}
.issues-sortable-list, .merge_requests-sortable-list {
.issues-sortable-list,
.merge_requests-sortable-list {
.issuable-detail {
display: block;
margin-top: 7px;
......
......@@ -8,7 +8,7 @@
.diff-file .diff-content {
tr.line_holder:hover > td .line_note_link {
opacity: 1.0;
filter: alpha(opacity=100);
filter: alpha(opacity = 100);
}
}
......@@ -24,7 +24,8 @@
display: none;
}
.new-note, .note-edit-form {
.new-note,
.note-edit-form {
.note-form-actions {
margin-top: $gl-padding;
}
......
......@@ -28,7 +28,8 @@ ul.notes {
}
}
.note-created-ago, .note-updated-at {
.note-created-ago,
.note-updated-at {
white-space: nowrap;
}
......
......@@ -248,7 +248,8 @@
font-size: 14px;
}
svg, .fa {
svg,
.fa {
margin-right: 0;
}
}
......@@ -369,10 +370,6 @@
&:hover {
background-color: $gray-lighter;
.dropdown-menu-toggle {
background-color: transparent;
}
}
&.playable {
......@@ -402,6 +399,15 @@
}
}
.tooltip {
white-space: nowrap;
.tooltip-inner {
overflow: hidden;
text-overflow: ellipsis;
}
}
.ci-status-text {
width: 135px;
white-space: nowrap;
......@@ -419,6 +425,7 @@
}
.dropdown-menu-toggle {
background-color: transparent;
border: none;
width: auto;
padding: 0;
......@@ -523,7 +530,8 @@
// Connect each build (except for first) with curved lines
&:not(:first-child) {
&::after, &::before {
&::after,
&::before {
content: '';
top: -49px;
position: absolute;
......@@ -549,7 +557,8 @@
// Connect second build to first build with smaller curved line
&:nth-child(2) {
&::after, &::before {
&::after,
&::before {
height: 29px;
top: -9px;
}
......@@ -564,7 +573,8 @@
.build {
// Remove right connecting horizontal line from first build in last stage
&:first-child {
&::after, &::before {
&::after,
&::before {
border: none;
}
}
......
......@@ -253,7 +253,8 @@
}
table.u2f-registrations {
th:not(:last-child), td:not(:last-child) {
th:not(:last-child),
td:not(:last-child) {
border-right: solid 1px transparent;
}
}
\ No newline at end of file
......@@ -6,16 +6,26 @@
}
}
.no-ssh-key-message, .project-limit-message {
.no-ssh-key-message,
.project-limit-message {
background-color: #f28d35;
margin-bottom: 0;
}
.new_project,
.edit-project {
fieldset {
&.features .control-label {
font-weight: normal;
&.features {
.label-light {
margin-bottom: 0;
}
.help-block {
margin-top: 0;
}
}
.form-group {
......@@ -40,6 +50,7 @@
}
.input-group > div {
&:last-child {
padding-right: 0;
}
......@@ -47,6 +58,7 @@
@media (max-width: $screen-xs-max) {
.input-group > div {
margin-bottom: 14px;
&:last-child {
......@@ -60,6 +72,7 @@
}
.input-group-addon {
&.static-namespace {
height: 35px;
border-radius: 3px;
......@@ -373,7 +386,8 @@ a.deploy-project-label {
text-align: center;
width: 169px;
&:hover, &.forked {
&:hover,
&.forked {
background-color: $row-hover;
border-color: $row-hover-border;
}
......@@ -722,7 +736,8 @@ pre.light-well {
.table-bordered {
border-radius: 1px;
th:not(:last-child), td:not(:last-child) {
th:not(:last-child),
td:not(:last-child) {
border-right: solid 1px transparent;
}
}
......@@ -745,7 +760,8 @@ pre.light-well {
}
}
.project-refs-form .dropdown-menu, .dropdown-menu-projects {
.project-refs-form .dropdown-menu,
.dropdown-menu-projects {
width: 300px;
@media (min-width: $screen-sm-min) {
......
......@@ -65,7 +65,8 @@
.search-input-wrap {
width: 100%;
.search-icon, .clear-icon {
.search-icon,
.clear-icon {
position: absolute;
right: 5px;
top: 0;
......@@ -185,7 +186,8 @@
padding-right: $gl-padding + 15px;
}
.btn-search, .btn-new {
.btn-search,
.btn-new {
width: 100%;
margin-top: 5px;
......
......@@ -23,7 +23,8 @@
border-bottom: 1px solid $table-border-gray;
border-top: 1px solid $table-border-gray;
td, th {
td,
th {
line-height: 21px;
}
......@@ -74,7 +75,8 @@
max-width: 320px;
vertical-align: middle;
i, a {
i,
a {
color: $gl-dark-link-color;
}
......
.wiki h1, .wiki h2, .wiki h3, .wiki h4, .wiki h5, .wiki h6 {margin-top: 17px; }
.wiki h1 {font-size: 30px;}
.wiki h2 {font-size: 22px;}
.wiki h3 {font-size: 18px; font-weight: bold; }
.wiki h1,
.wiki h2,
.wiki h3,
.wiki h4,
.wiki h5,
.wiki h6 {
margin-top: 17px;
}
.wiki h1 {
font-size: 30px;
}
.wiki h2 {
font-size: 22px;
}
.wiki h3 {
font-size: 18px;
font-weight: bold;
}
header,
nav,
......
......@@ -21,6 +21,10 @@ class Groups::GroupMembersController < Groups::ApplicationController
end
def create
if params[:user_ids].blank?
return redirect_to(group_group_members_path(@group), alert: 'No users specified.')
end
@group.add_users(
params[:user_ids].split(','),
params[:access_level],
......
......@@ -2,8 +2,8 @@ class Import::GitlabProjectsController < Import::BaseController
before_action :verify_gitlab_project_import_enabled
def new
@namespace_id = project_params[:namespace_id]
@namespace_name = Namespace.find(project_params[:namespace_id]).name
@namespace = Namespace.find(project_params[:namespace_id])
return render_404 unless current_user.can?(:create_projects, @namespace)
@path = project_params[:path]
end
......
......@@ -13,7 +13,7 @@ class Projects::CommitsController < Projects::ApplicationController
@commits =
if search.present?
@repository.find_commits_by_message(search, @ref, @path, @limit, @offset).compact
@repository.find_commits_by_message(search, @ref, @path, @limit, @offset)
else
@repository.commits(@ref, path: @path, limit: @limit, offset: @offset)
end
......
......@@ -398,7 +398,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
status ||= "preparing"
else
ci_service = @merge_request.source_project.ci_service
ci_service = @merge_request.source_project.try(:ci_service)
status = ci_service.commit_status(merge_request.diff_head_sha, merge_request.source_branch) if ci_service
if ci_service.respond_to?(:commit_coverage)
......@@ -554,7 +554,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def define_pipelines_vars
@pipelines = @merge_request.all_pipelines
if @pipelines.any?
if @pipelines.present?
@pipeline = @pipelines.first
@statuses = @pipeline.statuses.relevant
end
......
......@@ -25,6 +25,10 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
def create
if params[:user_ids].blank?
return redirect_to(namespace_project_project_members_path(@project.namespace, @project), alert: 'No users or groups specified.')
end
@project.team.add_users(
params[:user_ids].split(','),
params[:access_level],
......@@ -32,22 +36,7 @@ class Projects::ProjectMembersController < Projects::ApplicationController
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), notice: 'Users were successfully added.'
end
def update
......
......@@ -35,8 +35,10 @@ class LabelsFinder < UnionFinder
end
def with_title(items)
items = items.where(title: title) if title
items
return items if title.nil?
return items.none if title.blank?
items.where(title: title)
end
def group_id
......@@ -48,11 +50,11 @@ class LabelsFinder < UnionFinder
end
def projects_ids
params[:project_ids].presence
params[:project_ids]
end
def title
params[:title].presence || params[:name].presence
params[:title] || params[:name]
end
def project
......
......@@ -5,7 +5,7 @@ module BoardsHelper
{
endpoint: namespace_project_boards_path(@project.namespace, @project),
board_id: board.id,
disabled: !can?(current_user, :admin_list, @project),
disabled: "#{!can?(current_user, :admin_list, @project)}",
issue_link_base: namespace_project_issues_path(@project.namespace, @project)
}
end
......
......@@ -86,11 +86,15 @@ module MergeRequestsHelper
end
def source_branch_with_namespace(merge_request)
branch = link_to(merge_request.source_branch, namespace_project_commits_path(merge_request.source_project.namespace, merge_request.source_project, merge_request.source_branch))
namespace = merge_request.source_project_namespace
branch = merge_request.source_branch
if merge_request.source_branch_exists?
namespace = link_to(namespace, project_path(merge_request.source_project))
branch = link_to(branch, namespace_project_commits_path(merge_request.source_project.namespace, merge_request.source_project, merge_request.source_branch))
end
if merge_request.for_fork?
namespace = link_to(merge_request.source_project_namespace,
project_path(merge_request.source_project))
namespace + ":" + branch
else
branch
......
......@@ -3,8 +3,8 @@ module Ci
include TokenAuthenticatable
include AfterCommitQueue
belongs_to :runner, class_name: 'Ci::Runner'
belongs_to :trigger_request, class_name: 'Ci::TriggerRequest'
belongs_to :runner
belongs_to :trigger_request
belongs_to :erased_by, class_name: 'User'
serialize :options
......
......@@ -7,12 +7,12 @@ module Ci
self.table_name = 'ci_commits'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :project, foreign_key: :gl_project_id
belongs_to :user
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
has_many :builds, class_name: 'Ci::Build', foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest', foreign_key: :commit_id
has_many :builds, foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id
validates_presence_of :sha, unless: :importing?
validates_presence_of :ref, unless: :importing?
......@@ -59,9 +59,6 @@ module Ci
before_transition any => [:success, :failed, :canceled] do |pipeline|
pipeline.finished_at = Time.now
end
before_transition do |pipeline|
pipeline.update_duration
end
......
......@@ -6,9 +6,9 @@ module Ci
AVAILABLE_SCOPES = %w[specific shared active paused online]
FORM_EDITABLE = %i[description tag_list active run_untagged locked]
has_many :builds, class_name: 'Ci::Build'
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject'
has_many :projects, through: :runner_projects, class_name: '::Project', foreign_key: :gl_project_id
has_many :builds
has_many :runner_projects, dependent: :destroy
has_many :projects, through: :runner_projects, foreign_key: :gl_project_id
has_one :last_build, ->() { order('id DESC') }, class_name: 'Ci::Build'
......
......@@ -2,8 +2,8 @@ module Ci
class RunnerProject < ActiveRecord::Base
extend Ci::Model
belongs_to :runner, class_name: 'Ci::Runner'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :runner
belongs_to :project, foreign_key: :gl_project_id
validates_uniqueness_of :runner_id, scope: :gl_project_id
end
......
......@@ -4,8 +4,8 @@ module Ci
acts_as_paranoid
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
belongs_to :project, foreign_key: :gl_project_id
has_many :trigger_requests, dependent: :destroy
validates_presence_of :token
validates_uniqueness_of :token
......
......@@ -2,9 +2,9 @@ module Ci
class TriggerRequest < ActiveRecord::Base
extend Ci::Model
belongs_to :trigger, class_name: 'Ci::Trigger'
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
has_many :builds, class_name: 'Ci::Build'
belongs_to :trigger
belongs_to :pipeline, foreign_key: :commit_id
has_many :builds
serialize :variables
......
......@@ -2,7 +2,7 @@ module Ci
class Variable < ActiveRecord::Base
extend Ci::Model
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :project, foreign_key: :gl_project_id
validates_uniqueness_of :key, scope: :gl_project_id
validates :key,
......
......@@ -5,7 +5,7 @@ class CommitStatus < ActiveRecord::Base
self.table_name = 'ci_builds'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :project, foreign_key: :gl_project_id
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
belongs_to :user
......
module ProtectedBranchAccess
extend ActiveSupport::Concern
included do
scope :master, -> { where(access_level: Gitlab::Access::MASTER) }
scope :developer, -> { where(access_level: Gitlab::Access::DEVELOPER) }
end
def humanize
self.class.human_access_levels[self.access_level]
end
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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.
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