Merge remote-tracking branch 'origin/master' into 2979-personal-access-tokens
This commit is contained in:
commit
d0bcba1105
|
@ -0,0 +1,3 @@
|
|||
We’re closing our issue tracker on GitHub so we can focus on the GitLab.com project and respond to issues more quickly.
|
||||
|
||||
We encourage you to open an issue on the [GitLab.com issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues). You can log into GitLab.com using your GitHub account.
|
|
@ -0,0 +1,3 @@
|
|||
Thank you for taking the time to contribute back to GitLab!
|
||||
|
||||
Please open a merge request [on GitLab.com](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests), we look forward to reviewing your contribution! You can log into GitLab.com using your GitHub account.
|
|
@ -7,7 +7,8 @@ services:
|
|||
cache:
|
||||
key: "ruby21"
|
||||
paths:
|
||||
- vendor
|
||||
- vendor/apt
|
||||
- vendor/ruby
|
||||
|
||||
variables:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: "1"
|
||||
|
|
|
@ -13,7 +13,8 @@ AllCops:
|
|||
# Exclude some GitLab files
|
||||
Exclude:
|
||||
- 'vendor/**/*'
|
||||
- 'db/**/*'
|
||||
- 'db/*'
|
||||
- 'db/fixtures/**/*'
|
||||
- 'tmp/**/*'
|
||||
- 'bin/**/*'
|
||||
- 'lib/backup/**/*'
|
||||
|
@ -348,7 +349,7 @@ Style/MultilineArrayBraceLayout:
|
|||
|
||||
# Avoid multi-line chains of blocks.
|
||||
Style/MultilineBlockChain:
|
||||
Enabled: false
|
||||
Enabled: true
|
||||
|
||||
# Ensures newlines after multiline block do statements.
|
||||
Style/MultilineBlockLayout:
|
||||
|
|
14
CHANGELOG
14
CHANGELOG
|
@ -1,16 +1,20 @@
|
|||
Please view this file on the master branch, on stable branches it's out of date.
|
||||
|
||||
v 8.9.0 (unreleased)
|
||||
- Fix Error 500 when using closes_issues API with an external issue tracker
|
||||
- Bulk assign/unassign labels to issues.
|
||||
- Ability to prioritize labels !4009 / !3205 (Thijs Wouters)
|
||||
- Fix endless redirections when accessing user OAuth applications when they are disabled
|
||||
- Allow enabling wiki page events from Webhook management UI
|
||||
- Bump rouge to 1.11.0
|
||||
- Fix issue with arrow keys not working in search autocomplete dropdown
|
||||
- Make EmailsOnPushWorker use Sidekiq mailers queue
|
||||
- Fix wiki page events' webhook to point to the wiki repository
|
||||
- Don't show tags for revert and cherry-pick operations
|
||||
- Fix issue todo not remove when leave project !4150 (Long Nguyen)
|
||||
- Allow customisable text on the 'nearly there' page after a user signs up
|
||||
- Bump recaptcha gem to 3.0.0 to remove deprecated stoken support
|
||||
- Fix SVG sanitizer to allow more elements
|
||||
- Allow forking projects with restricted visibility level
|
||||
- Added descriptions to notification settings dropdown
|
||||
- Improve note validation to prevent errors when creating invalid note via API
|
||||
|
@ -31,7 +35,9 @@ v 8.9.0 (unreleased)
|
|||
- Add rake task 'gitlab:db:configure' for conditionally seeding or migrating the database
|
||||
- Changed the Slack build message to use the singular duration if necessary (Aran Koning)
|
||||
- Links from a wiki page to other wiki pages should be rewritten as expected
|
||||
- Add option to project to only allow merge requests to be merged if the build succeeds (Rui Santos)
|
||||
- Fix issues filter when ordering by milestone
|
||||
- Added artifacts:when to .gitlab-ci.yml - this requires GitLab Runner 1.3
|
||||
- Todos will display target state if issuable target is 'Closed' or 'Merged'
|
||||
- Fix bug when sorting issues by milestone due date and filtering by two or more labels
|
||||
- Add support for using Yubikeys (U2F) for two-factor authentication
|
||||
|
@ -54,7 +60,9 @@ v 8.9.0 (unreleased)
|
|||
- Improve error handling importing projects
|
||||
- Remove duplicated notification settings
|
||||
- Put project Files and Commits tabs under Code tab
|
||||
- Decouple global notification level from user model
|
||||
- Replace Colorize with Rainbow for coloring console output in Rake tasks.
|
||||
- Add workhorse controller and API helpers
|
||||
- An indicator is now displayed at the top of the comment field for confidential issues.
|
||||
- RepositoryCheck::SingleRepositoryWorker public and private methods are now instrumented
|
||||
- Improve issuables APIs performance when accessing notes !4471
|
||||
|
@ -62,15 +70,19 @@ v 8.9.0 (unreleased)
|
|||
- Markdown editor now correctly resets the input value on edit cancellation !4175
|
||||
- Toggling a task list item in a issue/mr description does not creates a Todo for mentions
|
||||
- Improved UX of date pickers on issue & milestone forms
|
||||
- Cache on the database if a project has an active external issue tracker.
|
||||
- Put project Labels and Milestones pages links under Issues and Merge Requests tabs as subnav
|
||||
- All classes in the Banzai::ReferenceParser namespace are now instrumented
|
||||
- Remove deprecated issues_tracker and issues_tracker_id from project model
|
||||
|
||||
v 8.8.5 (unreleased)
|
||||
- Ensure branch cleanup regardless of whether the GitHub import process succeeds
|
||||
- Fix issue with arrow keys not working in search autocomplete dropdown
|
||||
- Fix todos page throwing errors when you have a project pending deletion
|
||||
- Reduce number of SQL queries when rendering user references
|
||||
- Import GitHub repositories respecting the API rate limit
|
||||
- Fix importer for GitHub comments on diff
|
||||
- Disable Webhooks before proceeding with the GitHub import
|
||||
- Fix incremental trace upload API when using multi-byte UTF-8 chars in trace
|
||||
|
||||
v 8.8.4
|
||||
- Fix LDAP-based login for users with 2FA enabled. !4493
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -245,7 +245,7 @@ end
|
|||
|
||||
group :development do
|
||||
gem "foreman"
|
||||
gem 'brakeman', '~> 3.2.0', require: false
|
||||
gem 'brakeman', '~> 3.3.0', require: false
|
||||
|
||||
gem 'letter_opener_web', '~> 1.3.0'
|
||||
gem 'quiet_assets', '~> 1.0.2'
|
||||
|
|
28
Gemfile.lock
28
Gemfile.lock
|
@ -97,16 +97,7 @@ GEM
|
|||
bootstrap-sass (3.3.6)
|
||||
autoprefixer-rails (>= 5.2.1)
|
||||
sass (>= 3.3.4)
|
||||
brakeman (3.2.1)
|
||||
erubis (~> 2.6)
|
||||
haml (>= 3.0, < 5.0)
|
||||
highline (>= 1.6.20, < 2.0)
|
||||
ruby2ruby (~> 2.3.0)
|
||||
ruby_parser (~> 3.8.1)
|
||||
safe_yaml (>= 1.0)
|
||||
sass (~> 3.0)
|
||||
slim (>= 1.3.6, < 4.0)
|
||||
terminal-table (~> 1.4)
|
||||
brakeman (3.3.2)
|
||||
browser (2.0.3)
|
||||
builder (3.2.2)
|
||||
bullet (5.0.0)
|
||||
|
@ -338,7 +329,6 @@ GEM
|
|||
hashie (3.4.3)
|
||||
health_check (1.5.1)
|
||||
rails (>= 2.3.0)
|
||||
highline (1.7.8)
|
||||
hipchat (1.5.2)
|
||||
httparty
|
||||
mimemagic
|
||||
|
@ -642,10 +632,7 @@ GEM
|
|||
ruby-saml (1.1.2)
|
||||
nokogiri (>= 1.5.10)
|
||||
uuid (~> 2.3)
|
||||
ruby2ruby (2.3.0)
|
||||
ruby_parser (~> 3.1)
|
||||
sexp_processor (~> 4.0)
|
||||
ruby_parser (3.8.1)
|
||||
ruby_parser (3.8.2)
|
||||
sexp_processor (~> 4.1)
|
||||
rubyntlm (0.5.2)
|
||||
rubypants (0.2.0)
|
||||
|
@ -655,7 +642,7 @@ GEM
|
|||
safe_yaml (1.0.4)
|
||||
sanitize (2.1.0)
|
||||
nokogiri (>= 1.4.4)
|
||||
sass (3.4.21)
|
||||
sass (3.4.22)
|
||||
sass-rails (5.0.4)
|
||||
railties (>= 4.0.0, < 5.0)
|
||||
sass (~> 3.1)
|
||||
|
@ -704,9 +691,6 @@ GEM
|
|||
tilt (>= 1.3, < 3)
|
||||
six (0.2.0)
|
||||
slack-notifier (1.2.1)
|
||||
slim (3.0.6)
|
||||
temple (~> 0.7.3)
|
||||
tilt (>= 1.3.3, < 2.1)
|
||||
slop (3.6.0)
|
||||
spinach (0.8.10)
|
||||
colorize
|
||||
|
@ -747,10 +731,8 @@ GEM
|
|||
railties (>= 3.2.5, < 6)
|
||||
teaspoon-jasmine (2.2.0)
|
||||
teaspoon (>= 1.0.0)
|
||||
temple (0.7.6)
|
||||
term-ansicolor (1.3.2)
|
||||
tins (~> 1.0)
|
||||
terminal-table (1.5.2)
|
||||
test_after_commit (0.4.2)
|
||||
activerecord (>= 3.2)
|
||||
thin (1.6.4)
|
||||
|
@ -759,7 +741,7 @@ GEM
|
|||
rack (~> 1.0)
|
||||
thor (0.19.1)
|
||||
thread_safe (0.3.5)
|
||||
tilt (2.0.2)
|
||||
tilt (2.0.5)
|
||||
timecop (0.8.1)
|
||||
timfel-krb5-auth (0.8.3)
|
||||
tinder (1.10.1)
|
||||
|
@ -848,7 +830,7 @@ DEPENDENCIES
|
|||
better_errors (~> 1.0.1)
|
||||
binding_of_caller (~> 0.7.2)
|
||||
bootstrap-sass (~> 3.3.0)
|
||||
brakeman (~> 3.2.0)
|
||||
brakeman (~> 3.3.0)
|
||||
browser (~> 2.0.3)
|
||||
bullet
|
||||
bundler-audit
|
||||
|
|
|
@ -162,19 +162,6 @@ $ ->
|
|||
$el.data('placement') || 'bottom'
|
||||
)
|
||||
|
||||
$('.header-logo .home').tooltip(
|
||||
placement: (_, el) ->
|
||||
$el = $(el)
|
||||
if $('.page-with-sidebar').hasClass('page-sidebar-collapsed') then 'right' else 'bottom'
|
||||
container: 'body'
|
||||
)
|
||||
|
||||
$('.page-with-sidebar').tooltip(
|
||||
selector: '.sidebar-collapsed .nav-sidebar a, .sidebar-collapsed a.sidebar-user'
|
||||
placement: 'right'
|
||||
container: 'body'
|
||||
)
|
||||
|
||||
# Form submitter
|
||||
$('.trigger-submit').on 'change', ->
|
||||
$(@).parents('form').submit()
|
||||
|
@ -207,6 +194,7 @@ $ ->
|
|||
|
||||
$('.navbar-toggle').on 'click', ->
|
||||
$('.header-content .title').toggle()
|
||||
$('.header-content .header-logo').toggle()
|
||||
$('.header-content .navbar-collapse').toggle()
|
||||
$('.navbar-toggle').toggleClass('active')
|
||||
$('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left")
|
||||
|
@ -241,7 +229,6 @@ $ ->
|
|||
$this.attr 'value', $this.val()
|
||||
|
||||
$sidebarGutterToggle = $('.js-sidebar-toggle')
|
||||
$navIconToggle = $('.toggle-nav-collapse')
|
||||
|
||||
$(document)
|
||||
.off 'breakpoint:change'
|
||||
|
@ -251,10 +238,6 @@ $ ->
|
|||
if $gutterIcon.hasClass('fa-angle-double-right')
|
||||
$sidebarGutterToggle.trigger('click')
|
||||
|
||||
$navIcon = $navIconToggle.find('.fa')
|
||||
if $navIcon.hasClass('fa-angle-left')
|
||||
$navIconToggle.trigger('click')
|
||||
|
||||
fitSidebarForSize = ->
|
||||
oldBootstrapBreakpoint = bootstrapBreakpoint
|
||||
bootstrapBreakpoint = bp.getBreakpointSize()
|
||||
|
@ -267,8 +250,8 @@ $ ->
|
|||
$(document).trigger('breakpoint:change', [bootstrapBreakpoint])
|
||||
|
||||
$(window)
|
||||
.off "resize"
|
||||
.on "resize", (e) ->
|
||||
.off "resize.app"
|
||||
.on "resize.app", (e) ->
|
||||
fitSidebarForSize()
|
||||
|
||||
gl.awardsHandler = new AwardsHandler()
|
||||
|
|
|
@ -1,19 +1,31 @@
|
|||
class CiBuild
|
||||
class @CiBuild
|
||||
@interval: null
|
||||
@state: null
|
||||
|
||||
constructor: (build_url, build_status, build_state) ->
|
||||
constructor: (@build_url, @build_status, @state) ->
|
||||
clearInterval(CiBuild.interval)
|
||||
|
||||
@state = build_state
|
||||
# Init breakpoint checker
|
||||
@bp = Breakpoints.get()
|
||||
@hideSidebar()
|
||||
$('.js-build-sidebar').niceScroll()
|
||||
$(document)
|
||||
.off 'click', '.js-sidebar-build-toggle'
|
||||
.on 'click', '.js-sidebar-build-toggle', @toggleSidebar
|
||||
|
||||
@initScrollButtonAffix()
|
||||
$(window)
|
||||
.off 'resize.build'
|
||||
.on 'resize.build', @hideSidebar
|
||||
|
||||
if build_status == "running" || build_status == "pending"
|
||||
if $('#build-trace').length
|
||||
@getInitialBuildTrace()
|
||||
@initScrollButtonAffix()
|
||||
|
||||
if @build_status is "running" or @build_status is "pending"
|
||||
#
|
||||
# Bind autoscroll button to follow build output
|
||||
#
|
||||
$("#autoscroll-button").bind "click", ->
|
||||
$('#autoscroll-button').on 'click', ->
|
||||
state = $(this).data("state")
|
||||
if "enabled" is state
|
||||
$(this).data "state", "disabled"
|
||||
|
@ -27,26 +39,37 @@ class CiBuild
|
|||
# Only valid for runnig build when output changes during time
|
||||
#
|
||||
CiBuild.interval = setInterval =>
|
||||
if window.location.href.split("#").first() is build_url
|
||||
last_state = @state
|
||||
$.ajax
|
||||
url: build_url + "/trace.json?state=" + encodeURIComponent(@state)
|
||||
dataType: "json"
|
||||
success: (log) =>
|
||||
return unless last_state is @state
|
||||
|
||||
if log.state and log.status is "running"
|
||||
@state = log.state
|
||||
if log.append
|
||||
$('.fa-refresh').before log.html
|
||||
else
|
||||
$('#build-trace code').html log.html
|
||||
$('#build-trace code').append '<i class="fa fa-refresh fa-spin"/>'
|
||||
@checkAutoscroll()
|
||||
else if log.status isnt build_status
|
||||
Turbolinks.visit build_url
|
||||
if window.location.href.split("#").first() is @build_url
|
||||
@getBuildTrace()
|
||||
, 4000
|
||||
|
||||
getInitialBuildTrace: ->
|
||||
$.ajax
|
||||
url: @build_url
|
||||
dataType: 'json'
|
||||
success: (build_data) ->
|
||||
$('.js-build-output').html build_data.trace_html
|
||||
|
||||
if build_data.status is 'success' or build_data.status is 'failed'
|
||||
$('.js-build-refresh').remove()
|
||||
|
||||
getBuildTrace: ->
|
||||
$.ajax
|
||||
url: "#{@build_url}/trace.json?state=#{encodeURIComponent(@state)}"
|
||||
dataType: "json"
|
||||
success: (log) =>
|
||||
if log.state
|
||||
@state = log.state
|
||||
|
||||
if log.status is "running"
|
||||
if log.append
|
||||
$('.js-build-output').append log.html
|
||||
else
|
||||
$('.js-build-output').html log.html
|
||||
@checkAutoscroll()
|
||||
else if log.status isnt @build_status
|
||||
Turbolinks.visit @build_url
|
||||
|
||||
checkAutoscroll: ->
|
||||
$("html,body").scrollTop $("#build-trace").height() if "enabled" is $("#autoscroll-button").data("state")
|
||||
|
||||
|
@ -61,4 +84,22 @@ class CiBuild
|
|||
$body.outerHeight() - ($buildTrace.outerHeight() + $buildTrace.offset().top)
|
||||
)
|
||||
|
||||
@CiBuild = CiBuild
|
||||
shouldHideSidebar: ->
|
||||
bootstrapBreakpoint = @bp.getBreakpointSize()
|
||||
|
||||
bootstrapBreakpoint is 'xs' or bootstrapBreakpoint is 'sm'
|
||||
|
||||
toggleSidebar: =>
|
||||
if @shouldHideSidebar()
|
||||
$('.js-build-sidebar')
|
||||
.toggleClass 'right-sidebar-expanded right-sidebar-collapsed'
|
||||
|
||||
hideSidebar: =>
|
||||
if @shouldHideSidebar()
|
||||
$('.js-build-sidebar')
|
||||
.removeClass 'right-sidebar-expanded'
|
||||
.addClass 'right-sidebar-collapsed'
|
||||
else
|
||||
$('.js-build-sidebar')
|
||||
.removeClass 'right-sidebar-collapsed'
|
||||
.addClass 'right-sidebar-expanded'
|
||||
|
|
|
@ -97,13 +97,22 @@ class @IssuableBulkActions
|
|||
$labels = @form.find('.labels-filter input[name="update[label_ids][]"]')
|
||||
|
||||
$labels.each (k, label) ->
|
||||
labelIds.push $(label).val() if label
|
||||
labelIds.push parseInt($(label).val()) if label
|
||||
|
||||
labelIds
|
||||
|
||||
###*
|
||||
* Just an alias of @getUnmarkedIndeterminedLabels
|
||||
* @return {Array} Array of labels
|
||||
* Returns Label IDs that will be removed from issue selection
|
||||
* @return {Array} Array of labels IDs
|
||||
###
|
||||
getLabelsToRemove: ->
|
||||
@getUnmarkedIndeterminedLabels()
|
||||
result = []
|
||||
indeterminatedLabels = @getUnmarkedIndeterminedLabels()
|
||||
labelsToApply = @getLabelsToApply()
|
||||
|
||||
indeterminatedLabels.map (id) ->
|
||||
# We need to exclude label IDs that will be applied
|
||||
# By not doing this will cause issues from selection to not add labels at all
|
||||
result.push(id) if labelsToApply.indexOf(id) is -1
|
||||
|
||||
result
|
||||
|
|
|
@ -95,8 +95,11 @@ class @LabelsSelect
|
|||
$newLabelCreateButton.enable()
|
||||
|
||||
if label.message?
|
||||
errors = _.map label.message, (value, key) ->
|
||||
"#{key} #{value[0]}"
|
||||
|
||||
$newLabelError
|
||||
.text label.message
|
||||
.html errors.join("<br/>")
|
||||
.show()
|
||||
else
|
||||
$('.dropdown-menu-back', $dropdown.parent()).trigger 'click'
|
||||
|
@ -254,7 +257,7 @@ class @LabelsSelect
|
|||
search:
|
||||
fields: ['title']
|
||||
selectable: true
|
||||
|
||||
filterable: true
|
||||
toggleLabel: (selected, el) ->
|
||||
selected_labels = $('.js-label-select').siblings('.dropdown-menu-labels').find('.is-active')
|
||||
|
||||
|
|
|
@ -47,4 +47,4 @@ $ ->
|
|||
# Make logo clickable as part of a workaround for Safari visited
|
||||
# link behaviour (See !2690).
|
||||
$('#logo').on 'click', ->
|
||||
$('#js-shortcuts-home').get(0).click()
|
||||
Turbolinks.visit('/')
|
||||
|
|
|
@ -7,12 +7,17 @@ class @ProjectNew
|
|||
@toggleSettingsOnclick()
|
||||
|
||||
|
||||
toggleSettings: ->
|
||||
checked = $("#project_builds_enabled").prop("checked")
|
||||
if checked
|
||||
$('.builds-feature').show()
|
||||
else
|
||||
$('.builds-feature').hide()
|
||||
toggleSettings: =>
|
||||
@_showOrHide('#project_builds_enabled', '.builds-feature')
|
||||
@_showOrHide('#project_merge_requests_enabled', '.merge-requests-feature')
|
||||
|
||||
toggleSettingsOnclick: ->
|
||||
$("#project_builds_enabled").on 'click', @toggleSettings
|
||||
$('#project_builds_enabled, #project_merge_requests_enabled').on 'click', @toggleSettings
|
||||
|
||||
_showOrHide: (checkElement, container) ->
|
||||
$container = $(container)
|
||||
|
||||
if $(checkElement).prop('checked')
|
||||
$container.show()
|
||||
else
|
||||
$container.hide()
|
||||
|
|
|
@ -4,8 +4,6 @@ expanded = 'page-sidebar-expanded'
|
|||
toggleSidebar = ->
|
||||
$('.page-with-sidebar').toggleClass("#{collapsed} #{expanded}")
|
||||
$('header').toggleClass("header-collapsed header-expanded")
|
||||
$('.toggle-nav-collapse i').toggleClass("fa-angle-right fa-angle-left")
|
||||
$.cookie("collapsed_nav", $('.page-with-sidebar').hasClass(collapsed), { path: '/' })
|
||||
|
||||
setTimeout ( ->
|
||||
niceScrollBars = $('.nicescroll').niceScroll();
|
||||
|
@ -17,10 +15,3 @@ $(document).on("click", '.toggle-nav-collapse, .side-nav-toggle', (e) ->
|
|||
|
||||
toggleSidebar()
|
||||
)
|
||||
|
||||
$ ->
|
||||
size = bp.getBreakpointSize()
|
||||
|
||||
if size is "xs" or size is "sm"
|
||||
if $('.page-with-sidebar').hasClass(expanded)
|
||||
toggleSidebar()
|
||||
|
|
|
@ -95,7 +95,7 @@ class @UsersSelect
|
|||
data: (term, callback) =>
|
||||
isAuthorFilter = $('.js-author-search')
|
||||
|
||||
@users term, term is '' and isAuthorFilter, (users) =>
|
||||
@users term, (users) =>
|
||||
if term.length is 0
|
||||
showDivider = 0
|
||||
|
||||
|
@ -221,7 +221,7 @@ class @UsersSelect
|
|||
multiple: $(select).hasClass('multiselect')
|
||||
minimumInputLength: 0
|
||||
query: (query) =>
|
||||
@users query.term, @projectId?, (users) =>
|
||||
@users query.term, (users) =>
|
||||
data = { results: users }
|
||||
|
||||
if query.term.length == 0
|
||||
|
@ -304,7 +304,7 @@ class @UsersSelect
|
|||
|
||||
# Return users list. Filtered by query
|
||||
# Only active users retrieved
|
||||
users: (query, fromProject, callback) =>
|
||||
users: (query, callback) =>
|
||||
url = @buildUrl(@usersPath)
|
||||
|
||||
$.ajax(
|
||||
|
@ -313,7 +313,7 @@ class @UsersSelect
|
|||
search: query
|
||||
per_page: 20
|
||||
active: true
|
||||
project_id: @projectId if fromProject
|
||||
project_id: @projectId
|
||||
group_id: @groupId
|
||||
current_user: @showCurrentUser
|
||||
author_id: @authorId
|
||||
|
|
|
@ -8,32 +8,14 @@
|
|||
*/
|
||||
@mixin gitlab-theme($color-light, $color, $color-darker, $color-dark) {
|
||||
.page-with-sidebar {
|
||||
.header-logo {
|
||||
background: $color-darker;
|
||||
|
||||
a {
|
||||
color: $color-light;
|
||||
|
||||
h3 {
|
||||
color: $color-light;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $color-dark;
|
||||
a {
|
||||
color: $white-light;
|
||||
|
||||
h3 {
|
||||
color: $white-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.collapse-nav a {
|
||||
color: $white-light;
|
||||
color: $color-light;
|
||||
background: $color;
|
||||
|
||||
&:hover {
|
||||
color: $white-light;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
|
|
|
@ -109,10 +109,8 @@ header {
|
|||
position: relative;
|
||||
height: $header-height;
|
||||
padding-right: 40px;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-left: 40px;
|
||||
}
|
||||
padding-left: 30px;
|
||||
transition-duration: .3s;
|
||||
|
||||
@media (min-width: $screen-sm-min) {
|
||||
padding-right: 0;
|
||||
|
@ -122,9 +120,29 @@ header {
|
|||
margin-top: -5px;
|
||||
}
|
||||
|
||||
.header-logo {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -18px;
|
||||
top: 7px;
|
||||
transition-duration: .3s;
|
||||
z-index: 999;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
right: 25px;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
font-size: 19px;
|
||||
max-width: 400px;
|
||||
display: inline-block;
|
||||
line-height: $header-height;
|
||||
font-weight: normal;
|
||||
color: $gl-text-color;
|
||||
|
@ -133,6 +151,10 @@ header {
|
|||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: $screen-sm-max) {
|
||||
max-width: 190px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $gl-text-color;
|
||||
&:hover {
|
||||
|
@ -160,6 +182,10 @@ header {
|
|||
.navbar-collapse {
|
||||
float: right;
|
||||
border-top: none;
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,17 +202,20 @@ header {
|
|||
margin-left: 0;
|
||||
|
||||
.header-content {
|
||||
padding-left: 30px;
|
||||
transition-duration: .3s;
|
||||
|
||||
@media (min-width: $screen-sm-max) {
|
||||
padding-left: 30px;
|
||||
transition-duration: .3s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.header-expanded {
|
||||
margin-left: 0;
|
||||
.tanuki-shape {
|
||||
transition: all 0.8s;
|
||||
|
||||
.header-content {
|
||||
padding-left: $sidebar_width;
|
||||
transition-duration: .3s;
|
||||
&:hover, &.highlight {
|
||||
fill: rgb(255, 255, 255);
|
||||
transition: all 0.1s;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@mixin fade($gradient-direction, $rgba, $gradient-color) {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
bottom: 12px;
|
||||
width: 43px;
|
||||
|
@ -68,6 +69,7 @@
|
|||
}
|
||||
|
||||
&.sub-nav {
|
||||
text-align: center;
|
||||
background-color: $background-color;
|
||||
|
||||
.container-fluid {
|
||||
|
@ -171,7 +173,6 @@
|
|||
> form {
|
||||
display: inline-block;
|
||||
margin-top: -1px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.icon-label {
|
||||
|
@ -250,6 +251,7 @@
|
|||
background: $background-color;
|
||||
border-bottom: 1px solid $border-color;
|
||||
transition-duration: .3s;
|
||||
text-align: center;
|
||||
|
||||
.container-fluid {
|
||||
position: relative;
|
||||
|
@ -352,7 +354,7 @@
|
|||
|
||||
.fade-right {
|
||||
@media (min-width: $screen-xs-max) {
|
||||
right: 67px;
|
||||
right: 68px;
|
||||
}
|
||||
@media (max-width: $screen-xs-min) {
|
||||
right: 0;
|
||||
|
|
|
@ -35,24 +35,11 @@
|
|||
}
|
||||
|
||||
.sidebar-wrapper {
|
||||
.header-logo {
|
||||
height: $header-height;
|
||||
padding: 8px 26px;
|
||||
width: $sidebar_width;
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
overflow: hidden;
|
||||
transition-duration: .3s;
|
||||
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-user {
|
||||
padding: 15px 22px;
|
||||
position: fixed;
|
||||
bottom: 40px;
|
||||
bottom: 0;
|
||||
width: $sidebar_width;
|
||||
overflow: hidden;
|
||||
transition-duration: .3s;
|
||||
|
@ -97,10 +84,10 @@
|
|||
}
|
||||
|
||||
a {
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
width: $sidebar_width;
|
||||
padding: 7px 15px 7px 23px;
|
||||
font-size: $gl-font-size;
|
||||
color: $gray;
|
||||
line-height: 24px;
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
|
@ -118,10 +105,9 @@
|
|||
font-size: 16px;
|
||||
}
|
||||
|
||||
.nav-link-text {
|
||||
margin-top: 3px;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
i,
|
||||
svg {
|
||||
margin-right: 13px;
|
||||
}
|
||||
|
||||
&.back-link i {
|
||||
|
@ -129,6 +115,12 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.count {
|
||||
float: right;
|
||||
padding: 0 8px;
|
||||
@include border-radius(6px);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-subnav {
|
||||
|
@ -143,11 +135,12 @@
|
|||
.collapse-nav a {
|
||||
width: $sidebar_width;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
font-size: 13px;
|
||||
padding: 5px 0;
|
||||
font-size: 18px;
|
||||
background: transparent;
|
||||
height: 40px;
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
transition-duration: .3s;
|
||||
|
@ -170,25 +163,8 @@
|
|||
.sidebar-wrapper {
|
||||
width: 0;
|
||||
|
||||
.header-logo {
|
||||
width: 0;
|
||||
padding: 8px 0;
|
||||
|
||||
a {
|
||||
padding-left: ($sidebar_collapsed_width - 36) / 2;
|
||||
|
||||
.gitlab-text-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-sidebar {
|
||||
width: $sidebar_collapsed_width;
|
||||
width: 0;
|
||||
|
||||
li {
|
||||
width: auto;
|
||||
|
@ -203,6 +179,10 @@
|
|||
|
||||
.collapse-nav a {
|
||||
width: 0;
|
||||
|
||||
i {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-user {
|
||||
|
@ -218,9 +198,8 @@
|
|||
}
|
||||
|
||||
.page-sidebar-expanded {
|
||||
padding-left: $sidebar_width;
|
||||
|
||||
@media (max-width: $screen-xs-min) {
|
||||
@media (max-width: $screen-sm-max) {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
|
@ -241,20 +220,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.layout-nav {
|
||||
@media (max-width: $screen-xs-min) {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
@media (min-width: $screen-xs-min) and (max-width: $screen-md-min) {
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
@media (min-width: $screen-md-min) {
|
||||
padding-right: $sidebar_width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-sidebar-collapsed {
|
||||
|
@ -273,7 +238,9 @@
|
|||
padding-right: 0;
|
||||
|
||||
@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max) {
|
||||
padding-right: $sidebar_collapsed_width;
|
||||
&:not(.build-sidebar) {
|
||||
padding-right: $sidebar_collapsed_width;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $screen-md-min) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Layout
|
||||
*/
|
||||
$sidebar_collapsed_width: 62px;
|
||||
$sidebar_width: 90px;
|
||||
$sidebar_width: 220px;
|
||||
$gutter_collapsed_width: 62px;
|
||||
$gutter_width: 290px;
|
||||
$gutter_inner_width: 258px;
|
||||
|
@ -265,3 +265,6 @@ $calendar-unselectable-bg: #faf9f9;
|
|||
* Personal Access Tokens
|
||||
*/
|
||||
$personal-access-tokens-disabled-label-color: #bbb;
|
||||
|
||||
$ci-output-bg: #1d1f21;
|
||||
$ci-text-color: #c5c8c6;
|
||||
|
|
|
@ -101,13 +101,21 @@
|
|||
line-height: 20px;
|
||||
outline: 0;
|
||||
|
||||
&:hover,
|
||||
&.active,
|
||||
&:active {
|
||||
background-color: $white-dark;
|
||||
background-color: $row-hover;
|
||||
border-color: $row-hover-border;
|
||||
box-shadow: none;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&.btn {
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-loading {
|
||||
.award-control-icon-normal,
|
||||
.emoji-icon {
|
||||
|
|
|
@ -53,37 +53,92 @@
|
|||
left: 70px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.build-widget {
|
||||
padding: 10px;
|
||||
background: $background-color;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 4px;
|
||||
.build-header {
|
||||
position: relative;
|
||||
padding-right: 40px;
|
||||
|
||||
.title {
|
||||
margin-top: 0;
|
||||
color: #666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.attr-name {
|
||||
color: #777;
|
||||
@media (min-width: $screen-sm-min) {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $gl-gray;
|
||||
|
||||
&:hover {
|
||||
color: $gl-link-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-disabled {
|
||||
background: $background-color;
|
||||
code {
|
||||
color: $code-color;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3084bb !important;
|
||||
}
|
||||
.avatar {
|
||||
float: none;
|
||||
margin-right: 2px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
table.builds {
|
||||
|
||||
.build-link {
|
||||
a {
|
||||
color: $gl-dark-link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.build-trace {
|
||||
background: $ci-output-bg;
|
||||
color: $ci-text-color;
|
||||
white-space: pre;
|
||||
overflow-x: auto;
|
||||
font-size: 12px;
|
||||
|
||||
.fa-refresh {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.bash {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.right-sidebar.build-sidebar {
|
||||
padding-top: $gl-padding;
|
||||
padding-bottom: $gl-padding;
|
||||
|
||||
&.right-sidebar-collapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.block {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.build-sidebar-header {
|
||||
padding-top: 0;
|
||||
|
||||
.gutter-toggle {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.build-detail-row {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.build-light-text {
|
||||
color: $gl-placeholder-color;
|
||||
}
|
||||
|
||||
.build-gutter-toggle {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 0;
|
||||
margin-top: -17px;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.issuable-sidebar {
|
||||
.right-sidebar {
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
@ -74,6 +74,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.block-first {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: $gl-text-color;
|
||||
margin-bottom: 10px;
|
||||
|
|
|
@ -11,18 +11,15 @@
|
|||
$magenta: #cd00cd;
|
||||
$cyan: #00cdcd;
|
||||
$white: #e5e5e5;
|
||||
$l-black: #7f7f7f;
|
||||
$l-red: #f00;
|
||||
$l-green: #0f0;
|
||||
$l-yellow: #ff0;
|
||||
$l-blue: #5c5cff;
|
||||
$l-magenta: #f0f;
|
||||
$l-cyan: #0ff;
|
||||
$l-white: #fff;
|
||||
$l-black: #373b41;
|
||||
$l-red: #c66;
|
||||
$l-green: #b5bd68;
|
||||
$l-yellow: #f0c674;
|
||||
$l-blue: #81a2be;
|
||||
$l-magenta: #b294bb;
|
||||
$l-cyan: #8abeb7;
|
||||
$l-white: $ci-text-color;
|
||||
|
||||
.term-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
.term-italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
|
|||
include Gitlab::GonHelper
|
||||
include GitlabRoutingHelper
|
||||
include PageLayoutHelper
|
||||
include WorkhorseHelper
|
||||
|
||||
before_action :authenticate_user_from_token!
|
||||
before_action :authenticate_user!
|
||||
|
|
|
@ -42,7 +42,7 @@ class JwtController < ApplicationController
|
|||
end
|
||||
|
||||
def authenticate_user(login, password)
|
||||
user = Gitlab::Auth.find_in_gitlab_or_ldap(login, password)
|
||||
user = Gitlab::Auth.find_with_user_password(login, password)
|
||||
Gitlab::Auth.rate_limit!(request.ip, success: user.present?, login: login)
|
||||
user
|
||||
end
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
class Profiles::NotificationsController < Profiles::ApplicationController
|
||||
def show
|
||||
@user = current_user
|
||||
@group_notifications = current_user.notification_settings.for_groups
|
||||
@project_notifications = current_user.notification_settings.for_projects
|
||||
@user = current_user
|
||||
@group_notifications = current_user.notification_settings.for_groups
|
||||
@project_notifications = current_user.notification_settings.for_projects
|
||||
@global_notification_setting = current_user.global_notification_setting
|
||||
end
|
||||
|
||||
def update
|
||||
if current_user.update_attributes(user_params)
|
||||
if current_user.update_attributes(user_params) && update_notification_settings
|
||||
flash[:notice] = "Notification settings saved"
|
||||
else
|
||||
flash[:alert] = "Failed to save new settings"
|
||||
|
@ -16,6 +17,18 @@ class Profiles::NotificationsController < Profiles::ApplicationController
|
|||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:notification_email, :notification_level)
|
||||
params.require(:user).permit(:notification_email)
|
||||
end
|
||||
|
||||
def global_notification_setting_params
|
||||
params.require(:global_notification_setting).permit(:level)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_notification_settings
|
||||
return true unless global_notification_setting_params
|
||||
|
||||
current_user.global_notification_setting.update_attributes(global_notification_setting_params)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,10 +10,7 @@ class Projects::AvatarsController < Projects::ApplicationController
|
|||
|
||||
return if cached_blob?
|
||||
|
||||
headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
headers['Content-Type'] = safe_content_type(@blob)
|
||||
head :ok # 'render nothing: true' messes up the Content-Type
|
||||
send_git_blob @repository, @blob
|
||||
else
|
||||
render_404
|
||||
end
|
||||
|
|
|
@ -41,7 +41,7 @@ class Projects::BuildsController < Projects::ApplicationController
|
|||
def trace
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: @build.trace_with_state(params[:state]).merge!(id: @build.id, status: @build.status)
|
||||
render json: @build.trace_with_state(params[:state].presence).merge!(id: @build.id, status: @build.status)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ class Projects::GitHttpController < Projects::ApplicationController
|
|||
return if project && project.public? && upload_pack?
|
||||
|
||||
authenticate_or_request_with_http_basic do |login, password|
|
||||
auth_result = Gitlab::Auth.find(login, password, project: project, ip: request.ip)
|
||||
auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip)
|
||||
|
||||
if auth_result.type == :ci && upload_pack?
|
||||
@ci = true
|
||||
|
|
|
@ -61,12 +61,9 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
|||
format.json { render json: @merge_request }
|
||||
format.patch { render text: @merge_request.to_patch }
|
||||
format.diff do
|
||||
headers.store(*Gitlab::Workhorse.send_git_diff(@project.repository,
|
||||
@merge_request.diff_base_commit.id,
|
||||
@merge_request.last_commit.id))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
return render_404 unless @merge_request.diff_refs
|
||||
|
||||
head :ok
|
||||
send_git_diff @project.repository, @merge_request.diff_refs
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,10 +18,7 @@ class Projects::RawController < Projects::ApplicationController
|
|||
if @blob.lfs_pointer?
|
||||
send_lfs_object
|
||||
else
|
||||
headers.store(*Gitlab::Workhorse.send_git_blob(@repository, @blob))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
headers['Content-Type'] = safe_content_type(@blob)
|
||||
head :ok # 'render nothing: true' messes up the Content-Type
|
||||
send_git_blob @repository, @blob
|
||||
end
|
||||
else
|
||||
render_404
|
||||
|
|
|
@ -11,8 +11,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
|
|||
end
|
||||
|
||||
def archive
|
||||
headers.store(*Gitlab::Workhorse.send_git_archive(@project, params[:ref], params[:format]))
|
||||
head :ok
|
||||
send_git_archive @repository, ref: params[:ref], format: params[:format]
|
||||
rescue => ex
|
||||
logger.error("#{self.class.name}: #{ex}")
|
||||
return git_not_found!
|
||||
|
|
|
@ -234,7 +234,7 @@ class ProjectsController < Projects::ApplicationController
|
|||
:issues_tracker_id, :default_branch,
|
||||
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
|
||||
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
|
||||
:public_builds,
|
||||
:public_builds, :only_allow_merge_if_build_succeeds
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -14,4 +14,8 @@ module BranchesHelper
|
|||
|
||||
::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(branch_name)
|
||||
end
|
||||
|
||||
def project_branches
|
||||
options_for_select(@project.repository.branch_names, @project.default_branch)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,9 +67,9 @@ module DropdownsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def dropdown_filter(placeholder)
|
||||
def dropdown_filter(placeholder, search_id: nil)
|
||||
content_tag :div, class: "dropdown-input" do
|
||||
filter_output = search_field_tag nil, nil, class: "dropdown-input-field", placeholder: placeholder
|
||||
filter_output = search_field_tag search_id, nil, class: "dropdown-input-field", placeholder: placeholder
|
||||
filter_output << icon('search', class: "dropdown-input-search")
|
||||
filter_output << icon('times', class: "dropdown-input-clear js-dropdown-input-clear", role: "button")
|
||||
|
||||
|
|
|
@ -30,17 +30,13 @@ module NavHelper
|
|||
else
|
||||
"page-gutter right-sidebar-expanded"
|
||||
end
|
||||
elsif current_path?('builds#show')
|
||||
"page-gutter build-sidebar right-sidebar-expanded"
|
||||
end
|
||||
end
|
||||
|
||||
def nav_header_class
|
||||
class_name =
|
||||
if nav_menu_collapsed?
|
||||
"header-collapsed"
|
||||
else
|
||||
"header-expanded"
|
||||
end
|
||||
class_name += " with-horizontal-nav" if defined?(nav) && nav
|
||||
class_name = " with-horizontal-nav" if defined?(nav) && nav
|
||||
class_name
|
||||
end
|
||||
|
||||
|
|
|
@ -61,4 +61,23 @@ module NotificationsHelper
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def notification_level_radio_buttons
|
||||
html = ""
|
||||
|
||||
NotificationSetting.levels.each_key do |level|
|
||||
level = level.to_sym
|
||||
next if level == :global
|
||||
|
||||
html << content_tag(:div, class: "radio") do
|
||||
content_tag(:label, { value: level }) do
|
||||
radio_button_tag(:"global_notification_setting[level]", level, @global_notification_setting.level.to_sym == level) +
|
||||
content_tag(:div, level.to_s.capitalize, class: "level-title") +
|
||||
content_tag(:p, notification_description(level))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
html.html_safe
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# Helpers to send Git blobs, diffs or archives through Workhorse.
|
||||
# Workhorse will also serve files when using `send_file`.
|
||||
module WorkhorseHelper
|
||||
# Send a Git blob through Workhorse
|
||||
def send_git_blob(repository, blob)
|
||||
headers.store(*Gitlab::Workhorse.send_git_blob(repository, blob))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
headers['Content-Type'] = safe_content_type(blob)
|
||||
head :ok # 'render nothing: true' messes up the Content-Type
|
||||
end
|
||||
|
||||
# Send a Git diff through Workhorse
|
||||
def send_git_diff(repository, diff_refs)
|
||||
headers.store(*Gitlab::Workhorse.send_git_diff(repository, diff_refs))
|
||||
headers['Content-Disposition'] = 'inline'
|
||||
head :ok
|
||||
end
|
||||
|
||||
# Archive a Git repository and send it through Workhorse
|
||||
def send_git_archive(repository, ref:, format:)
|
||||
headers.store(*Gitlab::Workhorse.send_git_archive(repository, ref: ref, format: format))
|
||||
head :ok
|
||||
end
|
||||
end
|
|
@ -194,7 +194,7 @@ module Ci
|
|||
|
||||
def trace_length
|
||||
if raw_trace
|
||||
raw_trace.length
|
||||
raw_trace.bytesize
|
||||
else
|
||||
0
|
||||
end
|
||||
|
@ -216,7 +216,7 @@ module Ci
|
|||
recreate_trace_dir
|
||||
|
||||
File.truncate(path_to_trace, offset) if File.exist?(path_to_trace)
|
||||
File.open(path_to_trace, 'a') do |f|
|
||||
File.open(path_to_trace, 'ab') do |f|
|
||||
f.write(trace_part)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ module Ci
|
|||
extend Ci::Model
|
||||
|
||||
belongs_to :trigger, class_name: 'Ci::Trigger'
|
||||
belongs_to :commit, class_name: 'Ci::Pipeline', foreign_key: :commit_id
|
||||
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id
|
||||
has_many :builds, class_name: 'Ci::Build'
|
||||
|
||||
serialize :variables
|
||||
|
|
|
@ -260,19 +260,20 @@ class MergeRequest < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def mergeable?
|
||||
return false unless open? && !work_in_progress? && !broken?
|
||||
return false unless mergeable_state?
|
||||
|
||||
check_if_can_be_merged
|
||||
|
||||
can_be_merged?
|
||||
end
|
||||
|
||||
def gitlab_merge_status
|
||||
if work_in_progress?
|
||||
"work_in_progress"
|
||||
else
|
||||
merge_status_name
|
||||
end
|
||||
def mergeable_state?
|
||||
return false unless open?
|
||||
return false if work_in_progress?
|
||||
return false if broken?
|
||||
return false unless mergeable_ci_state?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def can_cancel_merge_when_build_succeeds?(current_user)
|
||||
|
@ -481,6 +482,12 @@ class MergeRequest < ActiveRecord::Base
|
|||
::Gitlab::GitAccess.new(user, project).can_push_to_branch?(target_branch)
|
||||
end
|
||||
|
||||
def mergeable_ci_state?
|
||||
return true unless project.only_allow_merge_if_build_succeeds?
|
||||
|
||||
!pipeline || pipeline.success?
|
||||
end
|
||||
|
||||
def state_human_name
|
||||
if merged?
|
||||
"Merged"
|
||||
|
|
|
@ -7,7 +7,6 @@ class NotificationSetting < ActiveRecord::Base
|
|||
belongs_to :source, polymorphic: true
|
||||
|
||||
validates :user, presence: true
|
||||
validates :source, presence: true
|
||||
validates :level, presence: true
|
||||
validates :user_id, uniqueness: { scope: [:source_type, :source_id],
|
||||
message: "already exists in source",
|
||||
|
|
|
@ -146,7 +146,6 @@ class Project < ActiveRecord::Base
|
|||
message: Gitlab::Regex.project_path_regex_message }
|
||||
validates :issues_enabled, :merge_requests_enabled,
|
||||
:wiki_enabled, inclusion: { in: [true, false] }
|
||||
validates :issues_tracker_id, length: { maximum: 255 }, allow_blank: true
|
||||
validates :namespace, presence: true
|
||||
validates_uniqueness_of :name, scope: :namespace_id
|
||||
validates_uniqueness_of :path, scope: :namespace_id
|
||||
|
@ -253,20 +252,69 @@ class Project < ActiveRecord::Base
|
|||
non_archived.where(table[:name].matches(pattern))
|
||||
end
|
||||
|
||||
def find_with_namespace(id)
|
||||
namespace_path, project_path = id.split('/', 2)
|
||||
# Finds a single project for the given path.
|
||||
#
|
||||
# path - The full project path (including namespace path).
|
||||
#
|
||||
# Returns a Project, or nil if no project could be found.
|
||||
def find_with_namespace(path)
|
||||
where_paths_in([path]).reorder(nil).take
|
||||
end
|
||||
|
||||
return nil if !namespace_path || !project_path
|
||||
# Builds a relation to find multiple projects by their full paths.
|
||||
#
|
||||
# Each path must be in the following format:
|
||||
#
|
||||
# namespace_path/project_path
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# gitlab-org/gitlab-ce
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# Project.where_paths_in(%w{gitlab-org/gitlab-ce gitlab-org/gitlab-ee})
|
||||
#
|
||||
# This would return the projects with the full paths matching the values
|
||||
# given.
|
||||
#
|
||||
# paths - An Array of full paths (namespace path + project path) for which
|
||||
# to find the projects.
|
||||
#
|
||||
# Returns an ActiveRecord::Relation.
|
||||
def where_paths_in(paths)
|
||||
wheres = []
|
||||
cast_lower = Gitlab::Database.postgresql?
|
||||
|
||||
# Use of unscoped ensures we're not secretly adding any ORDER BYs, which
|
||||
# have a negative impact on performance (and aren't needed for this
|
||||
# query).
|
||||
projects = unscoped.
|
||||
joins(:namespace).
|
||||
iwhere('namespaces.path' => namespace_path)
|
||||
paths.each do |path|
|
||||
namespace_path, project_path = path.split('/', 2)
|
||||
|
||||
projects.find_by('projects.path' => project_path) ||
|
||||
projects.iwhere('projects.path' => project_path).take
|
||||
next unless namespace_path && project_path
|
||||
|
||||
namespace_path = connection.quote(namespace_path)
|
||||
project_path = connection.quote(project_path)
|
||||
|
||||
where = "(namespaces.path = #{namespace_path}
|
||||
AND projects.path = #{project_path})"
|
||||
|
||||
if cast_lower
|
||||
where = "(
|
||||
#{where}
|
||||
OR (
|
||||
LOWER(namespaces.path) = LOWER(#{namespace_path})
|
||||
AND LOWER(projects.path) = LOWER(#{project_path})
|
||||
)
|
||||
)"
|
||||
end
|
||||
|
||||
wheres << where
|
||||
end
|
||||
|
||||
if wheres.empty?
|
||||
none
|
||||
else
|
||||
joins(:namespace).where(wheres.join(' OR '))
|
||||
end
|
||||
end
|
||||
|
||||
def visibility_levels
|
||||
|
@ -523,13 +571,21 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def external_issue_tracker
|
||||
return @external_issue_tracker if defined?(@external_issue_tracker)
|
||||
@external_issue_tracker ||=
|
||||
services.issue_trackers.active.without_defaults.first
|
||||
if has_external_issue_tracker.nil? # To populate existing projects
|
||||
cache_has_external_issue_tracker
|
||||
end
|
||||
|
||||
if has_external_issue_tracker?
|
||||
return @external_issue_tracker if defined?(@external_issue_tracker)
|
||||
|
||||
@external_issue_tracker = services.external_issue_trackers.first
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def can_have_issues_tracker_id?
|
||||
self.issues_enabled && !self.default_issues_tracker?
|
||||
def cache_has_external_issue_tracker
|
||||
update_column(:has_external_issue_tracker, services.external_issue_trackers.any?)
|
||||
end
|
||||
|
||||
def build_missing_services
|
||||
|
|
|
@ -38,9 +38,9 @@ class IssueTrackerService < Service
|
|||
if enabled_in_gitlab_config
|
||||
self.properties = {
|
||||
title: issues_tracker['title'],
|
||||
project_url: add_issues_tracker_id(issues_tracker['project_url']),
|
||||
issues_url: add_issues_tracker_id(issues_tracker['issues_url']),
|
||||
new_issue_url: add_issues_tracker_id(issues_tracker['new_issue_url'])
|
||||
project_url: issues_tracker['project_url'],
|
||||
issues_url: issues_tracker['issues_url'],
|
||||
new_issue_url: issues_tracker['new_issue_url']
|
||||
}
|
||||
else
|
||||
self.properties = {}
|
||||
|
@ -83,16 +83,4 @@ class IssueTrackerService < Service
|
|||
def issues_tracker
|
||||
Gitlab.config.issues_tracker[to_param]
|
||||
end
|
||||
|
||||
def add_issues_tracker_id(url)
|
||||
if self.project
|
||||
id = self.project.issues_tracker_id
|
||||
|
||||
if id
|
||||
url = url.gsub(":issues_tracker_id", id)
|
||||
end
|
||||
end
|
||||
|
||||
url
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ class Service < ActiveRecord::Base
|
|||
after_initialize :initialize_properties
|
||||
|
||||
after_commit :reset_updated_properties
|
||||
after_commit :cache_project_has_external_issue_tracker
|
||||
|
||||
belongs_to :project
|
||||
has_one :service_hook
|
||||
|
@ -34,6 +35,7 @@ class Service < ActiveRecord::Base
|
|||
scope :note_hooks, -> { where(note_events: true, active: true) }
|
||||
scope :build_hooks, -> { where(build_events: true, active: true) }
|
||||
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
|
||||
scope :external_issue_trackers, -> { issue_trackers.active.without_defaults }
|
||||
|
||||
default_value_for :category, 'common'
|
||||
|
||||
|
@ -192,4 +194,12 @@ class Service < ActiveRecord::Base
|
|||
service.project_id = project_id
|
||||
service if service.save
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def cache_project_has_external_issue_tracker
|
||||
if project && !project.destroyed?
|
||||
project.cache_has_external_issue_tracker
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,8 @@ class User < ActiveRecord::Base
|
|||
include CaseSensitivity
|
||||
include TokenAuthenticatable
|
||||
|
||||
DEFAULT_NOTIFICATION_LEVEL = :participating
|
||||
|
||||
add_authentication_token_field :authentication_token
|
||||
|
||||
default_value_for :admin, false
|
||||
|
@ -100,7 +102,6 @@ class User < ActiveRecord::Base
|
|||
presence: true,
|
||||
uniqueness: { case_sensitive: false }
|
||||
|
||||
validates :notification_level, presence: true
|
||||
validate :namespace_uniq, if: ->(user) { user.username_changed? }
|
||||
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
|
||||
validate :unique_email, if: ->(user) { user.email_changed? }
|
||||
|
@ -134,13 +135,6 @@ class User < ActiveRecord::Base
|
|||
# Note: When adding an option, it MUST go on the end of the array.
|
||||
enum project_view: [:readme, :activity, :files]
|
||||
|
||||
# Notification level
|
||||
# Note: When adding an option, it MUST go on the end of the array.
|
||||
#
|
||||
# TODO: Add '_prefix: :notification' to enum when update to Rails 5. https://github.com/rails/rails/pull/19813
|
||||
# Because user.notification_disabled? is much better than user.disabled?
|
||||
enum notification_level: [:disabled, :participating, :watch, :global, :mention]
|
||||
|
||||
alias_attribute :private_token, :authentication_token
|
||||
|
||||
delegate :path, to: :namespace, allow_nil: true, prefix: true
|
||||
|
@ -801,6 +795,17 @@ class User < ActiveRecord::Base
|
|||
notification_settings.find_or_initialize_by(source: source)
|
||||
end
|
||||
|
||||
# Lazy load global notification setting
|
||||
# Initializes User setting with Participating level if setting not persisted
|
||||
def global_notification_setting
|
||||
return @global_notification_setting if defined?(@global_notification_setting)
|
||||
|
||||
@global_notification_setting = notification_settings.find_or_initialize_by(source: nil)
|
||||
@global_notification_setting.update_attributes(level: NotificationSetting.levels[DEFAULT_NOTIFICATION_LEVEL]) unless @global_notification_setting.persisted?
|
||||
|
||||
@global_notification_setting
|
||||
end
|
||||
|
||||
def assigned_open_merge_request_count(force: false)
|
||||
Rails.cache.fetch(['users', id, 'assigned_open_merge_request_count'], force: force) do
|
||||
assigned_merge_requests.opened.count
|
||||
|
|
|
@ -11,7 +11,7 @@ module Ci
|
|||
|
||||
trigger_request = trigger.trigger_requests.create!(
|
||||
variables: variables,
|
||||
commit: pipeline,
|
||||
pipeline: pipeline,
|
||||
)
|
||||
|
||||
if pipeline.create_builds(nil, trigger_request)
|
||||
|
|
|
@ -279,10 +279,11 @@ class NotificationService
|
|||
end
|
||||
|
||||
def users_with_global_level_watch(ids)
|
||||
User.where(
|
||||
id: ids,
|
||||
notification_level: NotificationSetting.levels[:watch]
|
||||
).pluck(:id)
|
||||
NotificationSetting.where(
|
||||
user_id: ids,
|
||||
source_type: nil,
|
||||
level: NotificationSetting.levels[:watch]
|
||||
).pluck(:user_id)
|
||||
end
|
||||
|
||||
# Build a list of users based on project notifcation settings
|
||||
|
@ -352,7 +353,9 @@ class NotificationService
|
|||
users = users.reject(&:blocked?)
|
||||
|
||||
users.reject do |user|
|
||||
next user.notification_level == level unless project
|
||||
global_notification_setting = user.global_notification_setting
|
||||
|
||||
next global_notification_setting.level == level unless project
|
||||
|
||||
setting = user.notification_settings_for(project)
|
||||
|
||||
|
@ -361,13 +364,13 @@ class NotificationService
|
|||
end
|
||||
|
||||
# reject users who globally set mention notification and has no setting per project/group
|
||||
next user.notification_level == level unless setting
|
||||
next global_notification_setting.level == level unless setting
|
||||
|
||||
# reject users who set mention notification in project
|
||||
next true if setting.level == level
|
||||
|
||||
# reject users who have mention level in project and disabled in global settings
|
||||
setting.global? && user.notification_level == level
|
||||
setting.global? && global_notification_setting.level == level
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -456,7 +459,6 @@ class NotificationService
|
|||
|
||||
def build_recipients(target, project, current_user, action: nil, previous_assignee: nil)
|
||||
recipients = target.participants(current_user)
|
||||
|
||||
recipients = add_project_watchers(recipients, project)
|
||||
recipients = reject_mention_users(recipients, project)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
|
|||
xml.link href: issues_dashboard_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
|
||||
xml.link href: issues_dashboard_url, rel: "alternate", type: "text/html"
|
||||
xml.id issues_dashboard_url
|
||||
xml.updated @issues.first.created_at.xmlschema if @issues.any?
|
||||
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
|
||||
|
||||
xml << render(partial: 'issues/issue', collection: @issues) if @issues.any?
|
||||
xml << render(partial: 'issues/issue', collection: @issues) if @issues.reorder(nil).any?
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
|
|||
xml.link href: issues_group_url(format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
|
||||
xml.link href: issues_group_url, rel: "alternate", type: "text/html"
|
||||
xml.id issues_group_url
|
||||
xml.updated @issues.first.created_at.xmlschema if @issues.any?
|
||||
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
|
||||
|
||||
xml << render(partial: 'issues/issue', collection: @issues) if @issues.any?
|
||||
xml << render(partial: 'issues/issue', collection: @issues) if @issues.reorder(nil).any?
|
||||
end
|
||||
|
|
|
@ -1,4 +1 @@
|
|||
- if nav_menu_collapsed?
|
||||
= link_to icon('angle-right'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
|
||||
- else
|
||||
= link_to icon('angle-left'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
|
||||
= link_to icon('bars'), '#', class: 'toggle-nav-collapse', title: "Open/Close"
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
.page-with-sidebar{ class: "#{page_sidebar_class} #{page_gutter_class}" }
|
||||
.page-with-sidebar.page-sidebar-collapsed{ class: "#{page_gutter_class}" }
|
||||
.sidebar-wrapper.nicescroll{ class: nav_sidebar_class }
|
||||
= link_to root_path, class: 'gitlab-text-container-link', title: 'Dashboard', id: 'js-shortcuts-home' do
|
||||
.header-logo
|
||||
#logo
|
||||
= brand_header_logo
|
||||
|
||||
- if defined?(sidebar) && sidebar
|
||||
= render "layouts/nav/#{sidebar}"
|
||||
|
@ -16,7 +12,9 @@
|
|||
= render partial: 'layouts/collapse_button'
|
||||
- if current_user
|
||||
= link_to current_user, class: 'sidebar-user', title: "Profile", data: {user: current_user.username} do
|
||||
= image_tag avatar_icon(current_user, 60), alt: 'Profile', class: 'avatar avatar s46'
|
||||
= image_tag avatar_icon(current_user, 60), alt: 'Profile', class: 'avatar avatar s36'
|
||||
.username
|
||||
= current_user.username
|
||||
- if defined?(nav) && nav
|
||||
.layout-nav
|
||||
.container-fluid
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
.page-with-sidebar{ class: page_sidebar_class }
|
||||
= render "layouts/broadcast"
|
||||
.sidebar-wrapper.nicescroll{ class: nav_sidebar_class }
|
||||
.header-logo
|
||||
%a#logo
|
||||
= brand_header_logo
|
||||
= link_to root_path, class: 'gitlab-text-container-link', title: 'Dashboard', id: 'js-shortcuts-home' do
|
||||
.gitlab-text-container
|
||||
%h3 GitLab
|
||||
|
||||
- if defined?(sidebar) && sidebar
|
||||
= render "layouts/ci/#{sidebar}"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
|
||||
%header.navbar.navbar-fixed-top.navbar-gitlab.header-collapsed{ class: nav_header_class }
|
||||
%div{ class: fluid_layout ? "container-fluid" : "container-fluid" }
|
||||
.header-content
|
||||
%button.side-nav-toggle{type: 'button'}
|
||||
|
@ -50,6 +50,10 @@
|
|||
|
||||
%h1.title= title
|
||||
|
||||
.header-logo
|
||||
#logo
|
||||
= brand_header_logo
|
||||
|
||||
= yield :header_content
|
||||
|
||||
= render 'shared/outdated_browser'
|
||||
|
|
|
@ -2,102 +2,106 @@
|
|||
= nav_link(controller: :dashboard, html_options: {class: 'home'}) do
|
||||
= link_to admin_root_path, title: 'Overview' do
|
||||
= icon('dashboard fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Overview
|
||||
= nav_link(controller: [:admin, :projects]) do
|
||||
= link_to admin_namespaces_projects_path, title: 'Projects' do
|
||||
= icon('cube fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Projects
|
||||
= nav_link(controller: :users) do
|
||||
= link_to admin_users_path, title: 'Users' do
|
||||
= icon('user fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Users
|
||||
= nav_link(controller: :groups) do
|
||||
= link_to admin_groups_path, title: 'Groups' do
|
||||
= icon('group fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Groups
|
||||
= nav_link(controller: :deploy_keys) do
|
||||
= link_to admin_deploy_keys_path, title: 'Deploy Keys' do
|
||||
= icon('key fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Deploy Keys
|
||||
= nav_link path: ['runners#index', 'runners#show'] do
|
||||
= link_to admin_runners_path, title: 'Runners' do
|
||||
= icon('cog fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Runners
|
||||
%span.count= number_with_delimiter(Ci::Runner.count(:all))
|
||||
= nav_link path: 'builds#index' do
|
||||
= link_to admin_builds_path, title: 'Builds' do
|
||||
= icon('link fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Builds
|
||||
%span.count= number_with_delimiter(Ci::Build.count(:all))
|
||||
= nav_link(controller: :logs) do
|
||||
= link_to admin_logs_path, title: 'Logs' do
|
||||
= icon('file-text fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Logs
|
||||
= nav_link(controller: :health_check) do
|
||||
= link_to admin_health_check_path, title: 'Health Check' do
|
||||
= icon('medkit fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Health Check
|
||||
= nav_link(controller: :broadcast_messages) do
|
||||
= link_to admin_broadcast_messages_path, title: 'Messages' do
|
||||
= icon('bullhorn fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Messages
|
||||
= nav_link(controller: :hooks) do
|
||||
= link_to admin_hooks_path, title: 'Hooks' do
|
||||
= icon('external-link fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Hooks
|
||||
= nav_link(controller: :background_jobs) do
|
||||
= link_to admin_background_jobs_path, title: 'Background Jobs' do
|
||||
= icon('cog fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Background Jobs
|
||||
= nav_link(controller: :appearances) do
|
||||
= link_to admin_appearances_path, title: 'Appearances' do
|
||||
= icon('image')
|
||||
.nav-link-text
|
||||
%span
|
||||
Appearance
|
||||
|
||||
= nav_link(controller: :applications) do
|
||||
= link_to admin_applications_path, title: 'Applications' do
|
||||
= icon('cloud fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Applications
|
||||
|
||||
= nav_link(controller: :services) do
|
||||
= link_to admin_application_settings_services_path, title: 'Service Templates' do
|
||||
= icon('copy fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Service Templates
|
||||
|
||||
= nav_link(controller: :labels) do
|
||||
= link_to admin_labels_path, title: 'Labels' do
|
||||
= icon('tags fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Labels
|
||||
|
||||
= nav_link(controller: :abuse_reports) do
|
||||
= link_to admin_abuse_reports_path, title: "Abuse Reports" do
|
||||
= icon('exclamation-circle fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Abuse Reports
|
||||
%span.count= number_with_delimiter(AbuseReport.count(:all))
|
||||
|
||||
- if askimet_enabled?
|
||||
= nav_link(controller: :spam_logs) do
|
||||
= link_to admin_spam_logs_path, title: "Spam Logs" do
|
||||
= icon('exclamation-triangle fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Spam Logs
|
||||
%span.count= number_with_delimiter(SpamLog.count(:all))
|
||||
|
||||
= nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do
|
||||
= link_to admin_application_settings_path, title: 'Settings' do
|
||||
= icon('cogs fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Settings
|
||||
|
|
|
@ -2,50 +2,53 @@
|
|||
= nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: "#{project_tab_class} home"}) do
|
||||
= link_to dashboard_projects_path, title: 'Projects', class: 'dashboard-shortcuts-projects' do
|
||||
= navbar_icon('project')
|
||||
.nav-link-text
|
||||
%span
|
||||
Projects
|
||||
= nav_link(controller: :todos) do
|
||||
= link_to dashboard_todos_path, title: 'Todos' do
|
||||
= icon('bell fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Todos
|
||||
%span.count= number_with_delimiter(todos_pending_count)
|
||||
= nav_link(path: 'dashboard#activity') do
|
||||
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do
|
||||
= navbar_icon('activity')
|
||||
.nav-link-text
|
||||
%span
|
||||
Activity
|
||||
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
|
||||
= link_to dashboard_groups_path, title: 'Groups' do
|
||||
= navbar_icon('group')
|
||||
.nav-link-text
|
||||
%span
|
||||
Groups
|
||||
= nav_link(controller: 'dashboard/milestones') do
|
||||
= link_to dashboard_milestones_path, title: 'Milestones' do
|
||||
= navbar_icon('milestones')
|
||||
.nav-link-text
|
||||
%span
|
||||
Milestones
|
||||
= nav_link(path: 'dashboard#issues') do
|
||||
= link_to assigned_issues_dashboard_path, title: 'Issues', class: 'dashboard-shortcuts-issues' do
|
||||
= navbar_icon('issues')
|
||||
.nav-link-text
|
||||
%span
|
||||
Issues
|
||||
%span.count= number_with_delimiter(current_user.assigned_issues.opened.count)
|
||||
= nav_link(path: 'dashboard#merge_requests') do
|
||||
= link_to assigned_mrs_dashboard_path, title: 'Merge Requests', class: 'dashboard-shortcuts-merge_requests' do
|
||||
= navbar_icon('mr')
|
||||
.nav-link-text
|
||||
%span
|
||||
Merge Requests
|
||||
%span.count= number_with_delimiter(current_user.assigned_merge_requests.opened.count)
|
||||
= nav_link(controller: :snippets) do
|
||||
= link_to dashboard_snippets_path, title: 'Snippets' do
|
||||
= icon('clipboard fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Snippets
|
||||
= nav_link(controller: :help) do
|
||||
= link_to help_path, title: 'Help' do
|
||||
= icon('question-circle fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Help
|
||||
= nav_link(html_options: {class: profile_tab_class}) do
|
||||
= link_to profile_path, title: 'Profile Settings', data: {placement: 'bottom'} do
|
||||
= icon('user fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Profile Settings
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
= nav_link(path: ['dashboard#show', 'root#show', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
|
||||
= link_to explore_root_path, title: 'Projects' do
|
||||
= icon('bookmark fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Projects
|
||||
= nav_link(controller: [:groups, 'groups/milestones', 'groups/group_members']) do
|
||||
= link_to explore_groups_path, title: 'Groups' do
|
||||
= icon('group fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Groups
|
||||
= nav_link(controller: :snippets) do
|
||||
= link_to explore_snippets_path, title: 'Snippets' do
|
||||
= icon('clipboard fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Snippets
|
||||
= nav_link(controller: :help) do
|
||||
= link_to help_path, title: 'Help' do
|
||||
= icon('question-circle fw')
|
||||
.nav-link-text
|
||||
%span
|
||||
Help
|
||||
|
|
|
@ -5,36 +5,30 @@
|
|||
.fade-left
|
||||
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do
|
||||
= link_to group_path(@group), title: 'Home' do
|
||||
= navbar_icon('group')
|
||||
%span
|
||||
Group
|
||||
= nav_link(path: 'groups#activity') do
|
||||
= link_to activity_group_path(@group), title: 'Activity' do
|
||||
= navbar_icon('activity')
|
||||
%span
|
||||
Activity
|
||||
= nav_link(controller: [:group, :milestones]) do
|
||||
= link_to group_milestones_path(@group), title: 'Milestones' do
|
||||
= navbar_icon('milestones')
|
||||
%span
|
||||
Milestones
|
||||
= nav_link(path: 'groups#issues') do
|
||||
= link_to issues_group_path(@group), title: 'Issues' do
|
||||
= navbar_icon('issues')
|
||||
%span
|
||||
Issues
|
||||
- issues = IssuesFinder.new(current_user, group_id: @group.id, state: 'opened').execute
|
||||
%span.badge.count= number_with_delimiter(issues.count)
|
||||
= nav_link(path: 'groups#merge_requests') do
|
||||
= link_to merge_requests_group_path(@group), title: 'Merge Requests' do
|
||||
= navbar_icon('mr')
|
||||
%span
|
||||
Merge Requests
|
||||
- merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id, state: 'opened').execute
|
||||
%span.badge.count= number_with_delimiter(merge_requests.count)
|
||||
= nav_link(controller: [:group_members]) do
|
||||
= link_to group_group_members_path(@group), title: 'Members' do
|
||||
= navbar_icon('members')
|
||||
%span
|
||||
Members
|
||||
.fade-right
|
||||
|
|
|
@ -2,18 +2,15 @@
|
|||
.fade-left
|
||||
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
|
||||
= link_to profile_path, title: 'Profile Settings' do
|
||||
= icon('user fw')
|
||||
%span
|
||||
Profile
|
||||
= nav_link(controller: [:accounts, :two_factor_auths]) do
|
||||
= link_to profile_account_path, title: 'Account' do
|
||||
= icon('gear fw')
|
||||
%span
|
||||
Account
|
||||
- if current_application_settings.user_oauth_applications?
|
||||
= nav_link(controller: 'oauth/applications') do
|
||||
= link_to applications_profile_path, title: 'Applications' do
|
||||
= icon('cloud fw')
|
||||
%span
|
||||
Applications
|
||||
= nav_link(controller: :personal_access_tokens) do
|
||||
|
@ -23,35 +20,28 @@
|
|||
Personal Access Tokens
|
||||
= nav_link(controller: :emails) do
|
||||
= link_to profile_emails_path, title: 'Emails' do
|
||||
= icon('envelope-o fw')
|
||||
%span
|
||||
Emails
|
||||
- unless current_user.ldap_user?
|
||||
= nav_link(controller: :passwords) do
|
||||
= link_to edit_profile_password_path, title: 'Password' do
|
||||
= icon('lock fw')
|
||||
%span
|
||||
Password
|
||||
= nav_link(controller: :notifications) do
|
||||
= link_to profile_notifications_path, title: 'Notifications' do
|
||||
= icon('inbox fw')
|
||||
%span
|
||||
Notifications
|
||||
|
||||
= nav_link(controller: :keys) do
|
||||
= link_to profile_keys_path, title: 'SSH Keys' do
|
||||
= icon('key fw')
|
||||
%span
|
||||
SSH Keys
|
||||
= nav_link(controller: :preferences) do
|
||||
= link_to profile_preferences_path, title: 'Preferences' do
|
||||
-# TODO (rspeicher): Better icon?
|
||||
= icon('image fw')
|
||||
%span
|
||||
Preferences
|
||||
= nav_link(path: 'profiles#audit_log') do
|
||||
= link_to audit_log_profile_path, title: 'Audit Log' do
|
||||
= icon('history fw')
|
||||
%span
|
||||
Audit Log
|
||||
.fade-right
|
||||
|
|
|
@ -24,55 +24,41 @@
|
|||
.fade-left
|
||||
= nav_link(path: 'projects#show', html_options: {class: 'home'}) do
|
||||
= link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
|
||||
= navbar_icon('project')
|
||||
%span
|
||||
Project
|
||||
|
||||
= nav_link(path: 'projects#activity') do
|
||||
= link_to activity_project_path(@project), title: 'Activity', class: 'shortcuts-project-activity' do
|
||||
= navbar_icon('activity')
|
||||
%span
|
||||
Activity
|
||||
|
||||
- if project_nav_tab? :files
|
||||
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file commit commits compare repositories tags branches releases network)) do
|
||||
= link_to project_files_path(@project), title: 'Code', class: 'shortcuts-tree' do
|
||||
= icon('code fw')
|
||||
%span
|
||||
Code
|
||||
|
||||
- if project_nav_tab? :pipelines
|
||||
= nav_link(controller: :pipelines) do
|
||||
= link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
|
||||
= navbar_icon('pipelines')
|
||||
%span
|
||||
Pipelines
|
||||
|
||||
- if project_nav_tab? :container_registry
|
||||
= nav_link(controller: %w(container_registry)) do
|
||||
= link_to project_container_registry_path(@project), title: 'Container Registry', class: 'shortcuts-container-registry' do
|
||||
= icon('hdd-o fw')
|
||||
%span
|
||||
Registry
|
||||
|
||||
- if project_nav_tab? :graphs
|
||||
= nav_link(controller: %w(graphs)) do
|
||||
= link_to namespace_project_graph_path(@project.namespace, @project, current_ref), title: 'Graphs', class: 'shortcuts-graphs' do
|
||||
= icon('area-chart fw')
|
||||
%span
|
||||
Graphs
|
||||
|
||||
- if project_nav_tab? :milestones
|
||||
= nav_link(controller: :milestones) do
|
||||
= link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do
|
||||
= navbar_icon('milestones')
|
||||
%span
|
||||
Milestones
|
||||
|
||||
- if project_nav_tab? :issues
|
||||
= nav_link(controller: :issues) do
|
||||
= nav_link(controller: [:issues, :labels, :milestones]) do
|
||||
= link_to url_for_project_issues(@project, only_path: true), title: 'Issues', class: 'shortcuts-issues' do
|
||||
= navbar_icon('issues')
|
||||
%span
|
||||
Issues
|
||||
- if @project.default_issues_tracker?
|
||||
|
@ -81,29 +67,19 @@
|
|||
- if project_nav_tab? :merge_requests
|
||||
= nav_link(controller: :merge_requests) do
|
||||
= link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests', class: 'shortcuts-merge_requests' do
|
||||
= navbar_icon('mr')
|
||||
%span
|
||||
Merge Requests
|
||||
%span.badge.count.merge_counter= number_with_delimiter(@project.merge_requests.opened.count)
|
||||
|
||||
- if project_nav_tab? :labels
|
||||
= nav_link(controller: :labels) do
|
||||
= link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do
|
||||
= icon('tags fw')
|
||||
%span
|
||||
Labels
|
||||
|
||||
- if project_nav_tab? :wiki
|
||||
= nav_link(controller: :wikis) do
|
||||
= link_to get_project_wiki_path(@project), title: 'Wiki', class: 'shortcuts-wiki' do
|
||||
= navbar_icon('wiki')
|
||||
%span
|
||||
Wiki
|
||||
|
||||
- if project_nav_tab? :snippets
|
||||
= nav_link(controller: :snippets) do
|
||||
= link_to namespace_project_snippets_path(@project.namespace, @project), title: 'Snippets', class: 'shortcuts-snippets' do
|
||||
= icon('clipboard fw')
|
||||
%span
|
||||
Snippets
|
||||
|
||||
|
@ -129,5 +105,4 @@
|
|||
%li.hidden
|
||||
= link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do
|
||||
Commits
|
||||
|
||||
.fade-right
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
%li.notification-list-item
|
||||
%span.notification.fa.fa-holder.append-right-5
|
||||
- if setting.global?
|
||||
= notification_icon(current_user.notification_level)
|
||||
= notification_icon(current_user.global_notification_setting.level)
|
||||
- else
|
||||
= notification_icon(setting.level)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
%li.notification-list-item
|
||||
%span.notification.fa.fa-holder.append-right-5
|
||||
- if setting.global?
|
||||
= notification_icon(current_user.notification_level)
|
||||
= notification_icon(current_user.global_notification_setting.level)
|
||||
- else
|
||||
= notification_icon(setting.level)
|
||||
|
||||
|
|
|
@ -26,33 +26,7 @@
|
|||
= f.select :notification_email, @user.all_emails, { include_blank: false }, class: "select2"
|
||||
.form-group
|
||||
= f.label :notification_level, class: 'label-light'
|
||||
.radio
|
||||
= f.label :notification_level, value: :disabled do
|
||||
= f.radio_button :notification_level, :disabled
|
||||
.level-title
|
||||
Disabled
|
||||
%p You will not get any notifications via email
|
||||
|
||||
.radio
|
||||
= f.label :notification_level, value: :mention do
|
||||
= f.radio_button :notification_level, :mention
|
||||
.level-title
|
||||
On Mention
|
||||
%p You will receive notifications only for comments in which you were @mentioned
|
||||
|
||||
.radio
|
||||
= f.label :notification_level, value: :participating do
|
||||
= f.radio_button :notification_level, :participating
|
||||
.level-title
|
||||
Participating
|
||||
%p You will only receive notifications from related resources (e.g. from your commits or assigned issues)
|
||||
|
||||
.radio
|
||||
= f.label :notification_level, value: :watch do
|
||||
= f.radio_button :notification_level, :watch
|
||||
.level-title
|
||||
Watch
|
||||
%p You will receive notifications for any activity
|
||||
= notification_level_radio_buttons
|
||||
|
||||
.prepend-top-default
|
||||
= f.submit 'Update settings', class: "btn btn-create"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
%fieldset.builds-feature
|
||||
%h5.prepend-top-0
|
||||
Merge Requests
|
||||
.form-group
|
||||
.checkbox
|
||||
= f.label :only_allow_merge_if_build_succeeds do
|
||||
= f.check_box :only_allow_merge_if_build_succeeds
|
||||
%strong Only allow merge requests to be merged if the build succeeds
|
||||
.help-block
|
||||
Builds need to be configured to enable this feature.
|
||||
= link_to icon('question-circle'), help_page_path('workflow', 'merge_requests#only-allow-merge-requests-to-be-merged-if-the-build-succeeds')
|
|
@ -1,4 +1,5 @@
|
|||
- page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds'
|
||||
- header_title project_title(@project, "Builds", project_builds_path(@project))
|
||||
|
||||
.top-block.row-content-block.clearfix
|
||||
.pull-right
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
.content-block.build-header
|
||||
= ci_status_with_icon(@build.status)
|
||||
Build
|
||||
%strong ##{@build.id}
|
||||
for commit
|
||||
= link_to ci_status_path(@build.pipeline) do
|
||||
%strong= @build.pipeline.short_sha
|
||||
from
|
||||
= link_to namespace_project_commits_path(@project.namespace, @project, @build.ref) do
|
||||
%code
|
||||
= @build.ref
|
||||
- if @build.user
|
||||
= render "user"
|
||||
= time_ago_with_tooltip(@build.created_at)
|
||||
%button.btn.btn-default.pull-right.visible-xs-block.visible-sm-block.build-gutter-toggle.js-sidebar-build-toggle{ role: "button", type: "button" }
|
||||
= icon('angle-double-left')
|
|
@ -0,0 +1,93 @@
|
|||
%aside.right-sidebar.right-sidebar-expanded.build-sidebar.js-build-sidebar
|
||||
.block.build-sidebar-header.visible-xs-block.visible-sm-block.append-bottom-default
|
||||
Build
|
||||
%strong ##{@build.id}
|
||||
%a.gutter-toggle.pull-right.js-sidebar-build-toggle{ href: "#" }
|
||||
= icon('angle-double-right')
|
||||
- if @build.coverage
|
||||
.block.block-first
|
||||
.title
|
||||
Test coverage
|
||||
%p.build-detail-row
|
||||
#{@build.coverage}%
|
||||
|
||||
- if can?(current_user, :read_build, @project) && @build.artifacts?
|
||||
.block{ class: ("block-first" if !@build.coverage) }
|
||||
.title
|
||||
Build artifacts
|
||||
.btn-group.btn-group-justified{ role: :group }
|
||||
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do
|
||||
Download
|
||||
|
||||
- if @build.artifacts_metadata?
|
||||
= link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default' do
|
||||
Browse
|
||||
|
||||
.block{ class: ("block-first" if !@build.coverage && !(can?(current_user, :read_build, @project) && @build.artifacts?)) }
|
||||
.title
|
||||
Build details
|
||||
- if @build.retryable?
|
||||
= link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'pull-right', method: :post
|
||||
- if @build.merge_request
|
||||
%p.build-detail-row
|
||||
%span.build-light-text Merge Request:
|
||||
= link_to "#{@build.merge_request.to_reference}", merge_request_path(@build.merge_request)
|
||||
- if @build.duration
|
||||
%p.build-detail-row
|
||||
%span.build-light-text Duration:
|
||||
#{duration_in_words(@build.finished_at, @build.started_at)}
|
||||
- if @build.finished_at
|
||||
%p.build-detail-row
|
||||
%span.build-light-text Finished:
|
||||
#{time_ago_with_tooltip(@build.finished_at)}
|
||||
- if @build.erased_at
|
||||
%p.build-detail-row
|
||||
%span.build-light-text Erased:
|
||||
#{time_ago_with_tooltip(@build.erased_at)}
|
||||
%p.build-detail-row
|
||||
%span.build-light-text Runner:
|
||||
- if @build.runner && current_user && current_user.admin
|
||||
= link_to "##{@build.runner.id}", admin_runner_path(@build.runner.id)
|
||||
- elsif @build.runner
|
||||
\##{@build.runner.id}
|
||||
.btn-group.btn-group-justified{ role: :group }
|
||||
- if @build.has_trace?
|
||||
= link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default'
|
||||
- if @build.active?
|
||||
= link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-default', method: :post
|
||||
- if can?(current_user, :update_build, @project) && @build.erasable?
|
||||
= link_to erase_namespace_project_build_path(@project.namespace, @project, @build),
|
||||
class: "btn btn-sm btn-default", method: :post,
|
||||
data: { confirm: "Are you sure you want to erase this build?" } do
|
||||
Erase
|
||||
|
||||
- if @build.trigger_request
|
||||
.build-widget
|
||||
%h4.title
|
||||
Trigger
|
||||
|
||||
%p
|
||||
%span.build-light-text Token:
|
||||
#{@build.trigger_request.trigger.short_token}
|
||||
|
||||
- if @build.trigger_request.variables
|
||||
%p
|
||||
%span.build-light-text Variables:
|
||||
|
||||
%code
|
||||
- @build.trigger_request.variables.each do |key, value|
|
||||
#{key}=#{value}
|
||||
|
||||
.block
|
||||
.title
|
||||
Commit message
|
||||
%p.build-light-text.append-bottom-0
|
||||
#{@build.pipeline.git_commit_message}
|
||||
|
||||
- if @build.tags.any?
|
||||
.block
|
||||
.title
|
||||
Tags
|
||||
- @build.tag_list.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
|
@ -0,0 +1,4 @@
|
|||
by
|
||||
%a{ href: user_path(@build.user) }
|
||||
= image_tag avatar_icon(@build.user, 24), class: "avatar s24"
|
||||
%strong= @build.user.to_reference
|
|
@ -1,18 +1,10 @@
|
|||
- page_title "#{@build.name} (##{@build.id})", "Builds"
|
||||
- trace_with_state = @build.trace_with_state
|
||||
- header_title project_title(@project, "Builds", project_builds_path(@project))
|
||||
|
||||
.build-page
|
||||
.row-content-block.top-block
|
||||
Build ##{@build.id} for commit
|
||||
%strong.monospace= link_to @build.pipeline.short_sha, ci_status_path(@build.pipeline)
|
||||
from
|
||||
= link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
|
||||
- merge_request = @build.merge_request
|
||||
- if merge_request
|
||||
via
|
||||
= link_to "merge request #{merge_request.to_reference}", merge_request_path(merge_request)
|
||||
= render "header"
|
||||
|
||||
#up-build-trace
|
||||
- builds = @build.pipeline.builds.latest.to_a
|
||||
- if builds.size > 1
|
||||
%ul.nav-links.no-top.no-bottom
|
||||
|
@ -33,18 +25,6 @@
|
|||
·
|
||||
%i.fa.fa-warning
|
||||
This build was retried.
|
||||
|
||||
.row-content-block.middle-block
|
||||
.build-head
|
||||
.clearfix
|
||||
= ci_status_with_icon(@build.status)
|
||||
- if @build.duration
|
||||
%span
|
||||
%i.fa.fa-time
|
||||
#{duration_in_words(@build.finished_at, @build.started_at)}
|
||||
.pull-right
|
||||
#{time_ago_with_tooltip(@build.finished_at) if @build.finished_at}
|
||||
|
||||
- if @build.stuck?
|
||||
- unless @build.any_runners_online?
|
||||
.bs-callout.bs-callout-warning
|
||||
|
@ -64,158 +44,27 @@
|
|||
= link_to namespace_project_runners_path(@build.project.namespace, @build.project) do
|
||||
Runners page
|
||||
|
||||
.row.prepend-top-default
|
||||
.col-md-9
|
||||
.clearfix
|
||||
- if @build.active?
|
||||
.autoscroll-container
|
||||
%button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll
|
||||
.clearfix
|
||||
.prepend-top-default
|
||||
- if @build.active?
|
||||
.autoscroll-container
|
||||
%button.btn.btn-success.btn-sm#autoscroll-button{:type => "button", :data => {:state => 'disabled'}} enable autoscroll
|
||||
#js-build-scroll.scroll-controls
|
||||
= link_to '#up-build-trace', class: 'btn' do
|
||||
= link_to '#build-trace', class: 'btn' do
|
||||
%i.fa.fa-angle-up
|
||||
= link_to '#down-build-trace', class: 'btn' do
|
||||
%i.fa.fa-angle-down
|
||||
- if @build.erased?
|
||||
.erased.alert.alert-warning
|
||||
- erased_by = "by #{link_to @build.erased_by.name, user_path(@build.erased_by)}" if @build.erased_by
|
||||
Build has been erased #{erased_by.html_safe} #{time_ago_with_tooltip(@build.erased_at)}
|
||||
- else
|
||||
%pre.build-trace#build-trace
|
||||
%code.bash.js-build-output
|
||||
= icon("refresh spin", class: "js-build-refresh")
|
||||
|
||||
- if @build.erased?
|
||||
.erased.alert.alert-warning
|
||||
- erased_by = "by #{link_to @build.erased_by.name, user_path(@build.erased_by)}" if @build.erased_by
|
||||
Build has been erased #{erased_by.html_safe} #{time_ago_with_tooltip(@build.erased_at)}
|
||||
- else
|
||||
%pre.trace#build-trace
|
||||
%code.bash
|
||||
= preserve do
|
||||
= raw trace_with_state[:html]
|
||||
- if @build.active?
|
||||
%i{:class => "fa fa-refresh fa-spin"}
|
||||
#down-build-trace
|
||||
|
||||
%div#down-build-trace
|
||||
= render "sidebar"
|
||||
|
||||
.col-md-3
|
||||
- if @build.coverage
|
||||
.build-widget
|
||||
%h4.title
|
||||
Test coverage
|
||||
%h1 #{@build.coverage}%
|
||||
|
||||
- if can?(current_user, :read_build, @project) && @build.artifacts?
|
||||
.build-widget.artifacts
|
||||
%h4.title Build artifacts
|
||||
.center
|
||||
.btn-group{ role: :group }
|
||||
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary' do
|
||||
= icon('download')
|
||||
Download
|
||||
|
||||
- if @build.artifacts_metadata?
|
||||
= link_to browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary' do
|
||||
= icon('folder-open')
|
||||
Browse
|
||||
|
||||
.build-widget.build-controls
|
||||
%h4.title
|
||||
Build ##{@build.id}
|
||||
- if can?(current_user, :update_build, @project)
|
||||
.center
|
||||
.btn-group{ role: :group }
|
||||
- if @build.active?
|
||||
= link_to "Cancel", cancel_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-danger', method: :post
|
||||
- elsif @build.retryable?
|
||||
= link_to "Retry", retry_namespace_project_build_path(@project.namespace, @project, @build), class: 'btn btn-sm btn-primary', method: :post
|
||||
|
||||
- if @build.erasable?
|
||||
= link_to erase_namespace_project_build_path(@project.namespace, @project, @build),
|
||||
class: 'btn btn-sm btn-warning', method: :post,
|
||||
data: { confirm: 'Are you sure you want to erase this build?' } do
|
||||
= icon('eraser')
|
||||
Erase
|
||||
- if @build.has_trace?
|
||||
= link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build),
|
||||
class: 'btn btn-sm btn-success', target: '_blank'
|
||||
|
||||
.clearfix
|
||||
- if @build.duration
|
||||
%p
|
||||
%span.attr-name Duration:
|
||||
#{duration_in_words(@build.finished_at, @build.started_at)}
|
||||
%p
|
||||
%span.attr-name Created:
|
||||
#{time_ago_with_tooltip(@build.created_at)}
|
||||
- if @build.finished_at
|
||||
%p
|
||||
%span.attr-name Finished:
|
||||
#{time_ago_with_tooltip(@build.finished_at)}
|
||||
- if @build.erased_at
|
||||
%p
|
||||
%span.attr-name Erased:
|
||||
#{time_ago_with_tooltip(@build.erased_at)}
|
||||
%p
|
||||
%span.attr-name Runner:
|
||||
- if @build.runner && current_user && current_user.admin
|
||||
= link_to "##{@build.runner.id}", admin_runner_path(@build.runner.id)
|
||||
- elsif @build.runner
|
||||
\##{@build.runner.id}
|
||||
|
||||
- if @build.trigger_request
|
||||
.build-widget
|
||||
%h4.title
|
||||
Trigger
|
||||
|
||||
%p
|
||||
%span.attr-name Token:
|
||||
#{@build.trigger_request.trigger.short_token}
|
||||
|
||||
- if @build.trigger_request.variables
|
||||
%p
|
||||
%span.attr-name Variables:
|
||||
|
||||
%code
|
||||
- @build.trigger_request.variables.each do |key, value|
|
||||
#{key}=#{value}
|
||||
|
||||
.build-widget
|
||||
%h4.title
|
||||
Commit
|
||||
.pull-right
|
||||
%small
|
||||
= link_to @build.pipeline.short_sha, ci_status_path(@build.pipeline), class: "monospace"
|
||||
%p
|
||||
%span.attr-name Branch:
|
||||
= link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
|
||||
%p
|
||||
%span.attr-name Author:
|
||||
#{@build.pipeline.git_author_name}
|
||||
%p
|
||||
%span.attr-name Message:
|
||||
#{@build.pipeline.git_commit_message}
|
||||
|
||||
- if @build.tags.any?
|
||||
.build-widget
|
||||
%h4.title
|
||||
Tags
|
||||
- @build.tag_list.each do |tag|
|
||||
%span.label.label-primary
|
||||
= tag
|
||||
|
||||
- if @builds.present?
|
||||
.build-widget
|
||||
%h4.title #{pluralize(@builds.count(:id), "other build")} for
|
||||
= succeed ":" do
|
||||
= link_to @build.pipeline.short_sha, ci_status_path(@build.pipeline), class: "monospace"
|
||||
%table.table.builds
|
||||
- @builds.each_with_index do |build, i|
|
||||
%tr.build
|
||||
%td
|
||||
= ci_icon_for_status(build.status)
|
||||
%td
|
||||
= link_to namespace_project_build_path(@project.namespace, @project, build) do
|
||||
- if build.name
|
||||
= build.name
|
||||
- else
|
||||
%span ##{build.id}
|
||||
|
||||
%td.status= build.status
|
||||
|
||||
|
||||
:javascript
|
||||
new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{@build.status}", "#{trace_with_state[:state]}")
|
||||
:javascript
|
||||
new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{@build.status}", "#{trace_with_state[:state]}")
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
.form-group.branch
|
||||
= label_tag 'target_branch', target_label, class: 'control-label'
|
||||
.col-sm-10
|
||||
= select_tag "target_branch", grouped_options_refs, class: "select2 select2-sm js-target-branch"
|
||||
= select_tag "target_branch", project_branches, class: "select2 select2-sm js-target-branch"
|
||||
- if can?(current_user, :push_code, @project)
|
||||
.js-create-merge-request-container
|
||||
.checkbox
|
||||
|
|
|
@ -84,6 +84,8 @@
|
|||
%br
|
||||
%span.descr Enable Container Registry for this repository
|
||||
%hr
|
||||
= render 'merge_request_settings', f: f
|
||||
%hr
|
||||
= render 'builds_settings', f: f
|
||||
%hr
|
||||
%fieldset.features.append-bottom-default
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
%ul.nav-links.sub-nav
|
||||
%div{ class: (container_class) }
|
||||
- if project_nav_tab?(:issues) && !current_controller?(:merge_requests)
|
||||
= nav_link(controller: :issues) do
|
||||
= link_to url_for_project_issues(@project, only_path: true), title: 'Issues' do
|
||||
%span
|
||||
Issues
|
||||
|
||||
- if project_nav_tab?(:merge_requests) && current_controller?(:merge_requests)
|
||||
= nav_link(controller: :merge_requests) do
|
||||
= link_to namespace_project_merge_requests_path(@project.namespace, @project), title: 'Merge Requests' do
|
||||
%span
|
||||
Merge Requests
|
||||
|
||||
- if project_nav_tab? :labels
|
||||
= nav_link(controller: :labels) do
|
||||
= link_to namespace_project_labels_path(@project.namespace, @project), title: 'Labels' do
|
||||
%span
|
||||
Labels
|
||||
|
||||
- if project_nav_tab? :milestones
|
||||
= nav_link(controller: :milestones) do
|
||||
= link_to namespace_project_milestones_path(@project.namespace, @project), title: 'Milestones' do
|
||||
%span
|
||||
Milestones
|
|
@ -24,8 +24,6 @@
|
|||
MERGED
|
||||
- elsif merge_request.closed?
|
||||
CLOSED
|
||||
%li
|
||||
= render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
|
||||
- if @closed_by_merge_requests.present?
|
||||
%li
|
||||
= render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%li
|
||||
- sha = @project.repository.find_branch(branch).target
|
||||
- pipeline = @project.pipeline(sha, branch) if sha
|
||||
- if ci_copipelinemmit
|
||||
- if pipeline
|
||||
%span.related-branch-ci-status
|
||||
= render_pipeline_status(pipeline)
|
||||
%span.related-branch-info
|
||||
|
|
|
@ -4,7 +4,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://sear
|
|||
xml.link href: namespace_project_issues_url(@project.namespace, @project, format: :atom, private_token: current_user.try(:private_token)), rel: "self", type: "application/atom+xml"
|
||||
xml.link href: namespace_project_issues_url(@project.namespace, @project), rel: "alternate", type: "text/html"
|
||||
xml.id namespace_project_issues_url(@project.namespace, @project)
|
||||
xml.updated @issues.first.created_at.xmlschema if @issues.any?
|
||||
xml.updated @issues.first.created_at.xmlschema if @issues.reorder(nil).any?
|
||||
|
||||
xml << render(partial: 'issues/issue', collection: @issues) if @issues.any?
|
||||
xml << render(partial: 'issues/issue', collection: @issues) if @issues.reorder(nil).any?
|
||||
end
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
- @no_container = true
|
||||
- page_title "Issues"
|
||||
= render "projects/issues/head"
|
||||
|
||||
= content_for :meta_tags do
|
||||
- if current_user
|
||||
= auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
|
||||
|
||||
.top-area
|
||||
= render 'shared/issuable/nav', type: :issues
|
||||
.nav-controls
|
||||
- if current_user
|
||||
= link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
|
||||
= icon('rss')
|
||||
%span.icon-label
|
||||
Subscribe
|
||||
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
|
||||
- if can? current_user, :create_issue, @project
|
||||
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do
|
||||
New Issue
|
||||
%div{ class: (container_class) }
|
||||
.top-area
|
||||
= render 'shared/issuable/nav', type: :issues
|
||||
.nav-controls
|
||||
- if current_user
|
||||
= link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
|
||||
= icon('rss')
|
||||
%span.icon-label
|
||||
Subscribe
|
||||
= render 'shared/issuable/search_form', path: namespace_project_issues_path(@project.namespace, @project)
|
||||
- if can? current_user, :create_issue, @project
|
||||
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: @issuable_finder.assignee.try(:id), milestone_id: @issuable_finder.milestones.try(:first).try(:id) }), class: "btn btn-new", title: "New Issue", id: "new_issue_link" do
|
||||
New Issue
|
||||
|
||||
= render 'shared/issuable/filter', type: :issues
|
||||
= render 'shared/issuable/filter', type: :issues
|
||||
|
||||
.issues-holder
|
||||
= render "issues"
|
||||
.issues-holder
|
||||
= render "issues"
|
||||
|
|
|
@ -1,35 +1,38 @@
|
|||
- @no_container = true
|
||||
- page_title "Labels"
|
||||
- hide_class = ''
|
||||
= render "projects/issues/head"
|
||||
|
||||
.top-area
|
||||
.nav-text
|
||||
Labels can be applied to issues and merge requests.
|
||||
.nav-controls
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
= link_to new_namespace_project_label_path(@project.namespace, @project), class: "btn btn-new" do
|
||||
New label
|
||||
%div{ class: (container_class) }
|
||||
.top-area
|
||||
.nav-text
|
||||
Labels can be applied to issues and merge requests.
|
||||
.nav-controls
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
= link_to new_namespace_project_label_path(@project.namespace, @project), class: "btn btn-new" do
|
||||
New label
|
||||
|
||||
.labels
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
-# Only show it in the first page
|
||||
- hide = @project.labels.empty? || (params[:page].present? && params[:page] != '1')
|
||||
.prioritized-labels{ class: ('hide' if hide) }
|
||||
%h5 Prioritized Labels
|
||||
%ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_priorities_namespace_project_labels_path(@project.namespace, @project) }
|
||||
- if @prioritized_labels.present?
|
||||
= render @prioritized_labels
|
||||
- else
|
||||
%p.empty-message No prioritized labels yet
|
||||
.other-labels
|
||||
.labels
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
%h5{ class: ('hide' if hide) } Other Labels
|
||||
- if @labels.present?
|
||||
%ul.content-list.manage-labels-list.js-other-labels
|
||||
= render @labels
|
||||
= paginate @labels, theme: 'gitlab'
|
||||
- else
|
||||
.nothing-here-block
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
Create a label or #{link_to 'generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post}.
|
||||
- else
|
||||
No labels created
|
||||
-# Only show it in the first page
|
||||
- hide = @project.labels.empty? || (params[:page].present? && params[:page] != '1')
|
||||
.prioritized-labels{ class: ('hide' if hide) }
|
||||
%h5 Prioritized Labels
|
||||
%ul.content-list.manage-labels-list.js-prioritized-labels{ "data-url" => set_priorities_namespace_project_labels_path(@project.namespace, @project) }
|
||||
- if @prioritized_labels.present?
|
||||
= render @prioritized_labels
|
||||
- else
|
||||
%p.empty-message No prioritized labels yet
|
||||
.other-labels
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
%h5{ class: ('hide' if hide) } Other Labels
|
||||
- if @labels.present?
|
||||
%ul.content-list.manage-labels-list.js-other-labels
|
||||
= render @labels
|
||||
= paginate @labels, theme: 'gitlab'
|
||||
- else
|
||||
.nothing-here-block
|
||||
- if can?(current_user, :admin_label, @project)
|
||||
Create a label or #{link_to 'generate a default set of labels', generate_namespace_project_labels_path(@project.namespace, @project), method: :post}.
|
||||
- else
|
||||
No labels created
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
.top-tabs
|
||||
= link_to namespace_project_merge_requests_path(@project.namespace, @project), class: "tab #{'active' if current_page?(namespace_project_merge_requests_path(@project.namespace, @project)) }" do
|
||||
%span
|
||||
Merge Requests
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
- @no_container = true
|
||||
- page_title "Merge Requests"
|
||||
|
||||
= render "projects/issues/head"
|
||||
= render 'projects/last_push'
|
||||
|
||||
.top-area
|
||||
= render 'shared/issuable/nav', type: :merge_requests
|
||||
.nav-controls
|
||||
= render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
|
||||
%div{ class: (container_class) }
|
||||
.top-area
|
||||
= render 'shared/issuable/nav', type: :merge_requests
|
||||
.nav-controls
|
||||
= render 'shared/issuable/search_form', path: namespace_project_merge_requests_path(@project.namespace, @project)
|
||||
|
||||
- merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
|
||||
- if merge_project
|
||||
= link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do
|
||||
New Merge Request
|
||||
- merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
|
||||
- if merge_project
|
||||
= link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do
|
||||
New Merge Request
|
||||
|
||||
= render 'shared/issuable/filter', type: :merge_requests
|
||||
= render 'shared/issuable/filter', type: :merge_requests
|
||||
|
||||
.merge-requests-holder
|
||||
= render 'merge_requests'
|
||||
.merge-requests-holder
|
||||
= render 'merge_requests'
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
= render 'projects/merge_requests/widget/open/merge_when_build_succeeds'
|
||||
- elsif !@merge_request.can_be_merged_by?(current_user)
|
||||
= render 'projects/merge_requests/widget/open/not_allowed'
|
||||
- elsif !@merge_request.mergeable_ci_state? && @pipeline && @pipeline.failed?
|
||||
= render 'projects/merge_requests/widget/open/build_failed'
|
||||
- elsif @merge_request.can_be_merged?
|
||||
= render 'projects/merge_requests/widget/open/accept'
|
||||
|
||||
|
|
|
@ -10,19 +10,20 @@
|
|||
%span.btn-group
|
||||
= button_tag class: "btn btn-create js-merge-button merge_when_build_succeeds" do
|
||||
Merge When Build Succeeds
|
||||
= button_tag class: "btn btn-success dropdown-toggle", 'data-toggle' => 'dropdown' do
|
||||
%span.caret
|
||||
%span.sr-only
|
||||
Select Merge Moment
|
||||
%ul.js-merge-dropdown.dropdown-menu.dropdown-menu-right{ role: 'menu' }
|
||||
%li
|
||||
= link_to "#", class: "merge_when_build_succeeds" do
|
||||
= icon('check fw')
|
||||
Merge When Build Succeeds
|
||||
%li
|
||||
= link_to "#", class: "accept_merge_request" do
|
||||
= icon('warning fw')
|
||||
Merge Immediately
|
||||
- unless @project.only_allow_merge_if_build_succeeds?
|
||||
= button_tag class: "btn btn-success dropdown-toggle", 'data-toggle' => 'dropdown' do
|
||||
%span.caret
|
||||
%span.sr-only
|
||||
Select Merge Moment
|
||||
%ul.js-merge-dropdown.dropdown-menu.dropdown-menu-right{ role: 'menu' }
|
||||
%li
|
||||
= link_to "#", class: "merge_when_build_succeeds" do
|
||||
= icon('check fw')
|
||||
Merge When Build Succeeds
|
||||
%li
|
||||
= link_to "#", class: "accept_merge_request" do
|
||||
= icon('warning fw')
|
||||
Merge Immediately
|
||||
- else
|
||||
= f.button class: "btn btn-create btn-grouped js-merge-button accept_merge_request #{status_class}" do
|
||||
Accept Merge Request
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
%h4
|
||||
= icon('exclamation-triangle')
|
||||
The build for this merge request failed
|
||||
|
||||
%p
|
||||
Please retry the build or push a new commit to fix the failure.
|
|
@ -1,19 +1,22 @@
|
|||
- @no_container = true
|
||||
- page_title "Milestones"
|
||||
= render "projects/issues/head"
|
||||
|
||||
.top-area
|
||||
= render 'shared/milestones_filter'
|
||||
%div{ class: (container_class) }
|
||||
.top-area
|
||||
= render 'shared/milestones_filter'
|
||||
|
||||
.nav-controls
|
||||
- if can?(current_user, :admin_milestone, @project)
|
||||
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "btn btn-new", title: "New Milestone" do
|
||||
New Milestone
|
||||
.nav-controls
|
||||
- if can?(current_user, :admin_milestone, @project)
|
||||
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "btn btn-new", title: "New Milestone" do
|
||||
New Milestone
|
||||
|
||||
.milestones
|
||||
%ul.content-list
|
||||
= render @milestones
|
||||
.milestones
|
||||
%ul.content-list
|
||||
= render @milestones
|
||||
|
||||
- if @milestones.blank?
|
||||
%li
|
||||
.nothing-here-block No milestones to show
|
||||
- if @milestones.blank?
|
||||
%li
|
||||
.nothing-here-block No milestones to show
|
||||
|
||||
= paginate @milestones, theme: "gitlab"
|
||||
= paginate @milestones, theme: "gitlab"
|
||||
|
|
|
@ -5,11 +5,9 @@
|
|||
= link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
|
||||
%span
|
||||
Pipelines
|
||||
%span.badge.count.ci_counter= number_with_delimiter(@project.pipelines.running_or_pending.count)
|
||||
|
||||
- if project_nav_tab? :builds
|
||||
= nav_link(controller: %w(builds)) do
|
||||
= link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds' do
|
||||
%span
|
||||
Builds
|
||||
%span.badge.count.builds_counter= number_with_delimiter(@project.running_or_pending_build_count)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
- if @merge_requests.any?
|
||||
- if @merge_requests.reorder(nil).any?
|
||||
- @merge_requests.group_by(&:target_project).each do |group|
|
||||
.panel.panel-default.panel-small
|
||||
- project = group[0]
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>path-1</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<path d="M5,0 C4.448,0 4,0.448 4,1 L4,3 L1,3 C0.448,3 0,3.448 0,4 L0,9 C0,9.552 0.448,10 1,10 L5,10 L5,8 L11,8 L11,10 L15,10 C15.552,10 16,9.552 16,9 L16,4 C16,3.448 15.552,3 15,3 L12,3 L12,1 C12,0.448 11.552,0 11,0 L5,0 L5,0 L5,0 Z M6,2.5 C6,2.224 6.224,2 6.5,2 L9.5,2 C9.776,2 10,2.224 10,2.5 C10,2.776 9.776,3 9.5,3 L6.5,3 C6.224,3 6,2.776 6,2.5 L6,2.5 L6,2.5 Z M6,11 L10.001,11 L10.001,9 L6,9 L6,11 L6,11 L6,11 Z M11,11 L11,12 L5,12 L5,11 L1,11 C0.448,11 0,11.448 0,12 L0,15 C0,15.552 0.448,16 1,16 L15,16 C15.552,16 16,15.552 16,15 L16,12 C16,11.448 15.552,11 15,11 L11,11 L11,11 L11,11 Z" id="path-1"></path>
|
||||
</defs>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<mask id="mask-2" fill="white">
|
||||
<use xlink:href="#path-1"></use>
|
||||
</mask>
|
||||
<use id="path-1" fill="#D8D8D8" xlink:href="#path-1"></use>
|
||||
<g id="_activity" fill="#7E7D7D">
|
||||
<g id="Page-1">
|
||||
<g id="path-1">
|
||||
<path d="M5,0 C4.448,0 4,0.448 4,1 L4,3 L1,3 C0.448,3 0,3.448 0,4 L0,9 C0,9.552 0.448,10 1,10 L5,10 L5,8 L11,8 L11,10 L15,10 C15.552,10 16,9.552 16,9 L16,4 C16,3.448 15.552,3 15,3 L12,3 L12,1 C12,0.448 11.552,0 11,0 L5,0 L5,0 L5,0 L5,0 Z M6,2.5 C6,2.224 6.224,2 6.5,2 L9.5,2 C9.776,2 10,2.224 10,2.5 C10,2.776 9.776,3 9.5,3 L6.5,3 C6.224,3 6,2.776 6,2.5 L6,2.5 L6,2.5 L6,2.5 Z M6,11 L10.001,11 L10.001,9 L6,9 L6,11 L6,11 L6,11 L6,11 Z M11,11 L11,12 L5,12 L5,11 L1,11 C0.448,11 0,11.448 0,12 L0,15 C0,15.552 0.448,16 1,16 L15,16 C15.552,16 16,15.552 16,15 L16,12 C16,11.448 15.552,11 15,11 L11,11 L11,11 L11,11 L11,11 Z"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
@ -4,7 +4,7 @@
|
|||
- filter_placeholder = local_assigns.fetch(:filter_placeholder, 'Search labels')
|
||||
.dropdown-page-one
|
||||
= dropdown_title(title)
|
||||
= dropdown_filter(filter_placeholder)
|
||||
= dropdown_filter(filter_placeholder, search_id: "label-name")
|
||||
= dropdown_content
|
||||
- if @project && show_footer
|
||||
= dropdown_footer do
|
||||
|
|
|
@ -181,7 +181,7 @@ production: &base
|
|||
# host: registry.example.com
|
||||
# port: 5005
|
||||
# api_url: http://localhost:5000/ # internal address to the registry, will be used by GitLab to directly communicate with API
|
||||
# key_path: config/registry.key
|
||||
# key: config/registry.key
|
||||
# path: shared/registry
|
||||
# issuer: gitlab-issuer
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ Doorkeeper.configure do
|
|||
end
|
||||
|
||||
resource_owner_from_credentials do |routes|
|
||||
Gitlab::Auth.find_in_gitlab_or_ldap(params[:username], params[:password])
|
||||
Gitlab::Auth.find_with_user_password(params[:username], params[:password])
|
||||
end
|
||||
|
||||
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
|
||||
|
|
|
@ -96,13 +96,18 @@ if Gitlab::Metrics.enabled?
|
|||
config.instrument_instance_methods(const)
|
||||
end
|
||||
|
||||
# Instruments all Banzai filters
|
||||
Dir[Rails.root.join('lib', 'banzai', 'filter', '*.rb')].each do |file|
|
||||
klass = File.basename(file, File.extname(file)).camelize
|
||||
const = Banzai::Filter.const_get(klass)
|
||||
# Instruments all Banzai filters and reference parsers
|
||||
{
|
||||
Filter: Rails.root.join('lib', 'banzai', 'filter', '*.rb'),
|
||||
ReferenceParser: Rails.root.join('lib', 'banzai', 'reference_parser', '*.rb')
|
||||
}.each do |const_name, path|
|
||||
Dir[path].each do |file|
|
||||
klass = File.basename(file, File.extname(file)).camelize
|
||||
const = Banzai.const_get(const_name).const_get(klass)
|
||||
|
||||
config.instrument_methods(const)
|
||||
config.instrument_instance_methods(const)
|
||||
config.instrument_methods(const)
|
||||
config.instrument_instance_methods(const)
|
||||
end
|
||||
end
|
||||
|
||||
config.instrument_methods(Banzai::Renderer)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<%
|
||||
require "yaml"
|
||||
require "json"
|
||||
require_relative "lib/gitlab/redis"
|
||||
require_relative "lib/gitlab/redis" unless defined?(Gitlab::Redis)
|
||||
|
||||
rails_env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class InitSchema < ActiveRecord::Migration
|
||||
def up
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class RenameOwnerToCreatorForProject < ActiveRecord::Migration
|
||||
def change
|
||||
rename_column :projects, :owner_id, :creator_id
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class AddPublicToProject < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :projects, :public, :boolean, default: false, null: false
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class AddIssuesTrackerToProject < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :projects, :issues_tracker, :string, default: :gitlab, null: false
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class AddUserPermissions < ActiveRecord::Migration
|
||||
def up
|
||||
add_column :users, :can_create_group, :boolean, default: true, null: false
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class RemovePrivateFlagFromProject < ActiveRecord::Migration
|
||||
def up
|
||||
remove_column :projects, :private_flag
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class AddDescriptionToNamsespace < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :namespaces, :description, :string, default: '', null: false
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# rubocop:disable all
|
||||
class AddDescriptionToTeams < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :user_teams, :description, :string, default: '', null: false
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue