Commit 490ae8a6 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'ee/master' into ce-to-ee-2017-07-28

* ee/master:
  And end
  Squashed commit of the following:
  Trailing Spaces removed
  Moves the Performance Bar to the top instead of being at the bottom
  Fix remote mirror last_update_at nil error in view
  Adds restrict group owners to admins option to admin application settings dashboard
  Working File Locks
  Update CHANGELOG.md for 9.4.2
  Update CHANGELOG-EE.md for 9.4.2-ee
  Converting it to true string if :file_locks available
  Merge issuable "reopened" state into "opened"
  Remove :remove_default_access_levels and use
  Replace autodeploy guide image to use blank namespace
  Latest Changes from CE applied
  Removed Path Locks from _tree_content.html.haml
  removed similar code
  fixed form submitting
  EE port of ph-inline-js
  Applied Patch of inline-js-removal-projects-other from CE Also removed Additional EE Inline Script on _tree_content.html.haml
parents 2b84e500 d8aec0b7
Please view this file on the master branch, on stable branches it's out of date.
## 9.4.2 (2017-07-28)
- Adds lower bound to pull mirror scheduling feature. !2366
- Add warning and option toggle when rebuilding authorized_keys. !2508
- Fix CSS for mini graph with downstream pipeline.
- Renamed board to boards in new project sidebar.
- Fix Rebasing not working with Merge Requests.
- Fixed issue boards focus mode when new navigation is turned on.
## 9.4.1 (2017-07-25)
- Cleans up mirror capacity in project destroy service if project is a scheduled mirror. !2445
......
......@@ -2,6 +2,21 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 9.4.2 (2017-07-28)
- Fix job merge request link to a forked source project. !12965
- Improve redirect route query performance. !13062
- Allow admin to read_users_list even if it's restricted. !13066
- Fixes 500 error caused by pending delete projects in admin dashboard. !13067
- Add instrumentation to MarkupHelper#link_to_gfm. !13069
- Pending delete projects should not show in deploy keys. !13088
- Fix sizing of custom header logo in new navigation.
- Fix crash on /help/ui.
- Fix creating merge request diffs when diff contains bytes that are invalid in UTF-8.
- fix vertical alignment of New Project button.
- Add LDAP SSL certificate verification option.
- Fix vertical alignment in firefox and safari for pipeline mini graph.
## 9.4.1 (2017-07-25)
- Fix pipeline_schedules pages throwing error 500 (when ref is empty). !12983
......
......@@ -24,11 +24,6 @@ class AuditLogs {
$('.project-item-select').on('click', () => {
$('form.filter-form').submit();
});
$('form.filter-form').on('submit', function applyFilters(event) {
event.preventDefault();
gl.utils.visitUrl(`${this.action}?${$(this).serialize()}`);
});
}
initFilterDropdown($dropdown, fieldName, searchFields, cb) {
......
......@@ -8,6 +8,7 @@
/* global LabelsSelect */
/* global MilestoneSelect */
/* global Commit */
/* global NewBranchForm */
/* global NotificationsForm */
/* global NotificationsDropdown */
/* global GroupAvatar */
......@@ -23,6 +24,7 @@
/* global MergeRequest */
/* global Compare */
/* global CompareAutocomplete */
/* global PathLocks */
/* global ProjectNew */
/* global ProjectShow */
/* global Labels */
......@@ -68,6 +70,9 @@ import initExperimentalFlags from './experimental_flags';
import OAuthRememberMe from './oauth_remember_me';
import PerformanceBar from './performance_bar';
import GpgBadges from './gpg_badges';
import initNotes from './init_notes';
import initLegacyFilters from './init_legacy_filters';
import initIssuableSidebar from './init_issuable_sidebar';
// EE-only
import ApproversSelect from './approvers_select';
......@@ -166,6 +171,8 @@ import AuditLogs from './audit_logs';
new Issue();
shortcut_handler = new ShortcutsIssuable();
new ZenMode();
initIssuableSidebar();
initNotes();
break;
case 'dashboard:milestones:index':
new ProjectSelect();
......@@ -176,10 +183,12 @@ import AuditLogs from './audit_logs';
new Milestone();
new Sidebar();
break;
case 'dashboard:issues':
case 'dashboard:merge_requests':
case 'groups:issues':
case 'groups:merge_requests':
new UsersSelect();
new ProjectSelect();
initLegacyFilters();
break;
case 'dashboard:todos:index':
new Todos();
......@@ -259,7 +268,10 @@ import AuditLogs from './audit_logs';
case 'projects:tags:new':
new ZenMode();
new gl.GLForm($('.tag-form'), true);
new RefSelectDropdown($('.js-branch-select'), window.gl.availableRefs);
new RefSelectDropdown($('.js-branch-select'));
break;
case 'projects:snippets:show':
initNotes();
break;
case 'projects:snippets:new':
case 'projects:snippets:edit':
......@@ -285,15 +297,12 @@ import AuditLogs from './audit_logs';
window.mergeRequest = new MergeRequest({
action: mrShowNode.dataset.mrAction,
});
initIssuableSidebar();
initNotes();
break;
case 'dashboard:activity':
new gl.Activities();
break;
case 'dashboard:issues':
case 'dashboard:merge_requests':
new ProjectSelect();
new UsersSelect();
break;
case 'projects:commit:show':
new Commit();
new gl.Diff();
......@@ -302,6 +311,7 @@ import AuditLogs from './audit_logs';
new MiniPipelineGraph({
container: '.js-commit-pipeline-graph',
}).bindEvents();
initNotes();
break;
case 'projects:commit:pipelines':
new MiniPipelineGraph({
......@@ -331,6 +341,9 @@ import AuditLogs from './audit_logs';
case 'projects:edit':
setupProjectEdit();
break;
case 'projects:pipelines:new':
new NewBranchForm($('.js-new-pipeline-form'));
break;
case 'projects:pipelines:builds':
case 'projects:pipelines:failures':
case 'projects:pipelines:show':
......@@ -384,6 +397,17 @@ import AuditLogs from './audit_logs';
shortcut_handler = new ShortcutsNavigation();
new TreeView();
new BlobViewer();
if (document.querySelector('.js-tree-content').dataset.pathLocksAvailable === 'true') {
PathLocks.init(
document.querySelector('.js-tree-content').dataset.pathLocksToggle,
document.querySelector('.js-tree-content').dataset.pathLocksPath,
);
}
$('#tree-slider').waitForImages(function() {
gl.utils.ajaxGet(document.querySelector('.js-tree-content').dataset.logsPath);
});
break;
case 'projects:find_file:show':
shortcut_handler = true;
......@@ -401,10 +425,20 @@ import AuditLogs from './audit_logs';
case 'projects:labels:edit':
new Labels();
break;
case 'groups:labels:index':
case 'projects:labels:index':
if ($('.prioritized-labels').length) {
new gl.LabelManager();
}
$('.label-subscription').each((i, el) => {
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
new gl.GroupLabelSubscription($el);
} else {
new gl.ProjectLabelSubscription($el);
}
});
break;
case 'projects:network:show':
// Ensure we don't create a particular shortcut handler here. This is
......@@ -460,10 +494,15 @@ import AuditLogs from './audit_logs';
case 'snippets:show':
new LineHighlighter();
new BlobViewer();
initNotes();
break;
case 'import:fogbugz:new_user_map':
new UsersSelect();
break;
case 'profiles:personal_access_tokens:index':
case 'admin:impersonation_tokens:index':
new gl.DueDateSelectors();
break;
}
switch (path.first()) {
case 'sessions':
......@@ -541,6 +580,7 @@ import AuditLogs from './audit_logs';
shortcut_handler = new ShortcutsWiki();
new ZenMode();
new gl.GLForm($('.wiki-form'), true);
new Sidebar();
break;
case 'snippets':
shortcut_handler = new ShortcutsNavigation();
......
/* eslint-disable no-new */
/* global MilestoneSelect */
/* global LabelsSelect */
/* global WeightSelect */
/* global IssuableContext */
/* global Sidebar */
export default () => {
const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
new MilestoneSelect({
full_path: sidebarOptions.fullPath,
});
new LabelsSelect();
new WeightSelect();
new IssuableContext(sidebarOptions.currentUser);
gl.Subscription.bindAll('.subscription');
new gl.DueDateSelectors();
window.sidebar = new Sidebar();
};
/* eslint-disable no-new */
/* global LabelsSelect */
/* global MilestoneSelect */
/* global IssueStatusSelect */
/* global SubscriptionSelect */
/* global WeightSelect */
import UsersSelect from './users_select';
export default () => {
new UsersSelect();
new LabelsSelect();
new MilestoneSelect();
new IssueStatusSelect();
new SubscriptionSelect();
new WeightSelect();
};
/* global Notes */
export default () => {
const dataEl = document.querySelector('.js-notes-data');
const {
notesUrl,
notesIds,
now,
diffView,
autocomplete,
} = JSON.parse(dataEl.innerHTML);
window.notes = new Notes(notesUrl, notesIds, now, diffView, autocomplete);
};
......@@ -53,7 +53,7 @@ export default {
return this.state && this.state.length > 0;
},
isOpen() {
return this.state === 'opened' || this.state === 'reopened';
return this.state === 'opened';
},
isClosed() {
return this.state === 'closed';
......
......@@ -4,6 +4,8 @@
import Cookies from 'js-cookie';
import UsersSelect from './users_select';
const PARTICIPANTS_ROW_COUNT = 7;
(function() {
this.IssuableContext = (function() {
function IssuableContext(currentUser) {
......@@ -50,11 +52,9 @@ import UsersSelect from './users_select';
}
IssuableContext.prototype.initParticipants = function() {
var _this;
_this = this;
$(document).on("click", ".js-participants-more", this.toggleHiddenParticipants);
return $(".js-participants-author").each(function(i) {
if (i >= _this.PARTICIPANTS_ROW_COUNT) {
if (i >= PARTICIPANTS_ROW_COUNT) {
return $(this).addClass("js-participants-hidden").hide();
}
});
......
......@@ -145,7 +145,6 @@ import './right_sidebar';
import './search';
import './search_autocomplete';
import './smart_interval';
import './snippets_list';
import './star';
import './subscription';
import './subscription_select';
......@@ -365,4 +364,14 @@ $(function () {
gl.utils.renderTimeago();
$(document).trigger('init.scrolling-tabs');
$('form.filter-form').on('submit', function (event) {
const link = document.createElement('a');
link.href = this.action;
const action = `${this.action}${link.search === '' ? '?' : '&'}`;
event.preventDefault();
gl.utils.visitUrl(`${action}${$(this).serialize()}`);
});
});
......@@ -2,6 +2,7 @@
/* global Flash */
import Vue from 'vue';
import initIssuableSidebar from '../init_issuable_sidebar';
import './merge_conflict_store';
import './merge_conflict_service';
import './mixins/line_conflict_utils';
......@@ -19,6 +20,8 @@ $(() => {
resolveConflictsPath: conflictsEl.dataset.resolveConflictsPath
});
initIssuableSidebar();
gl.MergeConflictsResolverApp = new Vue({
el: '#conflicts',
data: mergeConflictsStore.state,
......
......@@ -8,7 +8,7 @@
var _this, $els;
if (currentProject != null) {
_this = this;
this.currentProject = JSON.parse(currentProject);
this.currentProject = typeof currentProject === 'string' ? JSON.parse(currentProject) : currentProject;
}
$els = $(els);
......
import Chart from 'vendor/Chart';
document.addEventListener('DOMContentLoaded', () => {
const chartData = JSON.parse(document.getElementById('pipelinesChartsData').innerHTML);
const buildChart = (chartScope) => {
const data = {
labels: chartScope.labels,
datasets: [{
fillColor: '#7f8fa4',
strokeColor: '#7f8fa4',
pointColor: '#7f8fa4',
pointStrokeColor: '#EEE',
data: chartScope.totalValues,
},
{
fillColor: '#44aa22',
strokeColor: '#44aa22',
pointColor: '#44aa22',
pointStrokeColor: '#fff',
data: chartScope.successValues,
},
],
};
const ctx = $(`#${chartScope.scope}Chart`).get(0).getContext('2d');
const options = {
scaleOverlay: true,
responsive: true,
maintainAspectRatio: false,
};
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8;
}
new Chart(ctx).Line(data, options);
};
chartData.forEach(scope => buildChart(scope));
});
import Chart from 'vendor/Chart';
document.addEventListener('DOMContentLoaded', () => {
const chartData = JSON.parse(document.getElementById('pipelinesTimesChartsData').innerHTML);
const data = {
labels: chartData.labels,
datasets: [{
fillColor: 'rgba(220,220,220,0.5)',
strokeColor: 'rgba(220,220,220,1)',
barStrokeWidth: 1,
barValueSpacing: 1,
barDatasetSpacing: 1,
data: chartData.values,
}],
};
const ctx = $('#build_timesChart').get(0).getContext('2d');
const options = {
scaleOverlay: true,
responsive: true,
maintainAspectRatio: false,
};
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8;
}
new Chart(ctx).Bar(data, options);
});
......@@ -6,21 +6,27 @@ import Cookies from 'js-cookie';
(function() {
this.Project = (function() {
function Project() {
$('ul.clone-options-dropdown a').click(function() {
var url;
if ($(this).hasClass('active')) {
return;
}
$('.active').not($(this)).removeClass('active');
$(this).toggleClass('active');
url = $("#project_clone").val();
$('#project_clone').val(url);
const $cloneOptions = $('ul.clone-options-dropdown');
const $projectCloneField = $('#project_clone');
const $cloneBtnText = $('a.clone-dropdown-btn span');
$('a', $cloneOptions).on('click', (e) => {
const $this = $(e.currentTarget);
const url = $this.attr('href');
e.preventDefault();
$('.active', $cloneOptions).not($this).removeClass('active');
$this.toggleClass('active');
$projectCloneField.val(url);
$cloneBtnText.text($this.text());
$('#modal-geo-info').data({
cloneUrlSecondary: $this.attr('href'),
cloneUrlPrimary: $this.data('primaryUrl') || ''
});
return $('.clone').text(url);
// Git protocol switcher
// Remove the active class for all buttons (ssh, http, kerberos if shown)
// Add the active class for the clicked button
// Update the input field
// Update the command line instructions
});
// Ref switcher
this.initRefSwitcher();
......
document.addEventListener('DOMContentLoaded', () => {
const importBtnTooltip = 'Please enter a valid project name.';
const $importBtnWrapper = $('.import_gitlab_project');
$('.how_to_import_link').on('click', (e) => {
e.preventDefault();
$('.how_to_import_link').next('.modal').show();
});
$('.modal-header .close').on('click', () => {
$('.modal').hide();
});
$('.btn_import_gitlab_project').on('click', () => {
const importHref = $('a.btn_import_gitlab_project').attr('href');
$('.btn_import_gitlab_project').attr('href', `${importHref}?namespace_id=${$('#project_namespace_id').val()}&path=${$('#project_path').val()}`);
});
$('.btn_import_gitlab_project').attr('disabled', !$('#project_path').val().trim().length);
$importBtnWrapper.attr('title', importBtnTooltip);
$('#new_project').on('submit', () => {
const $path = $('#project_path');
$path.val($path.val().trim());
});
$('#project_path').on('keyup', () => {
if ($('#project_path').val().trim().length) {
$('.btn_import_gitlab_project').attr('disabled', false);
$importBtnWrapper.attr('title', '');
$importBtnWrapper.removeClass('has-tooltip');
} else {
$('.btn_import_gitlab_project').attr('disabled', true);
$importBtnWrapper.addClass('has-tooltip');
}
});
$('#project_import_url').disable();
$('.import_git').on('click', () => {
const $projectImportUrl = $('#project_import_url');
$projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
});
});
class RefSelectDropdown {
constructor($dropdownButton, availableRefs) {
const availableRefsValue = availableRefs || JSON.parse(document.getElementById('availableRefs').innerHTML);
$dropdownButton.glDropdown({
data: availableRefs,
data: availableRefsValue,
filterable: true,
filterByText: true,
remote: false,
......
......@@ -5,7 +5,8 @@ import sidebarAssignees from './components/assignees/sidebar_assignees';
import Mediator from './sidebar_mediator';
function domContentLoaded() {
const mediator = new Mediator(gl.sidebarOptions);
const sidebarOptions = JSON.parse(document.querySelector('.js-sidebar-options').innerHTML);
const mediator = new Mediator(sidebarOptions);
mediator.fetch();
const sidebarAssigneesEl = document.querySelector('#js-vue-sidebar-assignees');
......
function SnippetsList() {
const $holder = $('.snippets-list-holder');
$holder.find('.pagination').on('ajax:success', (e, data) => {
$holder.replaceWith(data.html);
});
}
window.gl.SnippetsList = SnippetsList;
......@@ -37,10 +37,6 @@ export default class Todos {
this.initFilterDropdown($('.js-type-search'), 'type');
this.initFilterDropdown($('.js-action-search'), 'action_id');
$('form.filter-form').on('submit', function applyFilters(event) {
event.preventDefault();
gl.utils.visitUrl(`${this.action}&${$(this).serialize()}`);
});
return new UsersSelect();
}
......
......@@ -67,7 +67,7 @@ export default class MergeRequestStore {
this.mergeCheckPath = data.merge_check_path;
this.mergeActionsContentPath = data.commit_change_content_path;
this.isRemovingSourceBranch = this.isRemovingSourceBranch || false;
this.isOpen = data.state === 'opened' || data.state === 'reopened' || false;
this.isOpen = data.state === 'opened';
this.hasMergeableDiscussionsState = data.mergeable_discussions_state === false;
this.canRemoveSourceBranch = currentUser.can_remove_source_branch || false;
this.canMerge = !!data.merge_path;
......
......@@ -315,6 +315,10 @@ header {
}
}
.with-performance-bar header.navbar-gitlab {
top: $performance-bar-height;
}
.navbar-nav {
li {
.badge {
......
......@@ -120,3 +120,7 @@ of the body element here, we negate cascading side effects but allow momentum sc
.page-with-sidebar {
-webkit-overflow-scrolling: auto;
}
.with-performance-bar .page-with-sidebar {
margin-top: $header-height + $performance-bar-height;
}
......@@ -374,6 +374,10 @@
}
}
.with-performance-bar .layout-nav {
margin-top: $header-height + $performance-bar-height;
}
.scrolling-tabs-container {
position: relative;
......@@ -468,6 +472,22 @@
}
}
.with-performance-bar .page-with-layout-nav {
.right-sidebar {
top: ($header-height + 1) * 2 + $performance-bar-height;
}
&.page-with-sub-nav {
.right-sidebar {
top: ($header-height + 1) * 3 + $performance-bar-height;
&.affix {
top: $header-height + $performance-bar-height;
}
}
}
}
.nav-block {
&.activities {
border-bottom: 1px solid $border-color;
......
......@@ -89,6 +89,10 @@
}
}
.with-performance-bar .right-sidebar.affix {
top: $header-height + $performance-bar-height;
}
@mixin maintain-sidebar-dimensions {
display: block;
width: $gutter-width;
......
......@@ -205,6 +205,8 @@ $divergence-graph-separator-bg: #ccc;
$general-hover-transition-duration: 100ms;
$general-hover-transition-curve: linear;
$highlight-changes-color: rgb(235, 255, 232);
$performance-bar-height: 35px;
$issue-box-upcoming-bg: #8f8f8f;
$pages-group-name-color: #4c4e54;
$ldap-members-override-bg: $orange-50;
......
......@@ -118,7 +118,7 @@ $new-sidebar-width: 220px;
z-index: 400;
width: $new-sidebar-width;
transition: left $sidebar-transition-duration;
top: 50px;
top: $header-height;
bottom: 0;
left: 0;
overflow: auto;
......@@ -163,6 +163,10 @@ $new-sidebar-width: 220px;
}
}
.with-performance-bar .nav-sidebar {
top: $header-height + $performance-bar-height;
}
.sidebar-sub-level-items {
display: none;
padding-bottom: 8px;
......@@ -260,7 +264,7 @@ $new-sidebar-width: 220px;
// Make issue boards full-height now that sub-nav is gone
.boards-list {
height: calc(100vh - 50px);
height: calc(100vh - #{$header-height});
@media (min-width: $screen-sm-min) {
height: 475px; // Needed for PhantomJS
......@@ -270,6 +274,10 @@ $new-sidebar-width: 220px;
}
}
.with-performance-bar .boards-list {
height: calc(100vh - #{$header-height} - #{$performance-bar-height});
}
// Change color of all horizontal tabs to match the new indigo color
.nav-links li.active a {
......
......@@ -64,10 +64,10 @@
color: $gl-text-color;
position: sticky;
position: -webkit-sticky;
top: 50px;
top: $header-height;
&.affix {
top: 50px;
top: $header-height;
}
// with sidebar
......@@ -171,6 +171,16 @@
}
}
.with-performance-bar .build-page {
.top-bar {
top: $header-height + $performance-bar-height;
&.affix {
top: $header-height + $performance-bar-height;
}
}
}
.build-header {
.ci-header-container,
.header-action-buttons {
......
......@@ -445,6 +445,14 @@
}
}
.with-performance-bar .right-sidebar {
top: $header-height + $performance-bar-height;
.issuable-sidebar {
height: calc(100% - #{$header-height} - #{$performance-bar-height});
}
}
.detail-page-description {
padding: 16px 0;
......
......@@ -759,6 +759,10 @@
}
}
.with-performance-bar .merge-request-tabs-holder {
top: $header-height + $performance-bar-height;
}
.merge-request-tabs {
display: flex;
margin-bottom: 0;
......
......@@ -3,9 +3,16 @@
@import "peek/views/rblineprof";
#peek {
height: 35px;
position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 2000;
overflow-x: hidden;
height: $performance-bar-height;
background: $black;
line-height: 35px;
line-height: $performance-bar-height;
color: $perf-bar-text;
&.disabled {
......@@ -25,7 +32,8 @@
}
.wrapper {
width: 1000px;
width: 80%;
height: $performance-bar-height;
margin: 0 auto;
}
......
......@@ -2,6 +2,7 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController
before_action :group
before_action :require_ldap_enabled
before_action :authorize_admin_group!
before_action :authorize_manage_ldap_group_links!
layout 'group_settings'
......@@ -31,6 +32,12 @@ class Groups::LdapGroupLinksController < Groups::ApplicationController
private
def authorize_manage_ldap_group_links!
unless can?(current_user, :admin_ldap_group_links, group)
return render_404
end
end
def require_ldap_enabled
render_404 unless Gitlab.config.ldap.enabled
end
......
......@@ -86,7 +86,6 @@ class IssuableFinder
end
counts[:all] = counts.values.sum
counts[:opened] += counts[:reopened]
counts.with_indifferent_access
end
......
......@@ -268,7 +268,11 @@ module ApplicationHelper
end
def page_class
"issue-boards-page" if current_controller?(:boards)
class_names = []
class_names << 'issue-boards-page' if current_controller?(:boards)
class_names << 'with-performance-bar' if performance_bar_enabled?
class_names
end
# Returns active css class when condition returns true
......
......@@ -21,7 +21,8 @@ module EE
:slack_app_enabled,
:slack_app_id,
:slack_app_secret,
:slack_app_verification_token
:slack_app_verification_token,
:allow_group_owners_to_manage_ldap
]
end
......
......@@ -362,4 +362,14 @@ module IssuablesHelper
params[:format] = :json if issuable.is_a?(Issue)
end
end
def issuable_sidebar_options(issuable, can_edit_issuable)
{
endpoint: "#{issuable_json_path(issuable)}?basic=true",
editable: can_edit_issuable,
currentUser: current_user.as_json(only: [:username, :id, :name], methods: :avatar_url),
rootPath: root_path,
fullPath: @project.full_path
}
end
end
module MembersHelper
# Returns a `<action>_<source>_member` association, e.g.:
# - admin_project_member, update_project_member, destroy_project_member
# - admin_group_member, update_group_member, destroy_group_member
# - admin_group_member, update_group_member, destroy_group_member, override_group_member
def action_member_permission(action, member)
"#{action}_#{member.type.underscore}".to_sym
end
......
module NavHelper
def page_with_sidebar_class
class_name = page_gutter_class
class_name << 'page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar
class_name
end
def page_gutter_class
if current_path?('merge_requests#show') ||
current_path?('projects/merge_requests/conflicts#show') ||
current_path?('issues#show') ||
current_path?('milestones#show')
if cookies[:collapsed_gutter] == 'true'
"page-gutter right-sidebar-collapsed"
%w[page-gutter right-sidebar-collapsed]
else
"page-gutter right-sidebar-expanded"
%w[page-gutter right-sidebar-expanded]
end
elsif current_path?('jobs#show')
"page-gutter build-sidebar right-sidebar-expanded"
%w[page-gutter build-sidebar right-sidebar-expanded]
elsif current_path?('wikis#show') ||
current_path?('wikis#edit') ||
current_path?('wikis#update') ||
current_path?('wikis#history') ||
current_path?('wikis#git_access')
"page-gutter wiki-sidebar right-sidebar-expanded"
%w[page-gutter wiki-sidebar right-sidebar-expanded]
else
[]
end
end
def nav_header_class
class_name = ''
class_name << " with-horizontal-nav" if defined?(nav) && nav
class_names = []
class_names << 'with-horizontal-nav' if defined?(nav) && nav
class_name
class_names
end
def layout_nav_class
class_name = ''
class_name << " page-with-layout-nav" if defined?(nav) && nav
class_name << " page-with-sub-nav" if content_for?(:sub_nav)
return [] if show_new_nav?
class_name
class_names = []
class_names << 'page-with-layout-nav' if defined?(nav) && nav
class_names << 'page-with-sub-nav' if content_for?(:sub_nav)
class_names
end
def nav_control_class
......
......@@ -130,4 +130,14 @@ module NotesHelper
can?(current_user, :create_note, @project)
end
end
def initial_notes_data(autocomplete)
{
notesUrl: notes_url,
notesIds: @notes.map(&:id),
now: Time.now.to_i,
diffView: diff_view,
autocomplete: autocomplete
}
end
end
class Burndown
Issue = Struct.new(:closed_at, :weight, :state)
class Issue
attr_reader :closed_at, :weight, :state
def initialize(closed_at, weight, state)
@closed_at = closed_at
@weight = weight
@state = state
end
def reopened?
@state == 'opened' && @closed_at.present?
end
end
attr_reader :start_date, :due_date, :end_date, :issues_count, :issues_weight, :accurate, :legacy_data
alias_method :accurate?, :accurate
......@@ -12,8 +24,8 @@ class Burndown
@end_date = @milestone.due_date
@end_date = Date.today if @end_date.present? && @end_date > Date.today
@accurate = milestone_closed_issues.all?(&:closed_at)
@legacy_data = milestone_closed_issues.any? && milestone_closed_issues.none?(&:closed_at)
@accurate = milestone_issues.all?(&:closed_at)
@legacy_data = milestone_issues.any? && milestone_issues.none?(&:closed_at)
@issues_count, @issues_weight = milestone.issues.reorder(nil).pluck('COUNT(*), COALESCE(SUM(weight), 0)').first
end
......@@ -59,21 +71,21 @@ class Burndown
current_date = date.to_date
closed =
milestone_closed_issues.select do |issue|
milestone_issues.select do |issue|
(issue.closed_at&.to_date || start_date) == current_date
end
reopened = closed.select { |issue| issue.state == 'reopened' }
reopened = closed.select(&:reopened?)
[closed, reopened]
end
def milestone_closed_issues
@milestone_closed_issues ||=
def milestone_issues
@milestone_issues ||=
@milestone.issues
.where("state IN ('reopened', 'closed')")
.order("closed_at ASC")
.where("state = 'closed' OR (state = 'opened' AND closed_at IS NOT NULL)")
.reorder("closed_at ASC")
.pluck("closed_at, weight, state")
.map {|attrs| ::Burndown::Issue.new(*attrs) }
.map {|attrs| Issue.new(*attrs) }
end
end
......@@ -223,6 +223,7 @@ module Ci
variables += project.group.secret_variables_for(ref, project).map(&:to_runner_variable) if project.group
variables += secret_variables(environment: environment)
variables += trigger_request.user_variables if trigger_request
variables += pipeline.variables.map(&:to_runner_variable)
variables += pipeline.pipeline_schedule.job_variables if pipeline.pipeline_schedule
variables += persisted_environment_variables if environment
......
......@@ -27,6 +27,7 @@ module Ci
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
has_many :builds, foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
# Merge requests for which the current pipeline is running against
# the merge request's latest commit.
......
module Ci
class PipelineVariable < ActiveRecord::Base
extend Ci::Model
include HasVariable
belongs_to :pipeline
validates :key, uniqueness: { scope: :pipeline_id }
end
end
......@@ -71,9 +71,8 @@ module Issuable
scope :of_projects, ->(ids) { where(project_id: ids) }
scope :of_milestones, ->(ids) { where(milestone_id: ids) }
scope :with_milestone, ->(title) { left_joins_milestones.where(milestones: { title: title }) }
scope :opened, -> { with_state(:opened, :reopened) }
scope :opened, -> { with_state(:opened) }
scope :only_opened, -> { with_state(:opened) }
scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) }
scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') }
scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') }
......@@ -241,7 +240,7 @@ module Issuable
end
def open?
opened? || reopened?
opened?
end
def user_notes_count
......
......@@ -39,7 +39,8 @@ module EE
repository_size_limit: 0,
mirror_max_delay: Settings.gitlab['mirror_max_delay'],
mirror_max_capacity: Settings.gitlab['mirror_max_capacity'],
mirror_capacity_threshold: Settings.gitlab['mirror_capacity_threshold']
mirror_capacity_threshold: Settings.gitlab['mirror_capacity_threshold'],
allow_group_owners_to_manage_ldap: true
)
end
end
......
......@@ -73,15 +73,14 @@ class Issue < ActiveRecord::Base
state_machine :state, initial: :opened do
event :close do
transition [:reopened, :opened] => :closed
transition [:opened] => :closed
end
event :reopen do
transition closed: :reopened
transition closed: :opened
end
state :opened
state :reopened
state :closed
before_transition any => :closed do |issue|
......
......@@ -45,23 +45,23 @@ class MergeRequest < ActiveRecord::Base
state_machine :state, initial: :opened do
event :close do
transition [:reopened, :opened] => :closed
transition [:opened] => :closed
end
event :mark_as_merged do
transition [:reopened, :opened, :locked] => :merged
transition [:opened, :locked] => :merged
end
event :reopen do
transition closed: :reopened
transition closed: :opened
end
event :lock_mr do
transition [:reopened, :opened] => :locked
transition [:opened] => :locked
end
event :unlock_mr do
transition locked: :reopened
transition locked: :opened
end
after_transition any => :locked do |merge_request, transition|
......@@ -75,7 +75,6 @@ class MergeRequest < ActiveRecord::Base
end
state :opened
state :reopened
state :closed
state :merged
state :locked
......@@ -372,7 +371,7 @@ class MergeRequest < ActiveRecord::Base
errors.add :branch_conflict, "You can not use same project/branch for source and target"
end
if opened? || reopened?
if opened?
similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.try(:id)).opened
similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id
if similar_mrs.any?
......
......@@ -114,7 +114,7 @@ class DroneCiService < CiService
end
def merge_request_valid?(data)
%w(opened reopened).include?(data[:object_attributes][:state]) &&
data[:object_attributes][:state] == 'opened' &&
data[:object_attributes][:merge_status] == 'unchecked'
end
end
......@@ -6,19 +6,19 @@ module EE
with_scope :subject
condition(:ldap_synced) { @subject.ldap_synced? }
rule { ldap_synced }.prevent :admin_group_member
rule { ldap_synced & admin }.policy do
enable :override_group_member
enable :update_group_member
end
rule { ldap_synced & owner }.policy do
enable :override_group_member
enable :update_group_member
condition(:can_owners_manage_ldap, scope: :global) do
current_application_settings.allow_group_owners_to_manage_ldap
end
rule { auditor }.enable :read_group
rule { admin | (can_owners_manage_ldap & owner) }.enable :admin_ldap_group_links
rule { ldap_synced }.prevent :admin_group_member
rule { ldap_synced & (admin | owner) }.enable :update_group_member
rule { ldap_synced & (admin | (can_owners_manage_ldap & owner)) }.enable :override_group_member
end
end
end
......@@ -2,7 +2,7 @@ module Ci
class CreatePipelineService < BaseService
attr_reader :pipeline
def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, mirror_update: false, &block)
def execute(source, ignore_skip_ci: false, save_on_errors: true, trigger_request: nil, schedule: nil, mirror_update: false)
@pipeline = Ci::Pipeline.new(
source: source,
project: project,
......@@ -22,7 +22,27 @@ module Ci
return result if result
_create_pipeline(source, &block)
begin
Ci::Pipeline.transaction do
pipeline.save!
yield(pipeline) if block_given?
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
rescue ActiveRecord::RecordInvalid => e
return error("Failed to persist the pipeline: #{e}")
end
update_merge_requests_head_pipeline
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end
private
......@@ -69,24 +89,6 @@ module Ci
end
end
def _create_pipeline(source)
Ci::Pipeline.transaction do
update_merge_requests_head_pipeline if pipeline.save
yield(pipeline) if block_given?
Ci::CreatePipelineStagesService
.new(project, current_user)
.execute(pipeline)
end
cancel_pending_pipelines if project.auto_cancel_pending_pipelines?
pipeline_created_counter.increment(source: source)
pipeline.tap(&:process!)
end
def allowed_to_trigger_pipeline?(triggering_user)
if triggering_user
allowed_to_create?(triggering_user)
......
# This class is deprecated because we're closing Ci::TriggerRequest.
# New class is PipelineTriggerService (app/services/ci/pipeline_trigger_service.rb)
# which is integrated with Ci::PipelineVariable instaed of Ci::TriggerRequest.
# We remove this class after we removed v1 and v3 API. This class is still being
# referred by such legacy code.
module Ci
module CreateTriggerRequestService
Result = Struct.new(:trigger_request, :pipeline)
......
......@@ -14,9 +14,11 @@ module Ci
# this check is to not leak the presence of the project if user cannot read it
return unless trigger.project == project
trigger_request = trigger.trigger_requests.create(variables: params[:variables])
pipeline = Ci::CreatePipelineService.new(project, trigger.owner, ref: params[:ref])
.execute(:trigger, ignore_skip_ci: true, trigger_request: trigger_request)
.execute(:trigger, ignore_skip_ci: true) do |pipeline|
trigger.trigger_requests.create!(pipeline: pipeline)
create_pipeline_variables!(pipeline)
end
if pipeline.persisted?
success(pipeline: pipeline)
......@@ -47,17 +49,27 @@ module Ci
error(pipeline.errors.messages, 400)
end
end
def trigger_from_token
return @trigger if defined?(@trigger)
@trigger = Ci::Trigger.find_by_token(params[:token].to_s)
end
def job_from_token
return @job if defined?(@job)
@job = Ci::Build.find_by_token(params[:token].to_s)
end
def create_pipeline_variables!(pipeline)
return unless params[:variables]
variables = params[:variables].map do |key, value|
{ key: key, value: value }
end
pipeline.variables.create!(variables)
end
end
end
......@@ -5,7 +5,7 @@ module Issues
if issue.reopen
event_service.reopen_issue(issue, current_user)
create_note(issue)
create_note(issue, 'reopened')
notification_service.reopen_issue(issue, current_user)
execute_hooks(issue, 'reopen')
invalidate_cache_counts(issue, users: issue.assignees)
......@@ -16,8 +16,8 @@ module Issues
private
def create_note(issue)
SystemNoteService.change_status(issue, issue.project, current_user, issue.state, nil)
def create_note(issue, state = issue.state)
SystemNoteService.change_status(issue, issue.project, current_user, state, nil)
end
end
end
......@@ -2,8 +2,8 @@ module MergeRequests
class BaseService < ::IssuableBaseService
prepend EE::MergeRequests::BaseService
def create_note(merge_request)
SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, merge_request.state, nil)
def create_note(merge_request, state = merge_request.state)
SystemNoteService.change_status(merge_request, merge_request.target_project, current_user, state, nil)
end
def create_title_change_note(issuable, old_title)
......@@ -46,7 +46,7 @@ module MergeRequests
end
# Returns all origin and fork merge requests from `@project` satisfying passed arguments.
def merge_requests_for(source_branch, mr_states: [:opened, :reopened])
def merge_requests_for(source_branch, mr_states: [:opened])
MergeRequest
.with_state(mr_states)
.where(source_branch: source_branch, source_project_id: @project.id)
......
......@@ -82,7 +82,7 @@ module MergeRequests
# Note: Closed merge requests also need approvals reset.
def reset_approvals_for_merge_requests
merge_requests = merge_requests_for(@branch_name, mr_states: [:opened, :reopened, :closed])
merge_requests = merge_requests_for(@branch_name, mr_states: [:opened, :closed])
merge_requests.each do |merge_request|
target_project = merge_request.target_project
......
......@@ -5,7 +5,7 @@ module MergeRequests
if merge_request.reopen
event_service.reopen_mr(merge_request, current_user)
create_note(merge_request)
create_note(merge_request, 'reopened')
notification_service.reopen_mr(merge_request, current_user)
execute_hooks(merge_request, 'reopen')
merge_request.reload_diff(current_user)
......
......@@ -48,6 +48,17 @@
= select(:application_setting, :enabled_git_access_protocol, [['Both SSH and HTTP(S)', nil], ['Only SSH', 'ssh'], ['Only HTTP(S)', 'http']], {}, class: 'form-control')
%span.help-block#clone-protocol-help
Allow only the selected protocols to be used for Git access.
- if ldap_enabled?
.form-group
= f.label :allow_group_owners_to_manage_ldap, 'LDAP settings', class: 'control-label col-sm-2'
.col-sm-10
.checkbox
= f.label :allow_group_owners_to_manage_ldap do
= f.check_box :allow_group_owners_to_manage_ldap
Allow group owners to manage LDAP-related settings
%span.help-block
If checked, group owners can manage LDAP group links and LDAP member overrides
= link_to icon('question-circle'), help_page_path('administration/auth/ldap-ee')
%fieldset
%legend Account and Limit Settings
......
- if Gitlab::LDAP::Config.enabled_extras?
- if Gitlab::LDAP::Config.enabled_extras? && can?(current_user, :admin_ldap_group_links, @group)
= nav_link(path: 'ldap_group_links#index') do
= link_to group_ldap_group_links_path(@group), title: 'LDAP Group' do
%span
......
.page-with-sidebar{ class: "#{('page-with-new-sidebar' if defined?(@new_sidebar) && @new_sidebar)} #{page_gutter_class}" }
.page-with-sidebar{ class: page_with_sidebar_class }
- if show_new_nav?
- if defined?(nav) && nav
= render "layouts/nav/#{nav}"
......@@ -9,7 +9,7 @@
= render "layouts/nav/#{nav}"
- if content_for?(:sub_nav)
= yield :sub_nav
.content-wrapper{ class: "#{(layout_nav_class unless show_new_nav?)}" }
.content-wrapper{ class: layout_nav_class }
- if show_new_nav?
.mobile-overlay
.alert-wrapper
......
!!! 5
%html{ lang: I18n.locale, class: "#{page_class}" }
%html{ lang: I18n.locale, class: page_class }
= render "layouts/head"
%body{ class: @body_class, data: { page: body_data_page, project: "#{@project.path if @project}", group: "#{@group.path if @group}", find_file: find_file_path } }
= render "layouts/init_auto_complete" if @gfm_form
= render 'peek/bar'
- if show_new_nav?
= render "layouts/header/new"
- else
......@@ -10,5 +11,3 @@
= render 'layouts/page', sidebar: sidebar, nav: nav
= yield :scripts_body
= render 'peek/bar'
%span.current-host
= truncate(view.hostname)
......@@ -17,7 +17,11 @@
- if @remote_mirror.last_error.present?
.panel.panel-danger
.panel-heading
The remote repository failed to update #{time_ago_with_tooltip(@remote_mirror.last_update_at)}.
- if @remote_mirror.last_update_at
The remote repository failed to update #{time_ago_with_tooltip(@remote_mirror.last_update_at)}.
- else
The remote repository failed to update.
- if @remote_mirror.last_successful_update_at
Last successful update #{time_ago_with_tooltip(@remote_mirror.last_successful_update_at)}.
.panel-body
......
......@@ -4,6 +4,8 @@
- page_title 'New Project'
- header_title "Projects", dashboard_projects_path
- visibility_level = params.dig(:project, :visibility_level) || default_project_visibility
- content_for :page_specific_javascripts do
= webpack_bundle_tag 'project_new'
.project-edit-container
.project-edit-errors
......@@ -111,49 +113,3 @@
%i.fa.fa-spinner.fa-spin
Creating project &amp; repository.
%p Please wait a moment, this page will automatically refresh when ready.
:javascript
var importBtnTooltip = "Please enter a valid project name.";
var $importBtnWrapper = $('.import_gitlab_project');
$('.how_to_import_link').bind('click', function (e) {
e.preventDefault();
var import_modal = $(this).next(".modal").show();
});
$('.modal-header .close').bind('click', function() {
$(".modal").hide();
});
$('.btn_import_gitlab_project').bind('click', function() {
var _href = $("a.btn_import_gitlab_project").attr("href");
$(".btn_import_gitlab_project").attr("href", _href + '?namespace_id=' + $("#project_namespace_id").val() + '&path=' + $("#project_path").val());
});
$('.btn_import_gitlab_project').attr('disabled', $('#project_path').val().trim().length === 0);
$importBtnWrapper.attr('title', importBtnTooltip);
$('#new_project').submit(function(){
var $path = $('#project_path');
$path.val($path.val().trim());
});
$('#project_path').keyup(function(){
if($(this).val().trim().length !== 0) {
$('.btn_import_gitlab_project').attr('disabled', false);
$importBtnWrapper.attr('title','');
$importBtnWrapper.removeClass('has-tooltip');
} else {
$('.btn_import_gitlab_project').attr('disabled',true);
$importBtnWrapper.addClass('has-tooltip');
}
});
$('#project_import_url').disable();
$('.import_git').click(function( event ) {
$projectImportUrl = $('#project_import_url');
$projectMirror = $('#project_mirror');
$projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'));
$projectMirror.attr('disabled', !$projectMirror.attr('disabled'));
});
- content_for :page_specific_javascripts do
= webpack_bundle_tag('pipelines_times')
%div
%p.light
= _("Commit duration in minutes for last 30 commits")
%canvas#build_timesChart{ height: 200 }
:javascript
var data = {
labels : #{@charts[:pipeline_times].labels.to_json},
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
barStrokeWidth: 1,
barValueSpacing: 1,
barDatasetSpacing: 1,
data : #{@charts[:pipeline_times].pipeline_times.to_json}
}
]
}
var ctx = $("#build_timesChart").get(0).getContext("2d");
var options = { scaleOverlay: true, responsive: true, maintainAspectRatio: false };
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8
}
new Chart(ctx).Bar(data, options);
%script#pipelinesTimesChartsData{ type: "application/json" }= { :labels => @charts[:pipeline_times].labels, :values => @charts[:pipeline_times].pipeline_times }.to_json.html_safe
- content_for :page_specific_javascripts do
= webpack_bundle_tag('pipelines_charts')
%h4= _("Pipelines charts")
%p
&nbsp;
......@@ -26,31 +29,8 @@
= _("Jobs for last year")
%canvas#yearChart.padded{ height: 250 }
- [:week, :month, :year].each do |scope|
:javascript
var data = {
labels : #{@charts[scope].labels.to_json},
datasets : [
{
fillColor : "#7f8fa4",
strokeColor : "#7f8fa4",
pointColor : "#7f8fa4",
pointStrokeColor : "#EEE",
data : #{@charts[scope].total.to_json}
},
{
fillColor : "#44aa22",
strokeColor : "#44aa22",
pointColor : "#44aa22",
pointStrokeColor : "#fff",
data : #{@charts[scope].success.to_json}
}
]
}
var ctx = $("##{scope}Chart").get(0).getContext("2d");
var options = { scaleOverlay: true, responsive: true, maintainAspectRatio: false };
if (window.innerWidth < 768) {
// Scale fonts if window width lower than 768px (iPad portrait)
options.scaleFontSize = 8
}
new Chart(ctx).Line(data, options);
%script#pipelinesChartsData{ type: "application/json" }
- chartData = []
- [:week, :month, :year].each do |scope|
- chartData.push({ 'scope' => scope, 'labels' => @charts[scope].labels, 'totalValues' => @charts[scope].total, 'successValues' => @charts[scope].success })
= chartData.to_json.html_safe
......@@ -20,7 +20,4 @@
= f.submit 'Create pipeline', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_pipelines_path(@project), class: 'btn btn-cancel'
:javascript
var availableRefs = #{@project.repository.ref_names.to_json};
new NewBranchForm($('.js-new-pipeline-form'), availableRefs)
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
......@@ -40,7 +40,4 @@
.form-actions
= button_tag 'Create tag', class: 'btn btn-create', tabindex: 3
= link_to 'Cancel', project_tags_path(@project), class: 'btn btn-cancel'
:javascript
window.gl = window.gl || { };
window.gl.availableRefs = #{@project.repository.ref_names.to_json};
%script#availableRefs{ type: "application/json" }= @project.repository.ref_names.to_json.html_safe
.tree-content-holder
.tree-content-holder.js-tree-content{ 'data-logs-path': @logs_path, 'data-path-locks-available': (@project.feature_available?(:file_locks) ? 'true' : 'false'), 'data-path-locks-toggle': toggle_project_path_locks_path(@project), 'data-path-locks-path': @path }
.table-holder
%table.table#tree-slider{ class: "table_#{@hex_path} tree-table" }
%thead
......@@ -22,17 +22,3 @@
- if can_edit_tree?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, @id), method: :post
= render 'projects/blob/new_dir'
- if @project.feature_available?(:file_locks)
:javascript
PathLocks.init(
'#{toggle_project_path_locks_path(@project)}',
'#{@path}'
);
:javascript
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
gl.utils.ajaxGet("#{escape_javascript(@logs_path)}");
});
......@@ -19,6 +19,3 @@
More Pages
= render 'projects/wikis/new'
:javascript
new Sidebar();
......@@ -26,23 +26,4 @@
= geo_button(modal_target: '#modal-geo-info') if Gitlab::Geo.secondary?
:javascript
$('ul.clone-options-dropdown a').on('click',function(e){
e.preventDefault();
var $this = $(this);
$('a.clone-dropdown-btn span').text($this.text());
$('#project_clone').val($this.attr('href'));
});
// Change URLs in Geo Clone Dialog information text
$('ul.clone-options-dropdown a').on('click',function(e){
e.preventDefault();
var $this = $(this);
$('#modal-geo-info').data({
cloneUrlSecondary: $this.attr('href'),
cloneUrlPrimary: $this.data('primaryUrl') || ''
});
});
= render 'shared/geo_info_modal', project: project if Gitlab::Geo.secondary?
......@@ -76,11 +76,3 @@
= link_to destroy_label_path(label), title: "Delete", class: 'btn btn-transparent btn-action remove-row', method: :delete, data: {confirm: label_deletion_confirm_text(label), toggle: "tooltip"} do
%span.sr-only Delete
= icon('trash-o')
- if current_user
- if can_subscribe_to_label_in_different_levels?(label)
:javascript
new gl.GroupLabelSubscription('##{dom_id(label)} .label-subscription');
- else
:javascript
new gl.ProjectLabelSubscription('##{dom_id(label)} .label-subscription');
......@@ -23,18 +23,3 @@
.prepend-top-default
= f.submit "Create #{type} token", class: "btn btn-create"
:javascript
var $dateField = $('.datepicker');
var date = $dateField.val();
new Pikaday({
field: $dateField.get(0),
theme: 'gitlab-theme animate-picker',
format: 'yyyy-mm-dd',
minDate: new Date(),
container: $dateField.parent().get(0),
onSelect: function(dateText) {
$dateField.val(dateFormat(new Date(dateText), 'yyyy-mm-dd'));
}
});
......@@ -37,14 +37,3 @@
.row-content-block.second-block.filtered-labels{ class: ("hidden" unless has_labels) }
- if has_labels
= render 'shared/labels_row', labels: @labels
:javascript
new LabelsSelect();
new MilestoneSelect();
new IssueStatusSelect();
new WeightSelect();
new SubscriptionSelect();
$('form.filter-form').on('submit', function (event) {
event.preventDefault();
gl.utils.visitUrl(this.action + '&' + $(this).serialize());
});
......@@ -16,5 +16,3 @@
.hide-collapsed.participants-more
%a.js-participants-more{ href: "#", data: { original_text: "+ #{participants_size - 7} more", less_text: "- show less" } }
+ #{participants_extra} more
:javascript
IssuableContext.prototype.PARTICIPANTS_ROW_COUNT = #{participants_row};
......@@ -128,12 +128,3 @@
#js-add-issues-btn.prepend-left-10
- elsif type != :boards_modal
= render 'shared/sort_dropdown'
- unless type === :boards_modal
:javascript
$(document).off('page:restore').on('page:restore', function (event) {
if (gl.FilteredSearchManager) {
const filteredSearchManager = new gl.FilteredSearchManager();
filteredSearchManager.setup();
}
});
......@@ -165,18 +165,4 @@
= project_ref
= clipboard_button(text: project_ref, title: "Copy reference to clipboard", placement: "left")
:javascript
gl.sidebarOptions = {
endpoint: "#{issuable_json_path(issuable)}?basic=true",
editable: #{can_edit_issuable ? true : false},
currentUser: #{current_user.to_json(only: [:username, :id, :name], methods: :avatar_url)},
rootPath: "#{root_path}"
};
new MilestoneSelect('{"full_path":"#{@project.full_path}"}');
new LabelsSelect();
new WeightSelect();
new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}');
gl.Subscription.bindAll('.subscription');
new gl.DueDateSelectors();
window.sidebar = new Sidebar();
%script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable, can_edit_issuable).to_json.html_safe
......@@ -22,5 +22,4 @@
= link_to "sign in", new_session_path(:user, redirect_to_referer: 'yes')
to comment
:javascript
var notes = new Notes("#{notes_url}", #{@notes.map(&:id).to_json}, #{Time.now.to_i}, "#{diff_view}", #{autocomplete})
%script.js-notes-data{ type: "application/json" }= initial_notes_data(autocomplete).to_json.html_safe
- remote = local_assigns.fetch(:remote, false)
- link_project = local_assigns.fetch(:link_project, false)
.snippets-list-holder
......@@ -8,7 +7,4 @@
%li
.nothing-here-block Nothing here.
= paginate @snippets, theme: 'gitlab', remote: remote
:javascript
gl.SnippetsList();
= paginate @snippets, theme: 'gitlab'
---
title: Fix CSS for mini graph with downstream pipeline
merge_request:
author:
---
title: Add admin application setting to allow group owners to manage LDAP.
merge_request: 2529
author:
---
title: Adds lower bound to pull mirror scheduling feature
merge_request: 2366
author:
---
title: Renamed board to boards in new project sidebar
merge_request:
author:
---
title: Add warning and option toggle when rebuilding authorized_keys.
merge_request: 2508
author:
---
title: Fixed issue boards focus mode when new navigation is turned on
merge_request:
author:
---
title: Fix vertical alignment in firefox and safari for pipeline mini graph
merge_request:
author:
---
title: Fix crash on /help/ui
merge_request:
author:
---
title: Pending delete projects should not show in deploy keys.
merge_request: 13088
author:
---
title: Fixes 500 error caused by pending delete projects in admin dashboard
merge_request: 13067
author:
---
title: Allow admin to read_users_list even if it's restricted
merge_request: 13066
author:
---
title: Add instrumentation to MarkupHelper#link_to_gfm
merge_request: 13069
author:
---
title: Fix job merge request link to a forked source project
merge_request: 12965
author:
---
title: Fix Rebasing not working with Merge Requests
title: Merge issuable "reopened" state into "opened"
merge_request:
author:
---
title: Fix sizing of custom header logo in new navigation
merge_request:
author:
......@@ -57,8 +57,11 @@ var config = {
notebook_viewer: './blob/notebook_viewer.js',
pdf_viewer: './blob/pdf_viewer.js',
pipelines: './pipelines/pipelines_bundle.js',
pipelines_details: './pipelines/pipeline_details_bundle.js',
pipelines_charts: './pipelines/pipelines_charts.js',
pipelines_details: './pipelines/pipeline_details_bundle.js',
pipelines_times: './pipelines/pipelines_times.js',
profile: './profile/profile_bundle.js',
project_new: './projects/project_new.js',
prometheus_metrics: './prometheus_metrics',
protected_branches: './protected_branches',
ee_protected_branches: './protected_branches/ee',
......
class CreateCiPipelineVariables < ActiveRecord::Migration
DOWNTIME = false
def up
create_table :ci_pipeline_variables do |t|
t.string :key, null: false
t.text :value
t.text :encrypted_value
t.string :encrypted_value_salt
t.string :encrypted_value_iv
t.integer :pipeline_id, null: false
end
add_index :ci_pipeline_variables, [:pipeline_id, :key], unique: true
end
def down
drop_table :ci_pipeline_variables
end
end
class AddForeignKeyToCiPipelineVariables < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_foreign_key(:ci_pipeline_variables, :ci_pipelines, column: :pipeline_id)
end
def down
remove_foreign_key(:ci_pipeline_variables, column: :pipeline_id)
end
end
class AddRestrictGroupOwnersToAdminsOptionToApplicationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default(:application_settings, :allow_group_owners_to_manage_ldap, :boolean, default: true)
end
def down
remove_column(:application_settings, :allow_group_owners_to_manage_ldap)
end
end
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class MergeIssuableReopenedIntoOpenedState < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
class Issue < ActiveRecord::Base
self.table_name = 'issues'
include EachBatch
end
class MergeRequest < ActiveRecord::Base
self.table_name = 'merge_requests'
include EachBatch
end
def up
[Issue, MergeRequest].each do |model|
say "Changing #{model.table_name}.state from 'reopened' to 'opened'"
model.where(state: 'reopened').each_batch do |batch|
batch.update_all(state: 'opened')
end
end
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170725145659) do
ActiveRecord::Schema.define(version: 20170726111039) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -149,6 +149,7 @@ ActiveRecord::Schema.define(version: 20170725145659) do
t.string "slack_app_verification_token"
t.integer "performance_bar_allowed_group_id"
t.boolean "password_authentication_enabled"
t.boolean "allow_group_owners_to_manage_ldap", default: true, null: false
end
create_table "approvals", force: :cascade do |t|
......@@ -356,6 +357,17 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_index "ci_pipeline_schedules", ["next_run_at", "active"], name: "index_ci_pipeline_schedules_on_next_run_at_and_active", using: :btree
add_index "ci_pipeline_schedules", ["project_id"], name: "index_ci_pipeline_schedules_on_project_id", using: :btree
create_table "ci_pipeline_variables", force: :cascade do |t|
t.string "key", null: false
t.text "value"
t.text "encrypted_value"
t.string "encrypted_value_salt"
t.string "encrypted_value_iv"
t.integer "pipeline_id", null: false
end
add_index "ci_pipeline_variables", ["pipeline_id", "key"], name: "index_ci_pipeline_variables_on_pipeline_id_and_key", unique: true, using: :btree
create_table "ci_pipelines", force: :cascade do |t|
t.string "ref"
t.string "sha"
......@@ -1937,6 +1949,7 @@ ActiveRecord::Schema.define(version: 20170725145659) do
add_foreign_key "ci_group_variables", "namespaces", column: "group_id", name: "fk_33ae4d58d8", on_delete: :cascade
add_foreign_key "ci_pipeline_schedules", "projects", name: "fk_8ead60fcc4", on_delete: :cascade
add_foreign_key "ci_pipeline_schedules", "users", column: "owner_id", name: "fk_9ea99f58d2", on_delete: :nullify
add_foreign_key "ci_pipeline_variables", "ci_pipelines", column: "pipeline_id", name: "fk_f29c5f4380", on_delete: :cascade
add_foreign_key "ci_pipelines", "ci_pipeline_schedules", column: "pipeline_schedule_id", name: "fk_3d34ab2e06", on_delete: :nullify
add_foreign_key "ci_pipelines", "ci_pipelines", column: "auto_canceled_by_id", name: "fk_262d4c2d19", on_delete: :nullify
add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
......
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