Commit 96e6cc9c authored by Valery Sizov's avatar Valery Sizov

Merge branch 'ce_upstream' into 'master'

CE upstream



See merge request !235
parents c8bbbdc7 9a7e3061
...@@ -23,6 +23,7 @@ config/gitlab.yml ...@@ -23,6 +23,7 @@ config/gitlab.yml
config/gitlab_ci.yml config/gitlab_ci.yml
config/initializers/rack_attack.rb config/initializers/rack_attack.rb
config/initializers/smtp_settings.rb config/initializers/smtp_settings.rb
config/initializers/relative_url.rb
config/resque.yml config/resque.yml
config/unicorn.rb config/unicorn.rb
config/secrets.yml config/secrets.yml
......
...@@ -5,12 +5,32 @@ v 8.6.0 (unreleased) ...@@ -5,12 +5,32 @@ v 8.6.0 (unreleased)
- Improve the formatting for the user page bio (Connor Shea) - Improve the formatting for the user page bio (Connor Shea)
- Fix issue when pushing to projects ending in .wiki - Fix issue when pushing to projects ending in .wiki
- Fix avatar stretching by providing a cropping feature (Johann Pardanaud) - Fix avatar stretching by providing a cropping feature (Johann Pardanaud)
- Don't load all of GitLab in mail_room
- Strip leading and trailing spaces in URL validator (evuez) - Strip leading and trailing spaces in URL validator (evuez)
- Return empty array instead of 404 when commit has no statuses in commit status API
- Update documentation to reflect Guest role not being enforced on internal projects - Update documentation to reflect Guest role not being enforced on internal projects
- Allow search for logged out users
- Don't show Issues/MRs from archived projects in Groups view
v 8.5.3
- Flush repository caches before renaming projects
v 8.5.2 v 8.5.2
- Fix sidebar overlapping content when screen width was below 1200px - Fix sidebar overlapping content when screen width was below 1200px
- Don't repeat labels listed on Labels tab
- Bring the "branded appearance" feature from EE to CE
- Fix error 500 when commenting on a commit - Fix error 500 when commenting on a commit
- Show days remaining instead of elapsed time for Milestone
- Fix broken icons on installations with relative URL (Artem Sidorenko)
- Fix issue where tag list wasn't refreshed after deleting a tag
- Fix import from gitlab.com (KazSawada)
- Improve implementation to check read access to forks and add pagination
- Don't show any "2FA required" message if it's not actually required
- Fix help keyboard shortcut on relative URL setups (Artem Sidorenko)
- Update Rails to 4.2.5.2
- Fix permissions for deprecated CI build status badge
- Don't show "Welcome to GitLab" when the search didn't return any projects
- Add Todos documentation
v 8.5.1 v 8.5.1
- Fix group projects styles - Fix group projects styles
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
- [Closing policy for issues and merge requests](#closing-policy-for-issues-and-merge-requests) - [Closing policy for issues and merge requests](#closing-policy-for-issues-and-merge-requests)
- [Helping others](#helping-others) - [Helping others](#helping-others)
- [I want to contribute!](#i-want-to-contribute) - [I want to contribute!](#i-want-to-contribute)
- [Implement design & UI elements](#implement-design-ui-elements)
- [Design reference](#design-reference)
- [UI development kit](#ui-development-kit)
- [Issue tracker](#issue-tracker) - [Issue tracker](#issue-tracker)
- [Feature proposals](#feature-proposals) - [Feature proposals](#feature-proposals)
- [Issue tracker guidelines](#issue-tracker-guidelines) - [Issue tracker guidelines](#issue-tracker-guidelines)
...@@ -83,6 +86,22 @@ GitLab. ...@@ -83,6 +86,22 @@ GitLab.
This was inspired by [an article by Kent C. Dodds][medium-up-for-grabs]. This was inspired by [an article by Kent C. Dodds][medium-up-for-grabs].
## Implement design & UI elements
### Design reference
The GitLab design reference can be found in the [gitlab-design] project.
The designs are made using Antetype (`.atype` files). You can use the
[free Antetype viewer (Mac OSX only)] or grab an exported PNG from the design
(the PNG is 1:1).
The current designs can be found in the [`gitlab1.atype` file].
### UI development kit
Implemented UI elements can also be found at https://gitlab.com/help/ui. Please
note that this page isn't comprehensive at this time.
## Issue tracker ## Issue tracker
To get support for your particular problem please use the To get support for your particular problem please use the
...@@ -299,13 +318,14 @@ to us than having a minimal commit log. The smaller an MR is the more likely it ...@@ -299,13 +318,14 @@ to us than having a minimal commit log. The smaller an MR is the more likely it
is it will be merged (quickly). After that you can send more MRs to enhance it. is it will be merged (quickly). After that you can send more MRs to enhance it.
For examples of feedback on merge requests please look at already For examples of feedback on merge requests please look at already
[closed merge requests][closed-merge-requests]. If you would like quick feedback on your merge [closed merge requests][closed-merge-requests]. If you would like quick feedback
request feel free to mention one of the Merge Marshalls of the [core team][core-team]. on your merge request feel free to mention one of the Merge Marshalls in the
[core team][core-team] or one of the
[Merge request coaches](https://about.gitlab.com/team/).
Please ensure that your merge request meets the contribution acceptance criteria. Please ensure that your merge request meets the contribution acceptance criteria.
When having your code reviewed and when reviewing merge requests please take the When having your code reviewed and when reviewing merge requests please take the
[thoughtbot code review guidelines](https://github.com/thoughtbot/guides/tree/master/code-review) [Thoughtbot code review guide] into account.
into account.
### Merge request description format ### Merge request description format
...@@ -473,3 +493,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor ...@@ -473,3 +493,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
[rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout [rss-source]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#source-code-layout
[rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming [rss-naming]: https://github.com/bbatsov/ruby-style-guide/blob/master/README.md#naming
[doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide" [doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide"
[gitlab-design]: https://gitlab.com/gitlab-org/gitlab-design
[free Antetype viewer (Mac OSX only)]: https://itunes.apple.com/us/app/antetype-viewer/id824152298?mt=12
[`gitlab1.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/gitlab1.atype/
[Thoughtbot code review guide]: https://github.com/thoughtbot/guides/tree/master/code-review
...@@ -6,9 +6,9 @@ gem 'rails-deprecated_sanitizer', '~> 1.0.3' ...@@ -6,9 +6,9 @@ gem 'rails-deprecated_sanitizer', '~> 1.0.3'
# Responders respond_to and respond_with # Responders respond_to and respond_with
gem 'responders', '~> 2.0' gem 'responders', '~> 2.0'
# Specify a sprockets version due to security issue # Specify a sprockets version due to increased performance
# See https://groups.google.com/forum/#!topic/rubyonrails-security/doAVp0YaTqY # See https://gitlab.com/gitlab-org/gitlab-ce/issues/6069
gem 'sprockets', '~> 2.12.3' gem 'sprockets', '~> 3.3.5'
# Default values for AR models # Default values for AR models
gem "default_value_for", "~> 3.0.0" gem "default_value_for", "~> 3.0.0"
......
...@@ -431,7 +431,6 @@ GEM ...@@ -431,7 +431,6 @@ GEM
railties (>= 4.0.1) railties (>= 4.0.1)
hashie (3.4.3) hashie (3.4.3)
highline (1.7.8) highline (1.7.8)
hike (1.2.3)
hipchat (1.5.2) hipchat (1.5.2)
httparty httparty
mimemagic mimemagic
...@@ -795,11 +794,8 @@ GEM ...@@ -795,11 +794,8 @@ GEM
spring (>= 0.9.1) spring (>= 0.9.1)
spring-commands-teaspoon (0.0.2) spring-commands-teaspoon (0.0.2)
spring (>= 0.9.1) spring (>= 0.9.1)
sprockets (2.12.4) sprockets (3.3.5)
hike (~> 1.2) rack (> 1, < 3)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
sprockets-rails (2.3.3) sprockets-rails (2.3.3)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
...@@ -831,7 +827,7 @@ GEM ...@@ -831,7 +827,7 @@ GEM
rack (~> 1.0) rack (~> 1.0)
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (1.4.1) tilt (2.0.2)
timfel-krb5-auth (0.8.3) timfel-krb5-auth (0.8.3)
tinder (1.10.1) tinder (1.10.1)
eventmachine (~> 1.0) eventmachine (~> 1.0)
...@@ -1057,7 +1053,7 @@ DEPENDENCIES ...@@ -1057,7 +1053,7 @@ DEPENDENCIES
spring-commands-rspec (~> 1.0.4) spring-commands-rspec (~> 1.0.4)
spring-commands-spinach (~> 1.0.0) spring-commands-spinach (~> 1.0.0)
spring-commands-teaspoon (~> 0.0.2) spring-commands-teaspoon (~> 0.0.2)
sprockets (~> 2.12.3) sprockets (~> 3.3.5)
state_machines-activerecord (~> 0.3.0) state_machines-activerecord (~> 0.3.0)
task_list (~> 1.0.2) task_list (~> 1.0.2)
teaspoon (~> 1.0.0) teaspoon (~> 1.0.0)
......
This diff is collapsed.
...@@ -4,4 +4,7 @@ ...@@ -4,4 +4,7 @@
require File.expand_path('../config/application', __FILE__) require File.expand_path('../config/application', __FILE__)
relative_url_conf = File.expand_path('../config/initializers/relative_url', __FILE__)
require relative_url_conf if File.exist?("#{relative_url_conf}.rb")
Gitlab::Application.load_tasks Gitlab::Application.load_tasks
# Quick Submit behavior # Quick Submit behavior
# #
# When an input field with the `js-quick-submit` class receives a "Meta+Enter" # When a child field of a form with a `js-quick-submit` class receives a
# (Mac) or "Ctrl+Enter" (Linux/Windows) key combination, its parent form is # "Meta+Enter" (Mac) or "Ctrl+Enter" (Linux/Windows) key combination, the form
# submitted. # is submitted.
# #
#= require extensions/jquery #= require extensions/jquery
# #
# ### Example Markup # ### Example Markup
# #
# <form action="/foo"> # <form action="/foo" class="js-quick-submit">
# <input type="text" class="js-quick-submit" /> # <input type="text" />
# <textarea class="js-quick-submit"></textarea> # <textarea></textarea>
# <input type="submit" value="Submit" />
# </form> # </form>
# #
isMac = ->
navigator.userAgent.match(/Macintosh/)
keyCodeIs = (e, keyCode) ->
return false if (e.originalEvent && e.originalEvent.repeat) || e.repeat
return e.keyCode == keyCode
$(document).on 'keydown.quick_submit', '.js-quick-submit', (e) -> $(document).on 'keydown.quick_submit', '.js-quick-submit', (e) ->
return if (e.originalEvent && e.originalEvent.repeat) || e.repeat return unless keyCodeIs(e, 13) # Enter
return unless e.keyCode == 13 # Enter
if navigator.userAgent.match(/Macintosh/) if isMac()
return unless (e.metaKey && !e.altKey && !e.ctrlKey && !e.shiftKey) return unless (e.metaKey && !e.altKey && !e.ctrlKey && !e.shiftKey)
else else
return unless (e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey) return unless (e.ctrlKey && !e.altKey && !e.metaKey && !e.shiftKey)
...@@ -27,3 +34,22 @@ $(document).on 'keydown.quick_submit', '.js-quick-submit', (e) -> ...@@ -27,3 +34,22 @@ $(document).on 'keydown.quick_submit', '.js-quick-submit', (e) ->
$form = $(e.target).closest('form') $form = $(e.target).closest('form')
$form.find('input[type=submit], button[type=submit]').disable() $form.find('input[type=submit], button[type=submit]').disable()
$form.submit() $form.submit()
# If the user tabs to a submit button on a `js-quick-submit` form, display a
# tooltip to let them know they could've used the hotkey
$(document).on 'keyup.quick_submit', '.js-quick-submit input[type=submit], .js-quick-submit button[type=submit]', (e) ->
return unless keyCodeIs(e, 9) # Tab
if isMac()
title = "You can also press &#8984;-Enter"
else
title = "You can also press Ctrl-Enter"
$this = $(@)
$this.tooltip(
container: 'body'
html: 'true'
placement: 'auto top'
title: title
trigger: 'manual'
).tooltip('show').one('blur', -> $this.tooltip('hide'))
@Dashboard =
init: ->
$(".projects-list-filter").off('keyup')
this.initSearch()
initSearch: ->
@timer = null
$(".projects-list-filter").on('keyup', ->
clearTimeout(@timer)
@timer = setTimeout(Dashboard.filterResults, 500)
)
filterResults: =>
$('.projects-list-holder').fadeTo(250, 0.5)
form = null
form = $("form#project-filter-form")
search = $(".projects-list-filter").val()
project_filter_url = form.attr('action') + '?' + form.serialize()
$.ajax
type: "GET"
url: form.attr('action')
data: form.serialize()
complete: ->
$('.projects-list-holder').fadeTo(250, 1)
success: (data) ->
$('.projects-list-holder').replaceWith(data.html)
# Change url so if user reload a page - search results are saved
history.replaceState {page: project_filter_url}, document.title, project_filter_url
dataType: "json"
...@@ -16,8 +16,6 @@ class Dispatcher ...@@ -16,8 +16,6 @@ class Dispatcher
shortcut_handler = null shortcut_handler = null
switch page switch page
when 'explore:projects:index', 'explore:projects:starred', 'explore:projects:trending'
Dashboard.init()
when 'projects:issues:index' when 'projects:issues:index'
Issues.init() Issues.init()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
...@@ -59,8 +57,6 @@ class Dispatcher ...@@ -59,8 +57,6 @@ class Dispatcher
when 'projects:merge_requests:index' when 'projects:merge_requests:index'
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
MergeRequests.init() MergeRequests.init()
when 'dashboard:show', 'root:show'
Dashboard.init()
when 'dashboard:activity' when 'dashboard:activity'
new Activities() new Activities()
when 'dashboard:projects:starred' when 'dashboard:projects:starred'
...@@ -107,9 +103,6 @@ class Dispatcher ...@@ -107,9 +103,6 @@ class Dispatcher
new ProjectFork() new ProjectFork()
when 'projects:artifacts:browse' when 'projects:artifacts:browse'
new BuildArtifacts() new BuildArtifacts()
when 'users:show'
new User()
new Activities()
when 'projects:group_links:index' when 'projects:group_links:index'
new GroupsSelect() new GroupsSelect()
when 'projects:mirrors:show', 'projects:mirrors:update' when 'projects:mirrors:show', 'projects:mirrors:update'
......
@Pager = @Pager =
init: (@limit = 0, preload, @disable = false) -> init: (@limit = 0, preload, @disable = false) ->
@loading = $(".loading") @loading = $('.loading').first()
if preload if preload
@offset = 0 @offset = 0
@getOld() @getOld()
......
...@@ -48,7 +48,7 @@ class @Profile ...@@ -48,7 +48,7 @@ class @Profile
$filename.text($filename.data('label')) $filename.text($filename.data('label'))
$('.js-upload-user-avatar').on 'click', -> $('.js-upload-user-avatar').on 'click', ->
$('.edit_user').submit() $('.edit-user').submit()
$avatarInput.on "change", -> $avatarInput.on "change", ->
form = $(this).closest("form") form = $(this).closest("form")
...@@ -62,4 +62,3 @@ class @Profile ...@@ -62,4 +62,3 @@ class @Profile
$modalCropImg.attr('src', event.target.result) $modalCropImg.attr('src', event.target.result)
fileData = reader.readAsDataURL(this.files[0]) fileData = reader.readAsDataURL(this.files[0])
class @ProjectsList @ProjectsList =
constructor: -> init: ->
$(".projects-list .js-expand").on 'click', (e) -> $(".projects-list-filter").off('keyup')
e.preventDefault() this.initSearch()
list = $(this).closest('.projects-list')
$("#filter_projects").on 'keyup', -> initSearch: ->
ProjectsList.filter_results($("#filter_projects")) @timer = null
$(".projects-list-filter").on('keyup', ->
clearTimeout(@timer)
@timer = setTimeout(ProjectsList.filterResults, 500)
)
@filter_results: ($element) -> filterResults: =>
terms = $element.val() $('.projects-list-holder').fadeTo(250, 0.5)
filterSelector = $element.data('filter-selector') || 'span.filter-title'
if not terms form = null
$(".projects-list li").show() form = $("form#project-filter-form")
$('.gl-pagination').show() search = $(".projects-list-filter").val()
else project_filter_url = form.attr('action') + '?' + form.serialize()
$(".projects-list li").each (index) ->
$this = $(this)
name = $this.find(filterSelector).text()
if name.toLowerCase().indexOf(terms.toLowerCase()) == -1 $.ajax
$this.hide() type: "GET"
else url: form.attr('action')
$this.show() data: form.serialize()
$('.gl-pagination').hide() complete: ->
$('.projects-list-holder').fadeTo(250, 1)
success: (data) ->
$('.projects-list-holder').replaceWith(data.html)
# Change url so if user reload a page - search results are saved
history.replaceState {page: project_filter_url}, document.title, project_filter_url
dataType: "json"
...@@ -13,8 +13,10 @@ class @Shortcuts ...@@ -13,8 +13,10 @@ class @Shortcuts
if $('#modal-shortcuts').length > 0 if $('#modal-shortcuts').length > 0
$('#modal-shortcuts').modal('show') $('#modal-shortcuts').modal('show')
else else
url = '/help/shortcuts'
url = gon.relative_url_root + url if gon.relative_url_root?
$.ajax( $.ajax(
url: '/help/shortcuts', url: url,
dataType: 'script', dataType: 'script',
success: (e) -> success: (e) ->
if location and location.length > 0 if location and location.length > 0
......
class @User class @User
constructor: -> constructor: (@opts) ->
$('.profile-groups-avatars').tooltip("placement": "top") $('.profile-groups-avatars').tooltip("placement": "top")
new ProjectsList()
@initTabs()
$('.hide-project-limit-message').on 'click', (e) -> $('.hide-project-limit-message').on 'click', (e) ->
path = '/' path = '/'
$.cookie('hide_project_limit_message', 'false', { path: path }) $.cookie('hide_project_limit_message', 'false', { path: path })
$(@).parents('.project-limit-message').remove() $(@).parents('.project-limit-message').remove()
e.preventDefault() e.preventDefault()
initTabs: ->
new UserTabs(
parentEl: '.user-profile'
action: @opts.action
)
# UserTabs
#
# Handles persisting and restoring the current tab selection and lazily-loading
# content on the Users#show page.
#
# ### Example Markup
#
# <ul class="nav-links">
# <li class="activity-tab active">
# <a data-action="activity" data-target="#activity" data-toggle="tab" href="/u/username">
# Activity
# </a>
# </li>
# <li class="groups-tab">
# <a data-action="groups" data-target="#groups" data-toggle="tab" href="/u/username/groups">
# Groups
# </a>
# </li>
# <li class="contributed-tab">
# <a data-action="contributed" data-target="#contributed" data-toggle="tab" href="/u/username/contributed">
# Contributed projects
# </a>
# </li>
# <li class="projects-tab">
# <a data-action="projects" data-target="#projects" data-toggle="tab" href="/u/username/projects">
# Personal projects
# </a>
# </li>
# </ul>
#
# <div class="tab-content">
# <div class="tab-pane" id="activity">
# Activity Content
# </div>
# <div class="tab-pane" id="groups">
# Groups Content
# </div>
# <div class="tab-pane" id="contributed">
# Contributed projects content
# </div>
# <div class="tab-pane" id="projects">
# Projects content
# </div>
# </div>
#
# <div class="loading-status">
# <div class="loading">
# Loading Animation
# </div>
# </div>
#
class @UserTabs
constructor: (opts) ->
{
@action = 'activity'
@defaultAction = 'activity'
@parentEl = $(document)
} = opts
# Make jQuery object if selector is provided
@parentEl = $(@parentEl) if typeof @parentEl is 'string'
# Store the `location` object, allowing for easier stubbing in tests
@_location = location
# Set tab states
@loaded = {}
for item in @parentEl.find('.nav-links a')
@loaded[$(item).attr 'data-action'] = false
# Actions
@actions = Object.keys @loaded
@bindEvents()
# Set active tab
@action = @defaultAction if @action is 'show'
@activateTab(@action)
bindEvents: ->
# Toggle event listeners
@parentEl
.off 'shown.bs.tab', '.nav-links a[data-toggle="tab"]'
.on 'shown.bs.tab', '.nav-links a[data-toggle="tab"]', @tabShown
tabShown: (event) =>
$target = $(event.target)
action = $target.data('action')
source = $target.attr('href')
@setTab(source, action)
@setCurrentAction(action)
activateTab: (action) ->
@parentEl.find(".nav-links .#{action}-tab a").tab('show')
setTab: (source, action) ->
return if @loaded[action] is true
if action is 'activity'
@loadActivities(source)
if action in ['groups', 'contributed', 'projects']
@loadTab(source, action)
loadTab: (source, action) ->
$.ajax
beforeSend: => @toggleLoading(true)
complete: => @toggleLoading(false)
dataType: 'json'
type: 'GET'
url: "#{source}.json"
success: (data) =>
tabSelector = 'div#' + action
@parentEl.find(tabSelector).html(data.html)
@loaded[action] = true
loadActivities: (source) ->
return if @loaded['activity'] is true
$calendarWrap = @parentEl.find('.user-calendar')
$calendarWrap.load($calendarWrap.data('href'))
new Activities()
@loaded['activity'] = true
toggleLoading: (status) ->
@parentEl.find('.loading-status .loading').toggle(status)
setCurrentAction: (action) ->
# Remove possible actions from URL
regExp = new RegExp('\/(' + @actions.join('|') + ')(\.html)?\/?$')
new_state = @_location.pathname
new_state = new_state.replace(/\/+$/, "") # remove trailing slashes
new_state = new_state.replace(regExp, '')
# Append the new action if we're on a tab other than 'activity'
unless action == @defaultAction
new_state += "/#{action}"
# Ensure parameters and hash come along for the ride
new_state += @_location.search + @_location.hash
history.replaceState {turbolinks: true, url: new_state}, document.title, new_state
new_state
...@@ -6,11 +6,15 @@ ...@@ -6,11 +6,15 @@
.cdark { color: #444 } .cdark { color: #444 }
/** COMMON CLASSES **/ /** COMMON CLASSES **/
.prepend-top-0 { margin-top: 0; }
.prepend-top-5 { margin-top: 5px; }
.prepend-top-10 { margin-top:10px } .prepend-top-10 { margin-top:10px }
.prepend-top-default { margin-top: $gl-padding !important; } .prepend-top-default { margin-top: $gl-padding !important; }
.prepend-top-20 { margin-top:20px } .prepend-top-20 { margin-top:20px }
.prepend-left-10 { margin-left:10px } .prepend-left-10 { margin-left:10px }
.prepend-left-default { margin-left:$gl-padding }
.prepend-left-20 { margin-left:20px } .prepend-left-20 { margin-left:20px }
.append-right-5 { margin-right: 5px }
.append-right-10 { margin-right:10px } .append-right-10 { margin-right:10px }
.append-right-20 { margin-right:20px } .append-right-20 { margin-right:20px }
.append-bottom-10 { margin-bottom:10px } .append-bottom-10 { margin-bottom:10px }
...@@ -314,7 +318,7 @@ table { ...@@ -314,7 +318,7 @@ table {
} }
.btn-sign-in { .btn-sign-in {
margin-top: 8px; margin-top: 10px;
text-shadow: none; text-shadow: none;
} }
......
...@@ -69,6 +69,10 @@ label { ...@@ -69,6 +69,10 @@ label {
&.inline-label { &.inline-label {
margin: 0; margin: 0;
} }
&.label-light {
font-weight: 600;
}
} }
.inline-input-group { .inline-input-group {
......
...@@ -79,6 +79,10 @@ ...@@ -79,6 +79,10 @@
> .dropdown { > .dropdown {
margin-right: $gl-padding-top; margin-right: $gl-padding-top;
display: inline-block; display: inline-block;
&:last-child {
margin-right: 0;
}
} }
> .btn { > .btn {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
transition-duration: .3s; transition-duration: .3s;
} }
.home { .gitlab-text-container-link {
z-index: 1; z-index: 1;
position: absolute; position: absolute;
left: 0px; left: 0px;
......
...@@ -167,12 +167,6 @@ ...@@ -167,12 +167,6 @@
} }
} }
.alert-help {
background-color: $background-color;
border: 1px solid $border-color;
color: $gl-gray;
}
// Typography ================================================================= // Typography =================================================================
.text-primary, .text-primary,
......
...@@ -196,7 +196,7 @@ body { ...@@ -196,7 +196,7 @@ body {
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
color: $gl-header-color; color: $gl-header-color;
font-weight: 500; font-weight: 600;
} }
/** CODE **/ /** CODE **/
......
...@@ -34,6 +34,7 @@ $error-exclamation-point: #E62958; ...@@ -34,6 +34,7 @@ $error-exclamation-point: #E62958;
$border-radius-default: 3px; $border-radius-default: 3px;
$list-title-color: #333333; $list-title-color: #333333;
$list-text-color: #555555; $list-text-color: #555555;
$profile-settings-link-color: $md-link-color;
/* /*
* Color schema * Color schema
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
max-width: none; max-width: none;
} }
.flash-container {
margin-bottom: $gl-padding;
}
.brand-holder { .brand-holder {
font-size: 18px; font-size: 18px;
line-height: 1.5; line-height: 1.5;
......
...@@ -39,7 +39,7 @@ li.milestone { ...@@ -39,7 +39,7 @@ li.milestone {
margin-right: 10px; margin-right: 10px;
} }
.time-elapsed { .remaining-days {
color: $orange-light; color: $orange-light;
} }
} }
......
.global-notifications-form .level-title { .notification-list-item {
font-size: 15px; line-height: 34px;
color: #333;
font-weight: bold;
} }
.notification-icon-holder { .notification {
width: 20px; position: relative;
float: left; top: 1px;
> .fa {
font-size: 18px;
}
} }
.ns-part { .ns-part {
color: $gl-primary; color: $gl-text-green;
} }
.ns-watch { .ns-watch {
......
...@@ -5,12 +5,25 @@ ...@@ -5,12 +5,25 @@
} }
} }
.profile-avatar-form-option { .profile-settings-sidebar {
hr { a {
margin: 10px 0; color: $profile-settings-link-color;
} }
} }
.avatar-image {
@media (min-width: $screen-sm-min) {
float: left;
margin-bottom: 0;
}
}
.avatar-file-name {
position: relative;
top: 2px;
display: inline-block;
}
.oauth-buttons { .oauth-buttons {
.btn-group { .btn-group {
margin-right: 10px; margin-right: 10px;
...@@ -79,6 +92,13 @@ ...@@ -79,6 +92,13 @@
margin: auto; margin: auto;
} }
.user-avatar-button {
.file-name {
display: inline-block;
padding-left: 10px;
}
}
.modal-profile-crop { .modal-profile-crop {
.modal-dialog { .modal-dialog {
width: 500px; width: 500px;
......
.search-results { .search-results {
.search-result-row { .search-result-row {
border-bottom: 1px solid #DDD; border-bottom: 1px solid $border-color;
padding-bottom: 15px; padding-bottom: $gl-padding;
margin-bottom: 15px; margin-bottom: $gl-padding;
&:last-child {
border-bottom: none;
}
} }
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
.badge.todos-pending-count { .badge.todos-pending-count {
background-color: #7f8fa4; background-color: #7f8fa4;
margin-top: -5px; margin-top: -5px;
font-weight: normal;
} }
} }
} }
......
...@@ -3,6 +3,7 @@ module Ci ...@@ -3,6 +3,7 @@ module Ci
before_action :project before_action :project
before_action :authorize_read_project!, except: [:badge] before_action :authorize_read_project!, except: [:badge]
before_action :no_cache, only: [:badge] before_action :no_cache, only: [:badge]
skip_before_action :authenticate_user!, only: [:badge]
protect_from_forgery protect_from_forgery
def show def show
...@@ -18,6 +19,7 @@ module Ci ...@@ -18,6 +19,7 @@ module Ci
# #
def badge def badge
return render_404 unless @project return render_404 unless @project
image = Ci::ImageForBuildService.new.execute(@project, params) image = Ci::ImageForBuildService.new.execute(@project, params)
send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml" send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml"
end end
......
...@@ -2,7 +2,7 @@ module IssuesAction ...@@ -2,7 +2,7 @@ module IssuesAction
extend ActiveSupport::Concern extend ActiveSupport::Concern
def issues def issues
@issues = get_issues_collection @issues = get_issues_collection.non_archived
@issues = @issues.page(params[:page]).per(ApplicationController::PER_PAGE) @issues = @issues.page(params[:page]).per(ApplicationController::PER_PAGE)
@issues = @issues.preload(:author, :project) @issues = @issues.preload(:author, :project)
......
...@@ -2,7 +2,7 @@ module MergeRequestsAction ...@@ -2,7 +2,7 @@ module MergeRequestsAction
extend ActiveSupport::Concern extend ActiveSupport::Concern
def merge_requests def merge_requests
@merge_requests = get_merge_requests_collection @merge_requests = get_merge_requests_collection.non_archived
@merge_requests = @merge_requests.page(params[:page]).per(ApplicationController::PER_PAGE) @merge_requests = @merge_requests.page(params[:page]).per(ApplicationController::PER_PAGE)
@merge_requests = @merge_requests.preload(:author, :target_project) @merge_requests = @merge_requests.preload(:author, :target_project)
......
...@@ -6,7 +6,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController ...@@ -6,7 +6,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
@projects = @projects.sort(@sort = params[:sort]) @projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace) @projects = @projects.includes(:namespace)
terms = params['filter_projects'] terms = params[:filter_projects]
if terms.present? if terms.present?
@projects = @projects.search(terms) @projects = @projects.search(terms)
...@@ -35,7 +35,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController ...@@ -35,7 +35,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
@projects = @projects.includes(:namespace, :forked_from_project, :tags) @projects = @projects.includes(:namespace, :forked_from_project, :tags)
@projects = @projects.sort(@sort = params[:sort]) @projects = @projects.sort(@sort = params[:sort])
terms = params['filter_projects'] terms = params[:filter_projects]
if terms.present? if terms.present?
@projects = @projects.search(terms) @projects = @projects.search(terms)
......
...@@ -6,20 +6,24 @@ class Projects::ForksController < Projects::ApplicationController ...@@ -6,20 +6,24 @@ class Projects::ForksController < Projects::ApplicationController
def index def index
base_query = project.forks.includes(:creator) base_query = project.forks.includes(:creator)
@forks = if current_user @forks = base_query.merge(ProjectsFinder.new.execute(current_user))
base_query.where('projects.visibility_level IN (?) OR projects.id IN (?)',
Project.public_and_internal_levels,
current_user.authorized_projects.pluck(:id))
else
base_query.where('projects.visibility_level = ?', Project::PUBLIC)
end
@total_forks_count = base_query.size @total_forks_count = base_query.size
@private_forks_count = @total_forks_count - @forks.size @private_forks_count = @total_forks_count - @forks.size
@public_forks_count = @total_forks_count - @private_forks_count @public_forks_count = @total_forks_count - @private_forks_count
@sort = params[:sort] || 'id_desc' @sort = params[:sort] || 'id_desc'
@forks = @forks.search(params[:filter_projects]) if params[:filter_projects].present?
@forks = @forks.order_by(@sort).page(params[:page]).per(PER_PAGE) @forks = @forks.order_by(@sort).page(params[:page]).per(PER_PAGE)
respond_to do |format|
format.html
format.json do
render json: {
html: view_to_html_string("projects/forks/_projects", projects: @forks)
}
end
end
end end
def new def new
......
...@@ -34,6 +34,11 @@ class Projects::TagsController < Projects::ApplicationController ...@@ -34,6 +34,11 @@ class Projects::TagsController < Projects::ApplicationController
def destroy def destroy
DeleteTagService.new(project, current_user).execute(params[:id]) DeleteTagService.new(project, current_user).execute(params[:id])
respond_to do |format|
format.html do
redirect_to namespace_project_tags_path(@project.namespace, @project) redirect_to namespace_project_tags_path(@project.namespace, @project)
end end
format.js
end
end
end end
class SearchController < ApplicationController class SearchController < ApplicationController
skip_before_action :authenticate_user!, :reject_blocked
include SearchHelper include SearchHelper
layout 'search' layout 'search'
......
...@@ -3,13 +3,6 @@ class UsersController < ApplicationController ...@@ -3,13 +3,6 @@ class UsersController < ApplicationController
before_action :set_user before_action :set_user
def show def show
@contributed_projects = contributed_projects.joined(@user).reject(&:forked?)
@projects = PersonalProjectsFinder.new(@user).execute(current_user)
@projects = @projects.page(params[:page]).per(PER_PAGE)
@groups = @user.groups.order_id_desc
respond_to do |format| respond_to do |format|
format.html format.html
...@@ -25,6 +18,45 @@ class UsersController < ApplicationController ...@@ -25,6 +18,45 @@ class UsersController < ApplicationController
end end
end end
def groups
load_groups
respond_to do |format|
format.html { render 'show' }
format.json do
render json: {
html: view_to_html_string("shared/groups/_list", groups: @groups)
}
end
end
end
def projects
load_projects
respond_to do |format|
format.html { render 'show' }
format.json do
render json: {
html: view_to_html_string("shared/projects/_list", projects: @projects, remote: true)
}
end
end
end
def contributed
load_contributed_projects
respond_to do |format|
format.html { render 'show' }
format.json do
render json: {
html: view_to_html_string("shared/projects/_list", projects: @contributed_projects)
}
end
end
end
def calendar def calendar
calendar = contributions_calendar calendar = contributions_calendar
@timestamps = calendar.timestamps @timestamps = calendar.timestamps
...@@ -69,6 +101,20 @@ class UsersController < ApplicationController ...@@ -69,6 +101,20 @@ class UsersController < ApplicationController
limit_recent(20, params[:offset]) limit_recent(20, params[:offset])
end end
def load_projects
@projects =
PersonalProjectsFinder.new(@user).execute(current_user)
.page(params[:page]).per(PER_PAGE)
end
def load_contributed_projects
@contributed_projects = contributed_projects.joined(@user)
end
def load_groups
@groups = @user.groups.order_id_desc
end
def projects_for_current_user def projects_for_current_user
ProjectsFinder.new.execute(current_user) ProjectsFinder.new.execute(current_user)
end end
......
...@@ -10,6 +10,15 @@ module IconsHelper ...@@ -10,6 +10,15 @@ module IconsHelper
options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options) options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options)
end end
def audit_icon(names, options = {})
case names
when "standard"
names = "key"
end
options.include?(:base) ? fa_stacked_icon(names, options) : fa_icon(names, options)
end
def spinner(text = nil, visible = false) def spinner(text = nil, visible = false)
css_class = 'loading' css_class = 'loading'
css_class << ' hide' unless visible css_class << ' hide' unless visible
......
...@@ -36,4 +36,14 @@ module MilestonesHelper ...@@ -36,4 +36,14 @@ module MilestonesHelper
options_from_collection_for_select(grouped_milestones, 'name', 'title', params[:milestone_title]) options_from_collection_for_select(grouped_milestones, 'name', 'title', params[:milestone_title])
end end
def milestone_remaining_days(milestone)
if milestone.expired?
content_tag(:strong, 'expired')
elsif milestone.due_date
days = milestone.remaining_days
content = content_tag(:strong, days)
content << " #{'day'.pluralize(days)} remaining"
end
end
end end
...@@ -38,6 +38,7 @@ module Issuable ...@@ -38,6 +38,7 @@ module Issuable
scope :join_project, -> { joins(:project) } scope :join_project, -> { joins(:project) }
scope :references_project, -> { references(:project) } scope :references_project, -> { references(:project) }
scope :non_archived, -> { join_project.merge(Project.non_archived) }
delegate :name, delegate :name,
:email, :email,
......
...@@ -27,6 +27,7 @@ class Label < ActiveRecord::Base ...@@ -27,6 +27,7 @@ class Label < ActiveRecord::Base
belongs_to :project belongs_to :project
has_many :label_links, dependent: :destroy has_many :label_links, dependent: :destroy
has_many :issues, through: :label_links, source: :target, source_type: 'Issue' has_many :issues, through: :label_links, source: :target, source_type: 'Issue'
has_many :merge_requests, through: :label_links, source: :target, source_type: 'MergeRequest'
validates :color, color: true, allow_blank: false validates :color, color: true, allow_blank: false
validates :project, presence: true, unless: Proc.new { |service| service.template? } validates :project, presence: true, unless: Proc.new { |service| service.template? }
...@@ -90,6 +91,10 @@ class Label < ActiveRecord::Base ...@@ -90,6 +91,10 @@ class Label < ActiveRecord::Base
issues.closed.count issues.closed.count
end end
def open_merge_requests_count
merge_requests.opened.count
end
def template? def template?
template template
end end
......
...@@ -111,17 +111,10 @@ class Milestone < ActiveRecord::Base ...@@ -111,17 +111,10 @@ class Milestone < ActiveRecord::Base
0 0
end end
# Returns the elapsed time (in percent) since the Milestone creation date until today. def remaining_days
# If the Milestone doesn't have a due_date then returns 0 since we can't calculate the elapsed time. return 0 if !due_date || expired?
# If the Milestone is overdue then it returns 100%.
def percent_time_used
return 0 unless due_date
return 100 if expired?
duration = ((created_at - due_date.to_datetime) / 1.day) (due_date - Date.today).to_i
days_elapsed = ((created_at - Time.now) / 1.day)
((days_elapsed.to_f / duration) * 100).floor
end end
def expires_at def expires_at
......
...@@ -314,7 +314,7 @@ class Project < ActiveRecord::Base ...@@ -314,7 +314,7 @@ class Project < ActiveRecord::Base
end end
def search_by_title(query) def search_by_title(query)
where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%") non_archived.where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%")
end end
def find_with_namespace(id) def find_with_namespace(id)
...@@ -817,6 +817,8 @@ class Project < ActiveRecord::Base ...@@ -817,6 +817,8 @@ class Project < ActiveRecord::Base
old_path_with_namespace = File.join(namespace_dir, path_was) old_path_with_namespace = File.join(namespace_dir, path_was)
new_path_with_namespace = File.join(namespace_dir, path) new_path_with_namespace = File.join(namespace_dir, path)
expire_caches_before_rename(old_path_with_namespace)
if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace) if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace)
# If repository moved successfully we need to send update instructions to users. # If repository moved successfully we need to send update instructions to users.
# However we cannot allow rollback since we moved repository # However we cannot allow rollback since we moved repository
...@@ -846,6 +848,22 @@ class Project < ActiveRecord::Base ...@@ -846,6 +848,22 @@ class Project < ActiveRecord::Base
Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.path) Gitlab::PagesTransfer.new.rename_project(path_was, path, namespace.path)
end end
# Expires various caches before a project is renamed.
def expire_caches_before_rename(old_path)
repo = Repository.new(old_path, self)
wiki = Repository.new("#{old_path}.wiki", self)
if repo.exists?
repo.expire_cache
repo.expire_emptiness_caches
end
if wiki.exists?
wiki.expire_cache
wiki.expire_emptiness_caches
end
end
def hook_attrs def hook_attrs
{ {
name: name, name: name,
......
...@@ -690,30 +690,38 @@ class Repository ...@@ -690,30 +690,38 @@ class Repository
end end
end end
def revert(user, commit, base_branch, target_branch = nil) def revert(user, commit, base_branch, revert_tree_id = nil)
source_sha = find_branch(base_branch).target source_sha = find_branch(base_branch).target
target_branch ||= base_branch revert_tree_id ||= check_revert_content(commit, base_branch)
args = [commit.id, source_sha]
args << { mainline: 1 } if commit.merge_commit?
revert_index = rugged.revert_commit(*args)
return false if revert_index.conflicts?
tree_id = revert_index.write_tree(rugged) return false unless revert_tree_id
return false unless diff_exists?(source_sha, tree_id)
commit_with_hooks(user, target_branch) do |ref| commit_with_hooks(user, base_branch) do |ref|
committer = user_to_committer(user) committer = user_to_committer(user)
source_sha = Rugged::Commit.create(rugged, source_sha = Rugged::Commit.create(rugged,
message: commit.revert_message, message: commit.revert_message,
author: committer, author: committer,
committer: committer, committer: committer,
tree: tree_id, tree: revert_tree_id,
parents: [rugged.lookup(source_sha)], parents: [rugged.lookup(source_sha)],
update_ref: ref) update_ref: ref)
end end
end end
def check_revert_content(commit, base_branch)
source_sha = find_branch(base_branch).target
args = [commit.id, source_sha]
args << { mainline: 1 } if commit.merge_commit?
revert_index = rugged.revert_commit(*args)
return false if revert_index.conflicts?
tree_id = revert_index.write_tree(rugged)
return false unless diff_exists?(source_sha, tree_id)
tree_id
end
def diff_exists?(sha1, sha2) def diff_exists?(sha1, sha2)
rugged.diff(sha1, sha2).size > 0 rugged.diff(sha1, sha2).size > 0
end end
......
...@@ -171,7 +171,7 @@ class User < ActiveRecord::Base ...@@ -171,7 +171,7 @@ class User < ActiveRecord::Base
validates :avatar_crop_x, :avatar_crop_y, :avatar_crop_size, validates :avatar_crop_x, :avatar_crop_y, :avatar_crop_size,
numericality: { only_integer: true }, numericality: { only_integer: true },
presence: true, presence: true,
if: ->(user) { user.avatar? } if: ->(user) { user.avatar? && user.avatar_changed? }
before_validation :generate_password, on: :create before_validation :generate_password, on: :create
before_validation :restricted_signup_domains, on: :create before_validation :restricted_signup_domains, on: :create
...@@ -402,7 +402,8 @@ class User < ActiveRecord::Base ...@@ -402,7 +402,8 @@ class User < ActiveRecord::Base
def namespace_uniq def namespace_uniq
# Return early if username already failed the first uniqueness validation # Return early if username already failed the first uniqueness validation
return if self.errors[:username].include?('has already been taken') return if self.errors.key?(:username) &&
self.errors[:username].include?('has already been taken')
namespace_name = self.username namespace_name = self.username
existing_namespace = Namespace.by_path(namespace_name) existing_namespace = Namespace.by_path(namespace_name)
......
...@@ -17,28 +17,28 @@ module Commits ...@@ -17,28 +17,28 @@ module Commits
def commit def commit
revert_into = @create_merge_request ? @commit.revert_branch_name : @target_branch revert_into = @create_merge_request ? @commit.revert_branch_name : @target_branch
revert_tree_id = repository.check_revert_content(@commit, @target_branch)
if @create_merge_request if revert_tree_id
# Temporary branch exists and contains the revert commit create_target_branch(revert_into) if @create_merge_request
return success if repository.find_branch(revert_into)
create_target_branch
end
unless repository.revert(current_user, @commit, revert_into) repository.revert(current_user, @commit, revert_into, revert_tree_id)
success
else
error_msg = "Sorry, we cannot revert this #{params[:revert_type_title]} automatically. error_msg = "Sorry, we cannot revert this #{params[:revert_type_title]} automatically.
It may have already been reverted, or a more recent commit may have updated some of its content." It may have already been reverted, or a more recent commit may have updated some of its content."
raise ReversionError, error_msg raise ReversionError, error_msg
end end
success
end end
private private
def create_target_branch def create_target_branch(new_branch)
# Temporary branch exists and contains the revert commit
return success if repository.find_branch(new_branch)
result = CreateBranchService.new(@project, current_user) result = CreateBranchService.new(@project, current_user)
.execute(@commit.revert_branch_name, @target_branch, source_project: @source_project) .execute(new_branch, @target_branch, source_project: @source_project)
if result[:status] == :error if result[:status] == :error
raise ReversionError, "There was an error creating the source branch: #{result[:message]}" raise ReversionError, "There was an error creating the source branch: #{result[:message]}"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
%h3.page-title Report abuse %h3.page-title Report abuse
%p Please use this form to report users who create spam issues, comments or behave inappropriately. %p Please use this form to report users who create spam issues, comments or behave inappropriately.
%hr %hr
= form_for @abuse_report, html: { class: 'form-horizontal js-requires-input'} do |f| = form_for @abuse_report, html: { class: 'form-horizontal js-quick-submit js-requires-input'} do |f|
= f.hidden_field :user_id = f.hidden_field :user_id
- if @abuse_report.errors.any? - if @abuse_report.errors.any?
.alert.alert-danger .alert.alert-danger
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
.form-group .form-group
= f.label :message, class: 'control-label' = f.label :message, class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_area :message, class: "form-control js-quick-submit", rows: 2, required: true, value: sanitize(@ref_url) = f.text_area :message, class: "form-control", rows: 2, required: true, value: sanitize(@ref_url)
.help-block .help-block
Explain the problem with this user. If appropriate, provide a link to the relevant issue or comment. Explain the problem with this user. If appropriate, provide a link to the relevant issue or comment.
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.js-broadcast-message-preview .js-broadcast-message-preview
= render_broadcast_message(@broadcast_message.message.presence || "Your message here") = render_broadcast_message(@broadcast_message.message.presence || "Your message here")
= form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form form-horizontal js-requires-input'} do |f| = form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form form-horizontal js-quick-submit js-requires-input'} do |f|
-if @broadcast_message.errors.any? -if @broadcast_message.errors.any?
.alert.alert-danger .alert.alert-danger
- @broadcast_message.errors.full_messages.each do |msg| - @broadcast_message.errors.full_messages.each do |msg|
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
.form-group .form-group
= f.label :message, class: 'control-label' = f.label :message, class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_area :message, class: "form-control js-quick-submit js-autosize", = f.text_area :message, class: "form-control js-autosize",
required: true, required: true,
data: { preview_path: preview_admin_broadcast_messages_path } data: { preview_path: preview_admin_broadcast_messages_path }
.form-group.js-toggle-colors-container .form-group.js-toggle-colors-container
......
.projects-list-holder = render 'shared/projects/list', projects: @projects, ci: true
= render 'shared/projects/list', projects: @projects, ci: true
:javascript
Dashboard.init()
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
- if @last_push - if @last_push
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
- if @projects.any? - if @projects.any? || params[:filter_projects]
= render 'projects' = render 'projects'
- else - else
= render "zero_authorized_projects" = render "zero_authorized_projects"
.pull-right.hidden-sm.hidden-xs - if current_user
- if current_user .dropdown
.dropdown.inline.append-right-10
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-globe = icon('globe')
%span.light Visibility: %span.light Visibility:
- if params[:visibility_level].present? - if params[:visibility_level].present?
= visibility_level_label(params[:visibility_level].to_i) = visibility_level_label(params[:visibility_level].to_i)
...@@ -19,10 +18,10 @@ ...@@ -19,10 +18,10 @@
= visibility_level_icon(level) = visibility_level_icon(level)
= visibility_level_label(level) = visibility_level_label(level)
- if @tags.present? - if @tags.present?
.dropdown.inline.append-right-10 .dropdown
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-tags = icon('tags')
%span.light Tags: %span.light Tags:
- if params[:tag].present? - if params[:tag].present?
= params[:tag] = params[:tag]
......
- if projects.any? = render 'shared/projects/list', projects: projects
.projects-list-holder
= render 'shared/projects/list', projects: projects
- else
.nothing-here-block
No such projects
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
.top-area .top-area
= render 'explore/projects/nav' = render 'explore/projects/nav'
.gray-content-block.second-block.clearfix .nav-controls
= render 'filter' = render 'filter'
= render 'projects', projects: @projects = render 'projects', projects: @projects
...@@ -8,5 +8,4 @@ ...@@ -8,5 +8,4 @@
= icon('plus') = icon('plus')
New Project New Project
.projects-list-holder = render 'shared/projects/list', projects: @projects, stars: false, skip_namespace: true
= render 'shared/projects/list', projects: @projects, projects_limit: 20, stars: false, skip_namespace: true
- user = member.user - user = member.user
- return unless user || member.invite? - return unless user || member.invite?
- show_roles = local_assigns.fetch(:show_roles, true)
%li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)} %li{class: "#{dom_class(member)} js-toggle-container", id: dom_id(member)}
%span{class: ("list-item-name" if show_controls)} %span{class: ("list-item-name" if show_controls)}
...@@ -28,7 +29,7 @@ ...@@ -28,7 +29,7 @@
= link_to resend_invite_group_group_member_path(@group, member), method: :post, class: "btn-xs btn", title: 'Resend invite' do = link_to resend_invite_group_group_member_path(@group, member), method: :post, class: "btn-xs btn", title: 'Resend invite' do
Resend invite Resend invite
- if should_user_see_group_roles?(current_user, @group) - if show_roles && should_user_see_group_roles?(current_user, @group)
%span.pull-right %span.pull-right
%strong.member-access-level= member.human_access %strong.member-access-level= member.human_access
- if show_controls - if show_controls
......
...@@ -8,18 +8,18 @@ ...@@ -8,18 +8,18 @@
This will create milestone in every selected project This will create milestone in every selected project
%hr %hr
= form_for @milestone, url: group_milestones_path(@group), html: { class: 'form-horizontal milestone-form gfm-form js-requires-input' } do |f| = form_for @milestone, url: group_milestones_path(@group), html: { class: 'form-horizontal milestone-form gfm-form js-quick-submit js-requires-input' } do |f|
.row .row
.col-md-6 .col-md-6
.form-group .form-group
= f.label :title, "Title", class: "control-label" = f.label :title, "Title", class: "control-label"
.col-sm-10 .col-sm-10
= f.text_field :title, maxlength: 255, class: "form-control js-quick-submit", required: true, autofocus: true = f.text_field :title, maxlength: 255, class: "form-control", required: true, autofocus: true
.form-group.milestone-description .form-group.milestone-description
= f.label :description, "Description", class: "control-label" = f.label :description, "Description", class: "control-label"
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview" } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview" } do
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control js-quick-submit' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
.clearfix .clearfix
.error-alert .error-alert
.form-group .form-group
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.header-logo .header-logo
%a#logo %a#logo
= brand_header_logo = brand_header_logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home' do = link_to root_path, class: 'gitlab-text-container-link', title: 'Dashboard', id: 'js-shortcuts-home' do
.gitlab-text-container .gitlab-text-container
%h3 GitLab %h3 GitLab
......
...@@ -5,11 +5,7 @@ ...@@ -5,11 +5,7 @@
-# Ideally this would be inside the head, but turbolinks only evaluates page-specific JS in the body. -# Ideally this would be inside the head, but turbolinks only evaluates page-specific JS in the body.
= yield :scripts_body_top = yield :scripts_body_top
- if current_user
= render "layouts/header/default", title: header_title = render "layouts/header/default", title: header_title
- else
= render "layouts/header/public", title: header_title
= render 'layouts/page', sidebar: sidebar = render 'layouts/page', sidebar: sidebar
= yield :scripts_body = yield :scripts_body
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.header-logo .header-logo
%a#logo %a#logo
= brand_header_logo = brand_header_logo
= link_to root_path, class: 'home', title: 'Dashboard', id: 'js-shortcuts-home' do = link_to root_path, class: 'gitlab-text-container-link', title: 'Dashboard', id: 'js-shortcuts-home' do
.gitlab-text-container .gitlab-text-container
%h3 GitLab %h3 GitLab
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
%li.visible-sm.visible-xs %li.visible-sm.visible-xs
= link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to search_path, title: 'Search', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('search') = icon('search')
- if current_user
- if session[:impersonator_id] - if session[:impersonator_id]
%li.impersonation %li.impersonation
= link_to stop_impersonation_admin_users_path, method: :delete, title: 'Stop Impersonation', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do = link_to stop_impersonation_admin_users_path, method: :delete, title: 'Stop Impersonation', data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
...@@ -37,6 +38,10 @@ ...@@ -37,6 +38,10 @@
%li %li
= link_to destroy_user_session_path, class: 'logout', method: :delete, title: 'Sign out', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to destroy_user_session_path, class: 'logout', method: :delete, title: 'Sign out', data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('sign-out') = icon('sign-out')
- else
.pull-right
= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success'
%h1.title= title %h1.title= title
......
%header.navbar.navbar-fixed-top.navbar-gitlab{ class: nav_header_class }
%div{ class: fluid_layout ? "container-fluid" : "container-fluid" }
.header-content
- unless current_controller?('sessions')
.pull-right
= link_to "Sign in", new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in btn-success'
%h1.title= title
= render 'shared/outdated_browser'
.table-holder %h5.prepend-top-0
%table.table#audits History of authentications
%thead
%tr
%th Action
%th When
%tbody %ul.well-list
- events.each do |event| - events.each do |event|
%tr %li
%td %span.description
%span = audit_icon(event.details[:with], class: "append-right-5")
Signed in with Signed in with
%b= event.details[:with] = event.details[:with]
authentication authentication
%td #{time_ago_in_words event.created_at} ago %span.pull-right
#{time_ago_in_words event.created_at} ago
= paginate events, theme: "gitlab" = paginate events, theme: "gitlab"
- page_title "Audit Log" - page_title "Audit Log"
- header_title page_title, audit_log_profile_path - header_title page_title, audit_log_profile_path
.alert.alert-help.prepend-top-default .row.prepend-top-default
History of authentications .col-lg-3.profile-settings-sidebar
%h3.prepend-top-0
.prepend-top-default = page_title
= render 'event_table', events: @events %p
This is a security log of important events involving your account.
.col-lg-9
= render 'event_table', events: @events
%li %li.notification-list-item
%span.notification.fa.fa-holder %span.notification.fa.fa-holder.append-right-5
- if notification.global? - if notification.global?
= notification_icon(@notification) = notification_icon(@notification)
- else - else
......
- page_title "Notifications" - page_title "Notifications"
- header_title page_title, profile_notifications_path - header_title page_title, profile_notifications_path
.prepend-top-default = form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications prepend-top-default' } do |f|
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-danger %div.alert.alert-danger
%ul %ul
...@@ -10,15 +9,22 @@ ...@@ -10,15 +9,22 @@
%li= msg %li= msg
= hidden_field_tag :notification_type, 'global' = hidden_field_tag :notification_type, 'global'
.row
.col-lg-3.profile-settings-sidebar
%h4
= page_title
%p
You can specify notification level per group or per project.
%p
By default, all projects and groups will use the global notifications setting.
.col-lg-9
%h5
Global notification settings
.form-group .form-group
= f.label :notification_email, class: "control-label" = f.label :notification_email, class: "label-light"
.col-sm-10 = f.select :notification_email, @user.all_emails, { include_blank: false }, class: "select2"
= f.select :notification_email, @user.all_emails, { include_blank: false }, class: "form-control"
.form-group .form-group
= f.label :notification_level, class: 'control-label' = f.label :notification_level, class: 'label-light'
.col-sm-10
.radio .radio
= f.label :notification_level, value: Notification::N_DISABLED do = f.label :notification_level, value: Notification::N_DISABLED do
= f.radio_button :notification_level, Notification::N_DISABLED = f.radio_button :notification_level, Notification::N_DISABLED
...@@ -47,27 +53,21 @@ ...@@ -47,27 +53,21 @@
Watch Watch
%p You will receive notifications for any activity %p You will receive notifications for any activity
.gray-content-block .prepend-top-default
= f.submit 'Save changes', class: "btn btn-create" = f.submit 'Update settings', class: "btn btn-create"
%hr
.row.all-notifications.prepend-top-default %h5
.col-md-6 Groups (#{@group_members.count})
%p %div
You can also specify notification level per group or per project.
%br
By default, all projects and groups will use the notification level set above.
%h4 Groups:
%ul.bordered-list %ul.bordered-list
- @group_members.each do |group_member| - @group_members.each do |group_member|
- notification = Notification.new(group_member) - notification = Notification.new(group_member)
= render 'settings', type: 'group', membership: group_member, notification: notification = render 'settings', type: 'group', membership: group_member, notification: notification
%h5
.col-md-6 Projects (#{@project_members.count})
%p %p.account-well
To specify the notification level per project of a group you belong to, To specify the notification level per project of a group you belong to, you need to be a member of the project itself, not only its group.
%br .append-bottom-default
you need to be a member of the project itself, not only its group.
%h4 Projects:
%ul.bordered-list %ul.bordered-list
- @project_members.each do |project_member| - @project_members.each do |project_member|
- notification = Notification.new(project_member) - notification = Notification.new(project_member)
......
- page_title 'Preferences' - page_title 'Preferences'
- header_title page_title, profile_preferences_path - header_title page_title, profile_preferences_path
.alert.alert-help.prepend-top-default = form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'row prepend-top-default js-preferences-form'} do |f|
These settings allow you to customize the appearance and behavior of the site. .col-lg-3.profile-settings-sidebar
They are saved with your account and will persist to any device you use to %h4.prepend-top-0
access the site.
= form_for @user, url: profile_preferences_path, remote: true, method: :put, html: {class: 'js-preferences-form form-horizontal'} do |f|
.panel.panel-default.application-theme
.panel-heading
Application theme Application theme
.panel-body %p
This setting allows you to customize the appearance of the site, ex. sidebar.
.col-lg-9.application-theme
- Gitlab::Themes.each do |theme| - Gitlab::Themes.each do |theme|
= label_tag do = label_tag do
.preview{class: theme.css_class} .preview{class: theme.css_class}
= f.radio_button :theme_id, theme.id = f.radio_button :theme_id, theme.id
= theme.name = theme.name
.col-sm-12
.panel.panel-default.syntax-theme %hr
.panel-heading .col-lg-3.profile-settings-sidebar
%h4.prepend-top-0
Syntax highlighting theme Syntax highlighting theme
.panel-body %p
This setting allow you to customize the appearance of the syntax.
.col-lg-9.syntax-theme
- Gitlab::ColorSchemes.each do |scheme| - Gitlab::ColorSchemes.each do |scheme|
= label_tag do = label_tag do
.preview= image_tag "#{scheme.css_class}-scheme-preview.png" .preview= image_tag "#{scheme.css_class}-scheme-preview.png"
= f.radio_button :color_scheme_id, scheme.id = f.radio_button :color_scheme_id, scheme.id
= scheme.name = scheme.name
.col-sm-12
.panel.panel-default %hr
.panel-heading .col-lg-3.profile-settings-sidebar
%h4.prepend-top-0
Behavior Behavior
.panel-body %p
This setting allows you to customize the behavior of the system layout and default views.
.col-lg-9
.form-group .form-group
= f.label :layout, class: 'control-label' do = f.label :layout, class: 'label-light' do
Layout width Layout width
.col-sm-10
= f.select :layout, layout_choices, {}, class: 'form-control' = f.select :layout, layout_choices, {}, class: 'form-control'
.help-block .help-block
Choose between fixed (max. 1200px) and fluid (100%) application layout. Choose between fixed (max. 1200px) and fluid (100%) application layout.
.form-group .form-group
= f.label :dashboard, class: 'control-label' do = f.label :dashboard, class: 'label-light' do
Default Dashboard Default Dashboard
= link_to('(?)', help_page_path('profile', 'preferences') + '#default-dashboard', target: '_blank') = link_to('(?)', help_page_path('profile', 'preferences') + '#default-dashboard', target: '_blank')
.col-sm-10
= f.select :dashboard, dashboard_choices, {}, class: 'form-control' = f.select :dashboard, dashboard_choices, {}, class: 'form-control'
.form-group .form-group
= f.label :project_view, class: 'control-label' do = f.label :project_view, class: 'label-light' do
Project view Project view
= link_to('(?)', help_page_path('profile', 'preferences') + '#default-project-view', target: '_blank') = link_to('(?)', help_page_path('profile', 'preferences') + '#default-project-view', target: '_blank')
.col-sm-10
= f.select :project_view, project_view_choices, {}, class: 'form-control' = f.select :project_view, project_view_choices, {}, class: 'form-control'
.help-block .help-block
Choose what content you want to see on a project's home page. Choose what content you want to see on a project's home page.
.panel-footer .form-group
= f.submit 'Save changes', class: 'btn btn-save' = f.submit 'Save changes', class: 'btn btn-save'
.alert.alert-help.prepend-top-default = form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit-user prepend-top-default" }, authenticity_token: true do |f|
This information will appear on your profile. = f.hidden_field :avatar_crop_x
- if current_user.ldap_user? = f.hidden_field :avatar_crop_y
Some options are unavailable for LDAP accounts = f.hidden_field :avatar_crop_size
.prepend-top-default
= form_for @user, url: profile_path, method: :put, html: { multipart: true, class: "edit_user form-horizontal" }, authenticity_token: true do |f|
-if @user.errors.any? -if @user.errors.any?
%div.alert.alert-danger %div.alert.alert-danger
%ul %ul
- @user.errors.full_messages.each do |msg| - @user.errors.full_messages.each do |msg|
%li= msg %li= msg
.row .row
.col-md-7 .col-lg-3.profile-settings-sidebar
%h4.prepend-top-0
Public Avatar
%p
- if @user.avatar?
You can change your avatar here
- if Gitlab.config.gravatar.enabled
or remove the current avatar to revert to #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
- else
You can upload an avatar here
- if Gitlab.config.gravatar.enabled
or change it at #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
.col-lg-9
.clearfix.avatar-image.append-bottom-default
= image_tag avatar_icon(@user, 160), alt: '', class: 'avatar s160'
%h5.prepend-top-0
Upload new avatar
.prepend-top-5.append-bottom-10
%a.btn.js-choose-user-avatar-button
Browse file...
%span.avatar-file-name.prepend-left-default.js-avatar-filename No file chosen
= f.file_field :avatar, class: "js-user-avatar-input hidden"
.help-block
The maximum file size allowed is 200KB.
- if @user.avatar?
%hr
= link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-gray"
%hr
.row
.col-lg-3.profile-settings-sidebar
%h4.prepend-top-0
Main settings
%p
This information will appear on your profile.
- if current_user.ldap_user?
Some options are unavailable for LDAP accounts
.col-lg-9
.form-group .form-group
= f.label :name, class: "control-label" = f.label :name, class: "label-light"
.col-sm-10
= f.text_field :name, class: "form-control", required: true = f.text_field :name, class: "form-control", required: true
%span.help-block Enter your name, so people you know can recognize you. %span.help-block Enter your name, so people you know can recognize you.
.form-group .form-group
= f.label :email, class: "control-label" = f.label :email, class: "label-light"
.col-sm-10
- if @user.ldap_user? && @user.ldap_email? - if @user.ldap_user? && @user.ldap_email?
= f.text_field :email, class: "form-control", required: true, readonly: true = f.text_field :email, class: "form-control", required: true, readonly: true
%span.help-block.light %span.help-block.light
...@@ -41,66 +72,30 @@ ...@@ -41,66 +72,30 @@
- else - else
%span.help-block We also use email for avatar detection if no avatar is uploaded. %span.help-block We also use email for avatar detection if no avatar is uploaded.
.form-group .form-group
= f.label :public_email, class: "control-label" = f.label :public_email, class: "label-light"
.col-sm-10
= f.select :public_email, options_for_select(@user.all_emails, selected: @user.public_email), {include_blank: 'Do not show on profile'}, class: "select2" = f.select :public_email, options_for_select(@user.all_emails, selected: @user.public_email), {include_blank: 'Do not show on profile'}, class: "select2"
%span.help-block This email will be displayed on your public profile. %span.help-block This email will be displayed on your public profile.
.form-group .form-group
= f.label :skype, class: "control-label" = f.label :skype, class: "label-light"
.col-sm-10= f.text_field :skype, class: "form-control" = f.text_field :skype, class: "form-control"
.form-group .form-group
= f.label :linkedin, class: "control-label" = f.label :linkedin, class: "label-light"
.col-sm-10= f.text_field :linkedin, class: "form-control" = f.text_field :linkedin, class: "form-control"
.form-group .form-group
= f.label :twitter, class: "control-label" = f.label :twitter, class: "label-light"
.col-sm-10= f.text_field :twitter, class: "form-control" = f.text_field :twitter, class: "form-control"
.form-group .form-group
= f.label :website_url, 'Website', class: "control-label" = f.label :website_url, 'Website', class: "label-light"
.col-sm-10= f.text_field :website_url, class: "form-control" = f.text_field :website_url, class: "form-control"
.form-group .form-group
= f.label :location, 'Location', class: "control-label" = f.label :location, 'Location', class: "label-light"
.col-sm-10= f.text_field :location, class: "form-control" = f.text_field :location, class: "form-control"
.form-group .form-group
= f.label :bio, class: "control-label" = f.label :bio, class: "label-light"
.col-sm-10
= f.text_area :bio, rows: 4, class: "form-control", maxlength: 250 = f.text_area :bio, rows: 4, class: "form-control", maxlength: 250
%span.help-block Tell us about yourself in fewer than 250 characters. %span.help-block Tell us about yourself in fewer than 250 characters.
.prepend-top-default.append-bottom-default
.col-md-5 = f.submit 'Update profile settings', class: "btn btn-success"
.light-well
= image_tag avatar_icon(@user, 160), alt: '', class: 'avatar s160'
.clearfix
.profile-avatar-form-option
%p.light
- if @user.avatar?
You can change your avatar here
- if Gitlab.config.gravatar.enabled
%br
or remove the current avatar to revert to #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
- else
You can upload an avatar here
- if Gitlab.config.gravatar.enabled
%br
or change it at #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
%hr
%a.choose-btn.btn.btn-sm.js-choose-user-avatar-button
%i.fa.fa-paperclip
%span Choose File ...
&nbsp;
%span.file_name.js-avatar-filename File name...
= f.file_field :avatar, class: "js-user-avatar-input hidden"
= f.hidden_field :avatar_crop_x
= f.hidden_field :avatar_crop_y
= f.hidden_field :avatar_crop_size
.light The maximum file size allowed is 200KB.
- if @user.avatar?
%hr
= link_to 'Remove avatar', profile_avatar_path, data: { confirm: "Avatar will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-sm remove-avatar"
.form-actions
= f.submit 'Save changes', class: "btn btn-success"
= link_to "Cancel", user_path(current_user), class: "btn btn-cancel" = link_to "Cancel", user_path(current_user), class: "btn btn-cancel"
.modal.modal-profile-crop .modal.modal-profile-crop
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
%span.editor-file-name %span.editor-file-name
\/ \/
= text_field_tag 'file_name', params[:file_name], placeholder: "File name", = text_field_tag 'file_name', params[:file_name], placeholder: "File name",
required: true, class: 'form-control new-file-name js-quick-submit' required: true, class: 'form-control new-file-name'
.pull-right .pull-right
= select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2' = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2'
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
%a.close{href: "#", "data-dismiss" => "modal"} × %a.close{href: "#", "data-dismiss" => "modal"} ×
%h3.page-title Create New Directory %h3.page-title Create New Directory
.modal-body .modal-body
= form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-requires-input' do = form_tag namespace_project_create_dir_path(@project.namespace, @project, @id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-quick-submit js-requires-input' do
.form-group .form-group
= label_tag :dir_name, 'Directory name', class: 'control-label' = label_tag :dir_name, 'Directory name', class: 'control-label'
.col-sm-10 .col-sm-10
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
%h3.page-title Delete #{@blob.name} %h3.page-title Delete #{@blob.name}
.modal-body .modal-body
= form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal js-replace-blob-form js-requires-input' do = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal js-replace-blob-form js-quick-submit js-requires-input' do
= render 'shared/new_commit_form', placeholder: "Delete #{@blob.name}" = render 'shared/new_commit_form', placeholder: "Delete #{@blob.name}"
.form-group .form-group
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
%a.close{href: "#", "data-dismiss" => "modal"} × %a.close{href: "#", "data-dismiss" => "modal"} ×
%h3.page-title #{title} %h3.page-title #{title}
.modal-body .modal-body
= form_tag form_path, method: method, class: 'js-upload-blob-form form-horizontal' do = form_tag form_path, method: method, class: 'js-quick-submit js-upload-blob-form form-horizontal' do
.dropzone .dropzone
.dropzone-previews.blob-upload-dropzone-previews .dropzone-previews.blob-upload-dropzone-previews
%p.dz-message.light %p.dz-message.light
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
= icon('eye') = icon('eye')
= editing_preview_title(@blob.name) = editing_preview_title(@blob.name)
= form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-requires-input js-edit-blob-form') do = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-quick-submit js-requires-input js-edit-blob-form') do
= render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data = render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data
= render 'shared/new_commit_form', placeholder: "Update #{@blob.name}" = render 'shared/new_commit_form', placeholder: "Update #{@blob.name}"
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
New File New File
.file-editor .file-editor
= form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal js-new-blob-form js-requires-input') do = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal js-new-blob-form js-quick-submit js-requires-input') do
= render 'projects/blob/editor', ref: @ref = render 'projects/blob/editor', ref: @ref
= render 'shared/new_commit_form', placeholder: "Add new file" = render 'shared/new_commit_form', placeholder: "Add new file"
......
= render 'shared/projects/list', projects: projects, use_creator_avatar: true,
forks: true, show_last_commit_as_description: true
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
== #{pluralize(@total_forks_count, 'fork')}: #{full_count_title} == #{pluralize(@total_forks_count, 'fork')}: #{full_count_title}
.nav-controls .nav-controls
= form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
= search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter project-filter-form-field form-control input-short', = search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter project-filter-form-field form-control input-short',
spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' } spellcheck: false, data: { 'filter-selector' => 'span.namespace-name' }
...@@ -38,18 +39,10 @@ ...@@ -38,18 +39,10 @@
Fork Fork
.projects-list-holder = render 'projects', projects: @forks
- if @forks.blank?
%ul.content-list
%li
.nothing-here-block No forks to show
- else
= render 'shared/projects/list', projects: @forks, use_creator_avatar: true,
forks: true, show_last_commit_as_description: true
- if @private_forks_count > 0 - if @private_forks_count > 0
%ul.projects-list.private-forks-notice .private-forks-notice
%li.project-row
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon') = icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(@private_forks_count, 'private fork') %strong= pluralize(@private_forks_count, 'private fork')
%span you have no access to. %span you have no access to.
= form_for [@project.namespace.becomes(Namespace), @project, @issue], html: { class: 'form-horizontal issue-form gfm-form js-requires-input' } do |f| = form_for [@project.namespace.becomes(Namespace), @project, @issue], html: { class: 'form-horizontal issue-form gfm-form js-quick-submit js-requires-input' } do |f|
= render 'shared/issuable/form', f: f, issuable: @issue = render 'shared/issuable/form', f: f, issuable: @issue
:javascript :javascript
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
%span.creator %span.creator
&middot; &middot;
by #{link_to_member(@project, @issue.author, size: 24)} by #{link_to_member(@project, @issue.author, size: 24)}
= '@' + @issue.author.username
&middot; &middot;
= time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago') = time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago')
......
= form_for [@project.namespace.becomes(Namespace), @project, @label], html: { class: 'form-horizontal label-form js-requires-input' } do |f| = form_for [@project.namespace.becomes(Namespace), @project, @label], html: { class: 'form-horizontal label-form js-quick-submit js-requires-input' } do |f|
-if @label.errors.any? -if @label.errors.any?
.row .row
.col-sm-offset-2.col-sm-10 .col-sm-offset-2.col-sm-10
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
.form-group .form-group
= f.label :title, class: 'control-label' = f.label :title, class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_field :title, class: "form-control js-quick-submit", required: true, autofocus: true = f.text_field :title, class: "form-control", required: true, autofocus: true
.form-group .form-group
= f.label :description, class: 'control-label' = f.label :description, class: 'control-label'
.col-sm-10 .col-sm-10
......
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
= render "shared/label_row", label: label = render "shared/label_row", label: label
.pull-right .pull-right
%strong.append-right-20
= link_to_label(label, type: :merge_request) do
= pluralize label.open_merge_requests_count, 'open merge request'
%strong.append-right-20 %strong.append-right-20
= link_to_label(label) do = link_to_label(label) do
= pluralize label.open_issues_count, 'open issue' = pluralize label.open_issues_count, 'open issue'
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
%span.creator %span.creator
&middot; &middot;
by #{link_to_member(@project, @merge_request.author, size: 24)} by #{link_to_member(@project, @merge_request.author, size: 24)}
= '@' + @merge_request.author.username
&middot; &middot;
= time_ago_with_tooltip(@merge_request.created_at) = time_ago_with_tooltip(@merge_request.created_at)
......
- status_class = @ci_commit ? " ci-#{@ci_commit.status}" : nil - status_class = @ci_commit ? " ci-#{@ci_commit.status}" : nil
= form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f| = form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-quick-submit js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token = hidden_field_tag :authenticity_token, form_authenticity_token
.accept-merge-holder.clearfix.js-toggle-container .accept-merge-holder.clearfix.js-toggle-container
.clearfix .clearfix
......
= form_for [@project.namespace.becomes(Namespace), @project, @milestone], html: {class: 'form-horizontal milestone-form gfm-form js-requires-input'} do |f| = form_for [@project.namespace.becomes(Namespace), @project, @milestone], html: {class: 'form-horizontal milestone-form gfm-form js-quick-submit js-requires-input'} do |f|
-if @milestone.errors.any? -if @milestone.errors.any?
.alert.alert-danger .alert.alert-danger
%ul %ul
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
.form-group .form-group
= f.label :title, "Title", class: "control-label" = f.label :title, "Title", class: "control-label"
.col-sm-10 .col-sm-10
= f.text_field :title, maxlength: 255, class: "form-control js-quick-submit", required: true, autofocus: true = f.text_field :title, maxlength: 255, class: "form-control", required: true, autofocus: true
.form-group.milestone-description .form-group.milestone-description
= f.label :description, "Description", class: "control-label" = f.label :description, "Description", class: "control-label"
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview" } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview" } do
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control js-quick-submit' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.clearfix .clearfix
.error-alert .error-alert
......
...@@ -60,9 +60,7 @@ ...@@ -60,9 +60,7 @@
%strong== #{@milestone.percent_complete}% %strong== #{@milestone.percent_complete}%
complete complete
%span.milestone-stat %span.milestone-stat
%span.time-elapsed %span.remaining-days= milestone_remaining_days(@milestone)
%strong== #{@milestone.percent_time_used}%
time elapsed
%span.pull-right.tab-issues-buttons %span.pull-right.tab-issues-buttons
- if can?(current_user, :create_issue, @project) - if can?(current_user, :create_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do = link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { milestone_id: @milestone.id }), class: "btn btn-grouped", title: "New Issue" do
......
.note-edit-form .note-edit-form
= form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true do |f| = form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true, class: 'js-quick-submit' do |f|
= note_target_fields(note) = note_target_fields(note)
= render layout: 'projects/md_preview', locals: { preview_class: 'md-preview' } do = render layout: 'projects/md_preview', locals: { preview_class: 'md-preview' } do
= render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text js-task-list-field js-quick-submit' = render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text js-task-list-field'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.note-form-actions .note-form-actions
......
= form_for [@project.namespace.becomes(Namespace), @project, @note], remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new_note js-new-note-form common-note-form gfm-form" }, authenticity_token: true do |f| = form_for [@project.namespace.becomes(Namespace), @project, @note], remote: true, html: { :'data-type' => 'json', multipart: true, id: nil, class: "new_note js-new-note-form js-quick-submit common-note-form gfm-form" }, authenticity_token: true do |f|
= hidden_field_tag :view, diff_view = hidden_field_tag :view, diff_view
= hidden_field_tag :line_type = hidden_field_tag :line_type
= note_target_fields(@note) = note_target_fields(@note)
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
= f.hidden_field :noteable_type = f.hidden_field :noteable_type
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
= render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text js-quick-submit' = render 'projects/zen', f: f, attr: :note, classes: 'note_text js-note-text'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.error-alert .error-alert
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
%strong #{@tag.name} %strong #{@tag.name}
.prepend-top-default .prepend-top-default
= form_for(@release, method: :put, url: namespace_project_tag_release_path(@project.namespace, @project, @tag.name), html: { class: 'form-horizontal gfm-form release-form' }) do |f| = form_for(@release, method: :put, url: namespace_project_tag_release_path(@project.namespace, @project, @tag.name), html: { class: 'form-horizontal gfm-form release-form js-quick-submit' }) do |f|
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
= render 'projects/zen', f: f, attr: :description, classes: 'description js-quick-submit form-control' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.error-alert .error-alert
.form-actions.prepend-top-default .form-actions.prepend-top-default
......
$('.js-totaltags-count').html("#{@repository.tags.size}");
- if @repository.tags.empty?
$('.tags').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000)
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
New Tag New Tag
%hr %hr
= form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal gfm-form tag-form js-requires-input" do = form_tag namespace_project_tags_path, method: :post, id: "new-tag-form", class: "form-horizontal gfm-form tag-form js-quick-submit js-requires-input" do
.form-group .form-group
= label_tag :tag_name, nil, class: 'control-label' = label_tag :tag_name, nil, class: 'control-label'
.col-sm-10 .col-sm-10
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
= label_tag :release_description, 'Release notes', class: 'control-label' = label_tag :release_description, 'Release notes', class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
= render 'projects/zen', attr: :release_description, classes: 'description js-quick-submit form-control' = render 'projects/zen', attr: :release_description, classes: 'description form-control'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.help-block Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page. .help-block Optionally, add release notes to the tag. They will be stored in the GitLab database and displayed on the tags page.
.form-actions .form-actions
......
= form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form gfm-form prepend-top-default' } do |f| = form_for [@project.namespace.becomes(Namespace), @project, @page], method: @page.persisted? ? :put : :post, html: { class: 'form-horizontal wiki-form gfm-form prepend-top-default js-quick-submit' } do |f|
-if @page.errors.any? -if @page.errors.any?
#error_explanation #error_explanation
.alert.alert-danger .alert.alert-danger
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
= f.label :content, class: 'control-label' = f.label :content, class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview" } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview" } do
= render 'projects/zen', f: f, attr: :content, classes: 'description form-control js-quick-submit' = render 'projects/zen', f: f, attr: :content, classes: 'description form-control'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.clearfix .clearfix
......
...@@ -11,4 +11,4 @@ ...@@ -11,4 +11,4 @@
= button_tag 'Search', class: "btn btn-primary" = button_tag 'Search', class: "btn btn-primary"
- unless params[:snippets].eql? 'true' - unless params[:snippets].eql? 'true'
%br %br
= render 'filter' = render 'filter' if current_user
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
.max-width-marker .max-width-marker
= text_area_tag 'commit_message', = text_area_tag 'commit_message',
(params[:commit_message] || local_assigns[:text]), (params[:commit_message] || local_assigns[:text]),
class: 'form-control js-commit-message js-quick-submit', placeholder: local_assigns[:placeholder], class: 'form-control js-commit-message', placeholder: local_assigns[:placeholder],
required: true, rows: (local_assigns[:rows] || 3), required: true, rows: (local_assigns[:rows] || 3),
id: "commit_message-#{nonce}" id: "commit_message-#{nonce}"
- if local_assigns[:hint] - if local_assigns[:hint]
......
- if groups.any?
%ul.content-list
- groups.each_with_index do |group, i|
= render "shared/groups/group", group: group
- else
%h3 No groups found
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
= f.label :title, class: 'control-label' = f.label :title, class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_field :title, maxlength: 255, autofocus: true, autocomplete: 'off', = f.text_field :title, maxlength: 255, autofocus: true, autocomplete: 'off',
class: 'form-control pad js-gfm-input js-quick-submit', required: true class: 'form-control pad js-gfm-input', required: true
- if issuable.is_a?(MergeRequest) - if issuable.is_a?(MergeRequest)
%p.help-block %p.help-block
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
= render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do = render layout: 'projects/md_preview', locals: { preview_class: "md-preview", referenced_users: true } do
= render 'projects/zen', f: f, attr: :description, = render 'projects/zen', f: f, attr: :description,
classes: 'description form-control js-quick-submit' classes: 'description form-control'
= render 'projects/notes/hints' = render 'projects/notes/hints'
.clearfix .clearfix
.error-alert .error-alert
......
...@@ -6,25 +6,19 @@ ...@@ -6,25 +6,19 @@
- ci = false unless local_assigns[:ci] == true - ci = false unless local_assigns[:ci] == true
- skip_namespace = false unless local_assigns[:skip_namespace] == true - skip_namespace = false unless local_assigns[:skip_namespace] == true
- show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true - show_last_commit_as_description = false unless local_assigns[:show_last_commit_as_description] == true
- remote = false unless local_assigns[:remote] == true
%ul.projects-list.content-list .projects-list-holder
- if projects.any? - if projects.any?
%ul.projects-list.content-list
- projects.each_with_index do |project, i| - projects.each_with_index do |project, i|
- css_class = (i >= projects_limit) ? 'hide' : nil - css_class = (i >= projects_limit) ? 'hide' : nil
= render "shared/projects/project", project: project, skip_namespace: skip_namespace, = render "shared/projects/project", project: project, skip_namespace: skip_namespace,
avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar, avatar: avatar, stars: stars, css_class: css_class, ci: ci, use_creator_avatar: use_creator_avatar,
forks: forks, show_last_commit_as_description: show_last_commit_as_description forks: forks, show_last_commit_as_description: show_last_commit_as_description
= paginate(projects, remote: remote, theme: "gitlab") if projects.respond_to? :total_pages
- if projects.size > projects_limit && projects.kind_of?(Array)
%li.bottom.center
.light
#{projects_limit} of #{pluralize(projects.count, 'project')} displayed.
= link_to '#', class: 'js-expand' do
Show all
= paginate projects, theme: "gitlab" if projects.respond_to? :total_pages
- else - else
%h3 No projects found .nothing-here-block No projects found
:javascript :javascript
new ProjectsList(); ProjectsList.init();
Dashboard.init();
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
= render 'shared/show_aside' = render 'shared/show_aside'
.cover-block .user-profile
.cover-block
.cover-controls .cover-controls
- if @user == current_user - if @user == current_user
= link_to profile_path, class: 'btn btn-gray' do = link_to profile_path, class: 'btn btn-gray' do
...@@ -69,56 +70,48 @@ ...@@ -69,56 +70,48 @@
= icon('map-marker') = icon('map-marker')
= @user.location = @user.location
%ul.nav-links.center %ul.nav-links.center.user-profile-nav
%li.active %li.activity-tab
= link_to "#activity", 'data-toggle' => 'tab' do = link_to user_calendar_activities_path, data: {target: 'div#activity', action: 'activity', toggle: 'tab'} do
Activity Activity
- if @groups.any? %li.groups-tab
%li = link_to user_groups_path, data: {target: 'div#groups', action: 'groups', toggle: 'tab'} do
= link_to "#groups", 'data-toggle' => 'tab' do
Groups Groups
- if @contributed_projects.present? %li.contributed-tab
%li = link_to user_contributed_projects_path, data: {target: 'div#contributed', action: 'contributed', toggle: 'tab'} do
= link_to "#contributed", 'data-toggle' => 'tab' do
Contributed projects Contributed projects
- if @projects.present? %li.projects-tab
%li = link_to user_projects_path, data: {target: 'div#projects', action: 'projects', toggle: 'tab'} do
= link_to "#personal", 'data-toggle' => 'tab' do
Personal projects Personal projects
%div{ class: container_class } %div{ class: container_class }
.tab-content .tab-content
.tab-pane.active#activity #activity.tab-pane
.gray-content-block.white.second-block .gray-content-block.white.second-block
%div{ class: container_class } %div{ class: container_class }
.user-calendar .user-calendar{data: {href: user_calendar_path}}
%h4.center.light %h4.center.light
%i.fa.fa-spinner.fa-spin %i.fa.fa-spinner.fa-spin
.user-calendar-activities .user-calendar-activities
.content_list{ data: {href: user_path} }
.content_list
= spinner = spinner
- if @groups.any? #groups.tab-pane
.tab-pane#groups - # This tab is always loaded via AJAX
%ul.content-list
- @groups.each do |group| #contributed.contributed-projects.tab-pane
= render 'shared/groups/group', group: group - # This tab is always loaded via AJAX
- if @contributed_projects.present? #projects.tab-pane
.tab-pane#contributed - # This tab is always loaded via AJAX
.contributed-projects
= render 'shared/projects/list', .loading-status
projects: @contributed_projects.sort_by(&:star_count).reverse, = spinner
projects_limit: 10, stars: true, avatar: true
- if @projects.present?
.tab-pane#personal
.personal-projects
= render 'shared/projects/list',
projects: @projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: true
:javascript :javascript
$(".user-calendar").load("#{user_calendar_path}"); var userProfile;
userProfile = new User({
action: "#{controller.action_name}"
});
...@@ -54,14 +54,6 @@ module Gitlab ...@@ -54,14 +54,6 @@ module Gitlab
config.action_view.sanitized_allowed_protocols = %w(smb) config.action_view.sanitized_allowed_protocols = %w(smb)
# Relative URL support
# WARNING: We recommend using an FQDN to host GitLab in a root path instead
# of using a relative URL.
# Documentation: http://doc.gitlab.com/ce/install/relative_url.html
# Uncomment and customize the following line to run in a non-root path
#
# config.relative_url_root = "/gitlab"
config.middleware.use Rack::Attack config.middleware.use Rack::Attack
# Allow access to GitLab API from other domains # Allow access to GitLab API from other domains
......
...@@ -276,10 +276,6 @@ Settings.gitlab_ci['builds_path'] = File.expand_path(Settings.gitlab_c ...@@ -276,10 +276,6 @@ Settings.gitlab_ci['builds_path'] = File.expand_path(Settings.gitlab_c
# #
Settings['incoming_email'] ||= Settingslogic.new({}) Settings['incoming_email'] ||= Settingslogic.new({})
Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled'].nil? Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled'].nil?
Settings.incoming_email['port'] = 143 if Settings.incoming_email['port'].nil?
Settings.incoming_email['ssl'] = false if Settings.incoming_email['ssl'].nil?
Settings.incoming_email['start_tls'] = false if Settings.incoming_email['start_tls'].nil?
Settings.incoming_email['mailbox'] = "inbox" if Settings.incoming_email['mailbox'].nil?
# #
# Build Artifacts # Build Artifacts
......
# Relative URL support
# WARNING: We recommend using an FQDN to host GitLab in a root path instead
# of using a relative URL.
# Documentation: http://doc.gitlab.com/ce/install/relative_url.html
# Copy this file to relative_url.rb and customize it to run in a non-root path
#
Rails.application.configure do
config.relative_url_root = "/gitlab"
end
:mailboxes: :mailboxes:
<% <%
require_relative 'config/environment.rb' require "yaml"
require "json"
if Gitlab::IncomingEmail.enabled? rails_env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
config = Gitlab::IncomingEmail.config
config_file = ENV["MAIL_ROOM_GITLAB_CONFIG_FILE"] || "config/gitlab.yml"
if File.exists?(config_file)
all_config = YAML.load_file(config_file)[rails_env]
config = all_config["incoming_email"] || {}
config['enabled'] = false if config['enabled'].nil?
config['port'] = 143 if config['port'].nil?
config['ssl'] = false if config['ssl'].nil?
config['start_tls'] = false if config['start_tls'].nil?
config['mailbox'] = "inbox" if config['mailbox'].nil?
if config['enabled'] && config['address'] && config['address'].include?('%{key}')
redis_config_file = "config/resque.yml" redis_config_file = "config/resque.yml"
redis_url = redis_url =
if File.exists?(redis_config_file) if File.exists?(redis_config_file)
YAML.load_file(redis_config_file)[Rails.env] YAML.load_file(redis_config_file)[rails_env]
else else
"redis://localhost:6379" "redis://localhost:6379"
end end
%> %>
- -
:host: <%= config.host.to_json %> :host: <%= config['host'].to_json %>
:port: <%= config.port.to_json %> :port: <%= config['port'].to_json %>
:ssl: <%= config.ssl.to_json %> :ssl: <%= config['ssl'].to_json %>
:start_tls: <%= config.start_tls.to_json %> :start_tls: <%= config['start_tls'].to_json %>
:email: <%= config.user.to_json %> :email: <%= config['user'].to_json %>
:password: <%= config.password.to_json %> :password: <%= config['password'].to_json %>
:name: <%= config.mailbox.to_json %> :name: <%= config['mailbox'].to_json %>
:delete_after_delivery: true :delete_after_delivery: true
...@@ -36,4 +48,5 @@ if Gitlab::IncomingEmail.enabled? ...@@ -36,4 +48,5 @@ if Gitlab::IncomingEmail.enabled?
:arbitration_options: :arbitration_options:
:redis_url: <%= redis_url.to_json %> :redis_url: <%= redis_url.to_json %>
:namespace: mail_room:gitlab :namespace: mail_room:gitlab
<% end %>
<% end %> <% end %>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment