Commit 8fe72af3 authored by James Lopez's avatar James Lopez

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into fix/contributions-forked-projects

parents 303e9eb5 912e6438
......@@ -24,7 +24,12 @@ before_script:
- bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"
- RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load db:migrate
stages:
- test
- notifications
spec:feature:
stage: test
script:
- RAILS_ENV=test bundle exec rake assets:precompile 2>/dev/null
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:feature
......@@ -33,6 +38,7 @@ spec:feature:
- mysql
spec:api:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:api
tags:
......@@ -40,6 +46,7 @@ spec:api:
- mysql
spec:models:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:models
tags:
......@@ -47,6 +54,7 @@ spec:models:
- mysql
spec:lib:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:lib
tags:
......@@ -54,6 +62,7 @@ spec:lib:
- mysql
spec:services:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:services
tags:
......@@ -61,6 +70,7 @@ spec:services:
- mysql
spec:benchmark:
stage: test
script:
- RAILS_ENV=test bundle exec rake spec:benchmark
tags:
......@@ -69,6 +79,7 @@ spec:benchmark:
allow_failure: true
spec:other:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spec:other
tags:
......@@ -76,6 +87,7 @@ spec:other:
- mysql
spinach:project:half:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:half
tags:
......@@ -83,6 +95,7 @@ spinach:project:half:
- mysql
spinach:project:rest:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:project:rest
tags:
......@@ -90,6 +103,7 @@ spinach:project:rest:
- mysql
spinach:other:
stage: test
script:
- RAILS_ENV=test SIMPLECOV=true bundle exec rake spinach:other
tags:
......@@ -97,6 +111,7 @@ spinach:other:
- mysql
teaspoon:
stage: test
script:
- RAILS_ENV=test bundle exec teaspoon
tags:
......@@ -104,6 +119,7 @@ teaspoon:
- mysql
rubocop:
stage: test
script:
- bundle exec rubocop
tags:
......@@ -111,6 +127,7 @@ rubocop:
- mysql
brakeman:
stage: test
script:
- bundle exec rake brakeman
tags:
......@@ -118,6 +135,7 @@ brakeman:
- mysql
flog:
stage: test
script:
- bundle exec rake flog
tags:
......@@ -125,6 +143,7 @@ flog:
- mysql
flay:
stage: test
script:
- bundle exec rake flay
tags:
......@@ -132,6 +151,7 @@ flay:
- mysql
bundler:audit:
stage: test
script:
- "bundle exec bundle-audit update"
- "bundle exec bundle-audit check"
......@@ -143,6 +163,7 @@ bundler:audit:
# Ruby 2.2 jobs
spec:feature:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -158,6 +179,7 @@ spec:feature:ruby22:
- mysql
spec:api:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -172,6 +194,7 @@ spec:api:ruby22:
- mysql
spec:models:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -186,6 +209,7 @@ spec:models:ruby22:
- mysql
spec:lib:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -200,6 +224,7 @@ spec:lib:ruby22:
- mysql
spec:services:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -214,6 +239,7 @@ spec:services:ruby22:
- mysql
spec:benchmark:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -229,6 +255,7 @@ spec:benchmark:ruby22:
allow_failure: true
spec:other:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -243,6 +270,7 @@ spec:other:ruby22:
- mysql
spinach:project:half:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -257,6 +285,7 @@ spinach:project:half:ruby22:
- mysql
spinach:project:rest:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -271,6 +300,7 @@ spinach:project:rest:ruby22:
- mysql
spinach:other:ruby22:
stage: test
image: ruby:2.2
only:
- master
......@@ -284,3 +314,14 @@ spinach:other:ruby22:
- ruby
- mysql
notify:slack:
stage: notifications
script:
- ./scripts/notify_slack.sh "#builds" "Build on \`$CI_BUILD_REF_NAME\` failed! Check <https://gitlab.com/gitlab-org/$(basename "$PWD")/commit/"$CI_BUILD_REF"/builds>"
when: on_failure
only:
- master@gitlab-org/gitlab-ce
- tags@gitlab-org/gitlab-ce
- master@gitlab-org/gitlab-ee
- tags@gitlab-org/gitlab-ee
\ No newline at end of file
......@@ -2,6 +2,33 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.6.0 (unreleased)
- Contributions to forked projects are included in calendar
- Improve the formatting for the user page bio (Connor Shea)
- Fix avatar stretching by providing a cropping feature (Johann Pardanaud)
- Strip leading and trailing spaces in URL validator (evuez)
- Update documentation to reflect Guest role not being enforced on internal projects
v 8.5.2
- Fix sidebar overlapping content when screen width was below 1200px
- Fix error 500 when commenting on a commit
v 8.5.1
- Fix group projects styles
- Show Crowd login tab when sign in is disabled and Crowd is enabled (Peter Hudec)
- Fix a set of small UI glitches in project, profile, and wiki pages
- Restrict permissions on public/uploads
- Fix the merge request side-by-side view after loading diff results
- Fix the look of tooltip for the "Revert" button
- Add when the Builds & Runners API changes got introduced
- Fix error 500 on some merged merge requests
- Fix an issue causing the content of the issuable sidebar to disappear
- Fix error 500 when trying to mark an already done todo as "done"
- Fix an issue where MRs weren't sortable
- Issues can now be dragged & dropped into empty milestone lists. This is also
possible with MRs
- Changed padding & background color for highlighted notes
- Re-add the newrelic_rpm gem which was removed without any deprecation or warning (Stan Hu)
- Update sentry-raven gem to 0.15.6
- Add build coverage in project's builds page (Steffen Köhler)
v 8.5.0
- Fix duplicate "me" in tooltip of the "thumbsup" awards Emoji (Stan Hu)
......@@ -82,6 +109,9 @@ v 8.5.0
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
- Add Todos
v 8.4.5
- No CE-specific changes
v 8.4.4
- Update omniauth-saml gem to 1.4.2
- Prevent long-running backup tasks from timing out the database connection
......
......@@ -34,7 +34,7 @@ source edition, and GitLab Enterprise Edition (EE) which is our commercial
edition. Throughout this guide you will see references to CE and EE for
abbreviation.
If you have read this guide and want to know how the GitLab [core-team][]
If you have read this guide and want to know how the GitLab [core team][core-team]
operates please see [the GitLab contributing process](PROCESS.md).
## Contributor license agreement
......@@ -68,10 +68,10 @@ for audiences of all ages.
## Helping others
Please help other GitLab users when you can. The channels people will reach out
on can be found on the [getting help page][].
on can be found on the [getting help page][getting-help].
Sign up for the mailing list, answer GitLab questions on StackOverflow or
respond in the IRC channel. You can also sign up on [CodeTriage][] to help with
respond in the IRC channel. You can also sign up on [CodeTriage][codetriage] to help with
the remaining issues on the GitHub issue tracker.
## I want to contribute!
......@@ -115,7 +115,7 @@ For feature proposals for EE, open an issue on the
In order to help track the feature proposals, we have created a
[`feature proposal`][fpl] label. For the time being, users that are not members
of the project cannot add labels. You can instead ask one of the [core team][]
of the project cannot add labels. You can instead ask one of the [core team][core-team]
members to add the label `feature proposal` to the issue.
Please keep feature proposals as small and simple as possible, complex ones
......@@ -299,8 +299,8 @@ 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.
For examples of feedback on merge requests please look at already
[closed merge requests][]. If you would like quick feedback on your merge
request feel free to mention one of the Merge Marshalls of the [core team][].
[closed merge requests][closed-merge-requests]. If you would like quick feedback on your merge
request feel free to mention one of the Merge Marshalls of the [core team][core-team].
Please ensure that your merge request meets the contribution acceptance criteria.
When having your code reviewed and when reviewing merge requests please take the
......@@ -369,7 +369,7 @@ Like all merge requests the target should be master so all bugfixes are in maste
## Definition of done
If you contribute to GitLab please know that changes involve more than just
code. We have the following [definition of done][]. Please ensure you support
code. We have the following [definition of done][definition-of-done]. Please ensure you support
the feature you contribute through all of these steps.
1. Description explaining the relevancy (see following item)
......@@ -448,12 +448,12 @@ when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior can be
reported by emailing `contact@gitlab.com`.
This Code of Conduct is adapted from the [Contributor Covenant][], version 1.1.0,
This Code of Conduct is adapted from the [Contributor Covenant][contributor-covenant], version 1.1.0,
available at [http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/).
[core-team]: https://about.gitlab.com/core-team/
[getting help page]: https://about.gitlab.com/getting-help/
[Codetriage]: http://www.codetriage.com/gitlabhq/gitlabhq
[getting-help]: https://about.gitlab.com/getting-help/
[codetriage]: http://www.codetriage.com/gitlabhq/gitlabhq
[up-for-grabs]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=up-for-grabs
[medium-up-for-grabs]: https://medium.com/@kentcdodds/first-timers-only-78281ea47455
[ce-tracker]: https://gitlab.com/gitlab-org/gitlab-ce/issues
......@@ -467,9 +467,9 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
[github-mr-tracker]: https://github.com/gitlabhq/gitlabhq/pulls
[gdk]: https://gitlab.com/gitlab-org/gitlab-development-kit
[git-squash]: https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits
[closed merge requests]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed
[definition of done]: http://guide.agilealliance.org/guide/definition-of-done.html
[Contributor Covenant]: http://contributor-covenant.org
[closed-merge-requests]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed
[definition-of-done]: http://guide.agilealliance.org/guide/definition-of-done.html
[contributor-covenant]: http://contributor-covenant.org
[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
[doc-styleguide]: doc/development/doc_styleguide.md "Documentation styleguide"
......@@ -77,6 +77,9 @@ gem "haml-rails", '~> 0.9.0'
# Files attachments
gem "carrierwave", '~> 0.9.0'
# Image editing
gem "mini_magick", '~> 4.4.0'
# Drag and Drop UI
gem 'dropzonejs-rails', '~> 0.7.1'
......@@ -218,7 +221,7 @@ gem 'virtus', '~> 1.0.1'
gem 'net-ssh', '~> 3.0.1'
# Sentry integration
gem 'sentry-raven'
gem 'sentry-raven', '~> 0.15'
# Metrics
group :metrics do
......@@ -303,6 +306,8 @@ group :production do
gem "gitlab_meta", '7.0'
end
gem "newrelic_rpm", '~> 3.14'
gem 'octokit', '~> 3.8.0'
gem "mail_room", "~> 0.6.1"
......
......@@ -468,6 +468,7 @@ GEM
method_source (0.8.2)
mime-types (1.25.1)
mimemagic (0.3.0)
mini_magick (4.4.0)
mini_portile2 (2.0.0)
minitest (5.7.0)
mousetrap-rails (1.4.6)
......@@ -479,6 +480,7 @@ GEM
net-ldap (0.12.1)
net-ssh (3.0.1)
netrc (0.11.0)
newrelic_rpm (3.14.1.311)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
nprogress-rails (0.1.6.7)
......@@ -722,7 +724,7 @@ GEM
activesupport (>= 3.1, < 4.3)
select2-rails (3.5.9.3)
thor (~> 0.14)
sentry-raven (0.15.4)
sentry-raven (0.15.6)
faraday (>= 0.7.6)
settingslogic (2.0.9)
sexp_processor (4.6.0)
......@@ -954,11 +956,13 @@ DEPENDENCIES
loofah (~> 2.0.3)
mail_room (~> 0.6.1)
method_source (~> 0.8)
mini_magick (~> 4.4.0)
minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6)
mysql2 (~> 0.3.16)
nested_form (~> 0.3.2)
net-ssh (~> 3.0.1)
newrelic_rpm (~> 3.14)
nokogiri (~> 1.6.7, >= 1.6.7.2)
nprogress-rails (~> 0.1.6.7)
oauth2 (~> 1.0.0)
......@@ -1007,7 +1011,7 @@ DEPENDENCIES
sdoc (~> 0.3.20)
seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9)
sentry-raven
sentry-raven (~> 0.15)
settingslogic (~> 2.0.9)
sham_rack
shoulda-matchers (~> 2.8.0)
......
class @Activities
constructor: ->
Pager.init 20, true
$(".event-filter a").bind "click", (event) =>
$(".event-filter-link").on "click", (event) =>
event.preventDefault()
@toggleFilter($(event.currentTarget))
@reloadActivities()
......@@ -12,18 +12,10 @@ class @Activities
toggleFilter: (sender) ->
sender.closest('li').toggleClass "active"
$('.event-filter .active').removeClass "active"
event_filters = $.cookie("event_filter")
filter = sender.attr("id").split("_")[0]
if event_filters
event_filters = event_filters.split(",")
else
event_filters = new Array()
$.cookie "event_filter", (if event_filters isnt filter then filter else ""), { path: '/' }
index = event_filters.indexOf(filter)
if index is -1
event_filters.push filter
else
event_filters.splice index, 1
$.cookie "event_filter", event_filters.join(","), { path: '/' }
if event_filters isnt filter
sender.closest('li').toggleClass "active"
......@@ -44,6 +44,7 @@
#= require jquery.nicescroll
#= require_tree .
#= require fuzzaldrin-plus
#= require cropper.js
window.slugify = (text) ->
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
......@@ -210,7 +211,7 @@ $ ->
$this = $(this)
$this.attr 'value', $this.val()
return
$(document)
.off 'keyup', 'input[type="search"]'
.on 'keyup', 'input[type="search"]' , (e) ->
......@@ -253,7 +254,7 @@ $ ->
$('.page-with-sidebar')
.removeClass('right-sidebar-collapsed')
.addClass('right-sidebar-expanded')
$.cookie("collapsed_gutter",
$.cookie("collapsed_gutter",
$('.right-sidebar')
.hasClass('right-sidebar-collapsed'), { path: '/' })
......
......@@ -16,11 +16,11 @@ class @Autosave
try
text = window.localStorage.getItem @key
catch
catch e
return
@field.val text if text?.length > 0
@field.trigger "input"
@field.trigger "input"
save: ->
return unless window.localStorage?
......@@ -35,5 +35,5 @@ class @Autosave
reset: ->
return unless window.localStorage?
try
try
window.localStorage.removeItem @key
class @AwardsHandler
constructor: (@post_emoji_url, @noteable_type, @noteable_id, @aliases) ->
$(".add-award").click (event)->
$(".add-award").click (event) =>
event.stopPropagation()
event.preventDefault()
$(".emoji-menu").show()
$("#emoji_search").focus()
@showEmojiMenu()
$("html").on 'click', (event) ->
if !$(event.target).closest(".emoji-menu").length
......@@ -14,6 +14,16 @@ class @AwardsHandler
@renderFrequentlyUsedBlock()
@setupSearch()
showEmojiMenu: ->
if $(".emoji-menu").length
$(".emoji-menu").show()
$("#emoji_search").focus()
else
$.get "/emojis", (response) ->
$(".add-award").after response
$(".emoji-menu").show()
$("#emoji_search").focus()
addAward: (emoji) ->
emoji = @normilizeEmojiName(emoji)
@postEmoji emoji, =>
......
......@@ -76,6 +76,8 @@ class Dispatcher
shortcut_handler = new ShortcutsNavigation()
when 'projects:show'
shortcut_handler = new ShortcutsNavigation()
new TreeView() if $('#tree-slider').length
when 'groups:show'
new Activities()
shortcut_handler = new ShortcutsNavigation()
......@@ -88,10 +90,11 @@ class Dispatcher
when 'groups:new', 'groups:edit', 'admin:groups:edit', 'admin:groups:new'
new GroupAvatar()
when 'projects:tree:show'
shortcut_handler = new ShortcutsNavigation()
new TreeView()
when 'projects:find_file:show'
shortcut_handler = true
when 'projects:blob:show'
when 'projects:blob:show', 'projects:blame:show'
new LineHighlighter()
shortcut_handler = new ShortcutsNavigation()
when 'projects:labels:new', 'projects:labels:edit'
......
......@@ -70,6 +70,7 @@ class @MergeRequestTabs
@loadCommits($target.attr('href'))
else if action == 'diffs'
@loadDiff($target.attr('href'))
@shrinkView()
else if action == 'builds'
@loadBuilds($target.attr('href'))
......@@ -185,3 +186,14 @@ class @MergeRequestTabs
expandViewContainer: ->
$('.container-fluid').removeClass('container-limited')
shrinkView: ->
$gutterIcon = $('.gutter-toggle i')
# Wait until listeners are set
setTimeout( ->
# Only when sidebar is collapsed
if $gutterIcon.is('.fa-angle-double-right')
$gutterIcon.closest('a').trigger('click')
, 0)
......@@ -62,6 +62,11 @@ class @Milestone
dataType: "json"
constructor: ->
oldMouseStart = $.ui.sortable.prototype._mouseStart
$.ui.sortable.prototype._mouseStart = (event, overrideHandle, noActivation) ->
this._trigger "beforeStart", event, this._uiHash()
oldMouseStart.apply this, [event, overrideHandle, noActivation]
@bindIssuesSorting()
@bindMergeRequestSorting()
@bindTabsSwitching
......@@ -71,6 +76,10 @@ class @Milestone
connectWith: ".issues-sortable-list",
dropOnEmpty: true,
items: "li:not(.ui-sort-disabled)",
beforeStart: (event, ui) ->
$(".issues-sortable-list").css "min-height", ui.item.outerHeight()
stop: (event, ui) ->
$(".issues-sortable-list").css "min-height", "0px"
update: (event, ui) ->
data = $(this).sortable("serialize")
Milestone.sortIssues(data)
......@@ -96,10 +105,22 @@ class @Milestone
).disableSelection()
bindMergeRequestSorting: ->
$('a[data-toggle="tab"]').on 'show.bs.tab', (e) ->
currentTabClass = $(e.target).data('show')
previousTabClass = $(e.relatedTarget).data('show')
$(previousTabClass).hide()
$(currentTabClass).removeClass('hidden')
$(currentTabClass).show()
$("#merge_requests-list-unassigned, #merge_requests-list-ongoing, #merge_requests-list-closed").sortable(
connectWith: ".merge_requests-sortable-list",
dropOnEmpty: true,
items: "li:not(.ui-sort-disabled)",
beforeStart: (event, ui) ->
$(".merge_requests-sortable-list").css "min-height", ui.item.outerHeight()
stop: (event, ui) ->
$(".merge_requests-sortable-list").css "min-height", "0px"
update: (event, ui) ->
data = $(this).sortable("serialize")
Milestone.sortMergeRequests(data)
......@@ -123,12 +144,3 @@ class @Milestone
Milestone.updateMergeRequest(ui.item, merge_request_url, data)
).disableSelection()
bindMergeRequestSorting: ->
$('a[data-toggle="tab"]').on 'show.bs.tab', (e) ->
currentTabClass = $(e.target).data('show')
previousTabClass = $(e.relatedTarget).data('show')
$(previousTabClass).hide()
$(currentTabClass).removeClass('hidden')
$(currentTabClass).show()
......@@ -16,11 +16,50 @@ class @Profile
$('.update-notifications').on 'ajax:complete', ->
$(this).find('.btn-save').enable()
$('.js-choose-user-avatar-button').bind "click", ->
form = $(this).closest("form")
form.find(".js-user-avatar-input").click()
# Avatar management
$avatarInput = $('.js-user-avatar-input')
$filename = $('.js-avatar-filename')
$modalCrop = $('.modal-profile-crop')
$modalCropImg = $('.modal-profile-crop-image')
$('.js-choose-user-avatar-button').on "click", ->
$form = $(this).closest("form")
$form.find(".js-user-avatar-input").click()
$modalCrop.on 'shown.bs.modal', ->
setTimeout ( -> # The cropper must be asynchronously initialized
$modalCropImg.cropper
aspectRatio: 1
modal: false
scalable: false
rotatable: false
zoomable: false
crop: (event) ->
['x', 'y'].forEach (key) ->
$("#user_avatar_crop_#{key}").val(Math.floor(event[key]))
$("#user_avatar_crop_size").val(Math.floor(event.width))
), 0
$modalCrop.on 'hidden.bs.modal', ->
$modalCropImg.attr('src', '').cropper('destroy')
$avatarInput.val('')
$filename.text($filename.data('label'))
$('.js-user-avatar-input').bind "change", ->
$('.js-upload-user-avatar').on 'click', ->
$('.edit_user').submit()
$avatarInput.on "change", ->
form = $(this).closest("form")
filename = $(this).val().replace(/^.*[\\\/]/, '')
form.find(".js-avatar-filename").text(filename)
$filename.data('label', $filename.text()).text(filename)
reader = new FileReader
reader.onload = (event) ->
$modalCrop.modal('show')
$modalCropImg.attr('src', event.target.result)
fileData = reader.readAsDataURL(this.files[0])
......@@ -24,6 +24,10 @@ class @ShortcutsIssuable extends ShortcutsNavigation
@nextIssue()
return false
)
Mousetrap.bind('e', =>
@editIssue()
return false
)
if isMergeRequest
......@@ -63,3 +67,7 @@ class @ShortcutsIssuable extends ShortcutsNavigation
# Focus the input field
replyField.focus()
editIssue: ->
$editBtn = $('.issuable-edit')
Turbolinks.visit($editBtn.attr('href'))
......@@ -8,4 +8,10 @@ $(document).on("click", '.toggle-nav-collapse', (e) ->
$('.sidebar-wrapper').toggleClass("sidebar-collapsed sidebar-expanded")
$('.toggle-nav-collapse i').toggleClass("fa-angle-right fa-angle-left")
$.cookie("collapsed_nav", $('.page-with-sidebar').hasClass(collapsed), { path: '/' })
setTimeout ( ->
niceScrollBars = $('.nicescroll').niceScroll();
niceScrollBars.updateScrollBar();
), 300
)
......@@ -2,7 +2,7 @@
class @Wikis
constructor: ->
$('.build-new-wiki').bind 'click', (e) =>
$('.new-wiki-page').on 'submit', (e) =>
$('[data-error~=slug]').addClass('hidden')
field = $('#new_wiki_path')
slug = @slugify(field.val())
......@@ -10,6 +10,7 @@ class @Wikis
if (slug.length > 0)
path = field.attr('data-wikis-path')
location.href = path + '/' + slug
e.preventDefault()
dasherize: (value) ->
value.replace(/[_\s]+/g, '-')
......
......@@ -9,6 +9,7 @@
*= require_self
*= require dropzone/basic
*= require cal-heatmap
*= require cropper.css
*/
/*
......
......@@ -66,7 +66,7 @@
}
.oneline {
line-height: 42px;
line-height: 35px;
}
> p:last-child {
......
......@@ -7,7 +7,7 @@
&:focus,
&:active {
outline: none;
@include box-shadow(inset 0 0 4px rgba(0, 0, 0, 0.12));
@include box-shadow($gl-btn-active-background);
}
}
......@@ -28,7 +28,7 @@
}
&:active {
@include box-shadow (inset 0 0 4px rgba(0, 0, 0, 0.12));
@include box-shadow ($gl-btn-active-background);
background-color: $dark;
border-color: $border-dark;
......@@ -68,6 +68,12 @@
@include btn-default;
@include btn-white;
color: $gl-text-color;
&:focus:active {
outline: 0;
}
&.btn-small,
&.btn-sm {
padding: 4px 10px;
......@@ -130,6 +136,11 @@
&.disabled {
pointer-events: auto !important;
}
.caret {
margin-left: 5px;
color: $gray-darkest;
}
}
.btn-block {
......@@ -179,7 +190,7 @@
}
.active {
@include box-shadow(inset 0 0 4px rgba(0, 0, 0, 0.12));
@include box-shadow($gl-btn-active-background);
border: 1px solid #c6cacf !important;
background-color: #e4e7ed !important;
......
......@@ -56,6 +56,10 @@ hr {
margin: $gl-padding 0;
}
.dropdown-menu {
margin: 6px 0 0;
}
.dropdown-menu > li > a {
text-shadow: none;
}
......
......@@ -158,7 +158,7 @@
}
&:hover {
background: $hover;
background: $row-hover;
}
}
}
......
......@@ -21,10 +21,3 @@
}
}
}
.issues-filters,
.issues_bulk_update {
.select2-container .select2-choice {
color: #444 !important;
}
}
......@@ -77,6 +77,7 @@ header {
line-height: $header-height;
font-weight: normal;
color: #4c4e54;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: top;
white-space: nowrap;
......@@ -141,9 +142,13 @@ header {
}
@media (max-width: $screen-md-max) {
.header-collapsed, .header-expanded {
@include collapsed-header;
.header-collapsed {
margin-left: $sidebar_collapsed_width;
}
.header-expanded {
margin-left: $sidebar_width;
}
}
@media(min-width: $screen-md-max) {
......
......@@ -44,8 +44,10 @@
white-space: nowrap;
i {
float: left;
margin-top: 3px;
margin-right: 5px;
visibility: hidden;
@extend .pull-left;
}
&:hover i {
......
......@@ -6,31 +6,28 @@
.status-box {
@include border-radius(3px);
display: block;
float: left;
padding: 0 $gl-btn-padding;
font-weight: normal;
margin-top: 5px;
margin-right: 10px;
color: #FFF;
font-size: $gl-font-size;
line-height: 25px;
&.status-box-closed {
background-color: $gl-danger;
color: #FFF;
}
&.status-box-merged {
background-color: $gl-primary;
color: #FFF;
}
&.status-box-open {
background-color: $green-light;
color: #FFF;
}
&.status-box-expired {
background: #cea61b;
color: #FFF;
}
}
......@@ -48,8 +48,8 @@
.ui-state-hover,
.ui-state-focus {
border: 1px solid $hover;
background: $hover;
border: 1px solid $row-hover;
background: $row-hover;
color: #333;
}
}
......
......@@ -38,7 +38,7 @@
&.smoke { background-color: $background-color; }
&:hover {
background: $hover;
background: $row-hover;
}
&:last-child {
......@@ -110,7 +110,20 @@ ul.content-list {
> li {
border-color: $table-border-color;
color: $gl-gray;
color: $list-text-color;
font-size: $list-font-size;
.title {
color: $list-title-color;
font-weight: 600;
}
.description {
p {
@include str-truncated;
margin-bottom: 0;
}
}
.avatar {
margin-right: 15px;
......@@ -127,13 +140,6 @@ ul.content-list {
}
}
.panel > .content-list {
li {
margin: 0;
padding: $gl-padding;
}
}
ul.controls {
padding-top: 1px;
float: right;
......
......@@ -41,6 +41,12 @@
transition: $transition;
}
@mixin transform($transform) {
-webkit-transform: $transform;
-ms-transform: $transform;
transform: $transform;
}
/**
* Prefilled mixins
* Mixins with fixed values
......
......@@ -77,12 +77,21 @@
margin-bottom: 0px;
> .dropdown {
margin-right: 10px;
margin-right: $gl-padding-top;
display: inline-block;
}
> .btn {
margin-right: $gl-padding-top;
display: inline-block;
&:last-child {
margin-right: 0;
}
}
> .btn-grouped {
float: none;
}
> form {
......@@ -94,7 +103,7 @@
display: inline-block;
position: relative;
top: 1px;
margin-right: 10px;
margin-right: $gl-padding-top;
/* Medium devices (desktops, 992px and up) */
@media (min-width: $screen-md-min) { width: 200px; }
......
/** Select2 selectbox style override **/
.select2-container {
width: 100% !important;
}
.select2-container, .select2-container.select2-drop-above {
.select2-choice {
background: #FFF;
border-color: #DDD;
height: 36px;
padding: 6px $gl-padding;
background: #fff;
border-color: $input-border;
border-color: $border-white-light;
height: 35px;
padding: $gl-vert-padding $gl-btn-padding;
font-size: $gl-font-size;
line-height: 1.42857143;
@include border-radius(2px);
@include border-radius($border-radius-default);
.select2-arrow {
background: #FFF;
border-left: none;
padding-top: 5px;
background-image: none;
background-color: transparent;
border: none;
padding-top: 6px;
padding-right: 10px;
b {
@extend .caret;
color: $gray-darkest;
}
}
.select2-chosen {
color: $gl-text-color;
margin-right: 15px;
}
&.select2-default {
.select2-chosen {
color: #999;
}
&:hover {
background-color: $gray-dark;
border-color: $border-white-normal;
color: $gl-text-color;
}
}
}
.select2-container .select2-choice, .select2-container.select2-drop-above .select2-choice{
color: #7f8fa4;
border: 1px solid #e7e9ed;
}
.select2-drop {
@include box-shadow(rgba(76, 86, 103, 0.247059) 0px 0px 1px 0px, rgba(31, 37, 50, 0.317647) 0px 2px 18px 0px);
@include border-radius (0px);
padding: 16px;
border: none !important;
@include border-radius ($border-radius-default);
border: none;
}
.select2-results .select2-result-label {
padding: 9px;
padding: 10px 15px;
}
.select2-drop{
......@@ -56,15 +60,30 @@
.select2-results li.select2-result-with-children > .select2-result-label {
font-weight: 600;
color: #313236;
color: $gl-text-color;
}
.select2-container-active {
.select2-choice, .select2-choices {
@include box-shadow(none);
}
}
.select2-dropdown-open {
.select2-choice {
border-color: $border-white-normal;
outline: 0;
background-image: none;
background-color: $white-dark;
@include box-shadow($gl-btn-active-gradient);
}
}
.select2-container-multi {
.select2-choices {
@include border-radius(2px);
@include border-radius($border-radius-default);
border-color: $input-border;
background: white;
padding-left: $gl-padding / 2;
background: none;
.select2-search-field input {
padding: $gl-padding / 2;
......@@ -76,14 +95,16 @@
.select2-search-choice {
margin: 8px 0 0 8px;
background: white;
box-shadow: none;
border-color: $input-border;
color: $gl-text-color;
line-height: 15px;
background-color: $background-color;
background-image: none;
.select2-search-choice-close {
top: 5px;
top: 4px;
left: 3px;
}
&.select2-search-choice-focus {
......@@ -91,22 +112,25 @@
}
}
}
&.select2-container-active .select2-choices,
&.select2-dropdown-open .select2-choices {
border-color: $border-white-normal;
@include box-shadow($gl-btn-active-gradient);
}
}
.select2-container-multi .select2-choices .select2-search-choice {
}
.select2-drop-active {
border: 1px solid #BBB !important;
margin-top: 4px;
font-size: 13px;
margin-top: 6px;
font-size: 14px;
&.select2-drop-above {
margin-bottom: 8px;
}
.select2-search input {
background: #fafafa;
border-color: #DDD;
}
.select2-results {
max-height: 350px;
.select2-highlighted {
......@@ -115,8 +139,34 @@
}
}
.select2-container {
width: 100% !important;
.select2-search {
padding: 15px 15px 5px;
.select2-drop-auto-width & {
padding: 15px 15px 5px;
}
}
.select2-search input {
padding: 2px 25px 2px 5px;
background: #fff image-url('select2.png');
background-repeat: no-repeat;
background-position: right 0px bottom 6px;
border: 1px solid $input-border;
@include border-radius($border-radius-default);
@include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s);
&:focus {
border-color: $input-border-focus;
}
}
.select2-search input.select2-active {
background-color: #fff;
background-image: image-url('select2-spinner.gif') !important;
background-repeat: no-repeat;
background-position: right 5px center !important;
background-size: 16px 16px !important;
}
/** Branch/tag selector **/
......@@ -124,10 +174,19 @@
width: 160px !important;
}
.ajax-users-dropdown, .ajax-project-users-dropdown {
.select2-search {
padding-top: 2px;
}
.select2-results .select2-no-results,
.select2-results .select2-searching,
.select2-results .select2-ajax-error,
.select2-results .select2-selection-limit {
background: $gray-light;
display: list-item;
padding: 10px 15px;
}
.select2-results {
margin: 0;
padding: 10px 0;
}
.ajax-users-select {
......
......@@ -12,6 +12,10 @@
height: 100%;
transition-duration: .3s;
}
&.right-sidebar-expanded {
padding-right: $gutter_width;
}
}
.sidebar-wrapper {
......@@ -45,19 +49,6 @@
overflow: hidden;
transition-duration: .3s;
.home {
z-index: 1;
position: absolute;
left: 0px;
}
#logo {
z-index: 2;
position: absolute;
width: 58px;
cursor: pointer;
}
a {
float: left;
height: $header-height;
......@@ -83,7 +74,7 @@
width: 158px;
float: left;
margin: 0;
margin-left: 50px;
margin-left: 14px;
font-size: 19px;
line-height: 41px;
font-weight: normal;
......@@ -194,6 +185,10 @@
@mixin expanded-sidebar {
padding-left: $sidebar_width;
&.right-sidebar-collapsed {
padding-right: $sidebar_collapsed_width;
}
.sidebar-wrapper {
width: $sidebar_width;
......@@ -213,17 +208,13 @@
}
}
@mixin expanded-gutter {
padding-right: $gutter_width;
}
@mixin collapsed-gutter {
padding-right: $sidebar_collapsed_width;
}
@mixin collapsed-sidebar {
padding-left: $sidebar_collapsed_width;
&.right-sidebar-collapsed {
padding-right: $sidebar_collapsed_width;
}
.sidebar-wrapper {
width: $sidebar_collapsed_width;
......@@ -287,47 +278,10 @@
background: #f2f6f7;
}
// page is small enough
@media (max-width: $screen-md-max) {
.page-sidebar-collapsed {
@include collapsed-sidebar;
}
.page-sidebar-expanded {
@include collapsed-sidebar;
}
.page-gutter {
&.right-sidebar-collapsed {
@include collapsed-gutter;
}
&.right-sidebar-expanded {
@include expanded-gutter;
}
}
.collapse-nav {
display: none;
}
.page-sidebar-collapsed {
@include collapsed-sidebar;
}
// page is large enough
@media(min-width: $screen-md-max) {
.page-gutter {
&.right-sidebar-collapsed {
@include collapsed-gutter;
}
&.right-sidebar-expanded {
@include expanded-gutter;
}
}
.page-sidebar-collapsed {
@include collapsed-sidebar;
}
.page-sidebar-expanded {
@include expanded-sidebar;
}
}
\ No newline at end of file
.page-sidebar-expanded {
@include expanded-sidebar;
}
......@@ -5,13 +5,13 @@
padding: 0;
.timeline-entry {
padding: $gl-padding 0;
padding: $gl-padding $gl-btn-padding;
border-color: $table-border-color;
color: $gl-gray;
border-bottom: 1px solid $border-white-light;
&:target {
background: $hover;
background: $row-hover;
}
&:last-child {
......
......@@ -70,7 +70,7 @@ $pagination-bg: #fff;
$pagination-border: $border-color;
$pagination-hover-color: $gl-gray;
$pagination-hover-bg: $hover;
$pagination-hover-bg: $row-hover;
$pagination-hover-border: $border-color;
$pagination-active-color: $blue-dark;
......
$hover: #faf9f9;
$row-hover: #f4f8fe;
$gl-text-color: #54565B;
$gl-text-green: #4A2;
$gl-text-red: #D12F19;
......@@ -31,6 +31,9 @@ $gl-padding-top:10px;
$gl-avatar-size: 40px;
$secondary-text: #7f8fa4;
$error-exclamation-point: #E62958;
$border-radius-default: 3px;
$list-title-color: #333333;
$list-text-color: #555555;
/*
* Color schema
......@@ -100,6 +103,8 @@ $gl-success: $green-normal;
$gl-info: $blue-normal;
$gl-warning: $orange-normal;
$gl-danger: $red-normal;
$gl-btn-active-background: rgba(0, 0, 0, 0.12);
$gl-btn-active-gradient: inset 0 0 4px $gl-btn-active-background;
/*
* Commit Diff Colors
......
.appearance-logo-preview {
max-width: 400px;
margin-bottom: 20px;
}
.appearance-light-logo-preview {
background-color: $background-color;
max-width: 72px;
padding: 10px;
margin-bottom: 10px;
}
......@@ -64,7 +64,6 @@
// This prevents the mess when resizing the sidebar
// of elements repositioning themselves..
width: $gutter_inner_width;
overflow-x: hidden;
// --
&:first-child {
......@@ -90,7 +89,6 @@
.gutter-toggle {
margin-left: 20px;
border-left: 1px solid $border-gray-light;
padding-left: 10px;
&:hover {
......@@ -157,11 +155,10 @@
.right-sidebar {
position: fixed;
top: 58px;
bottom: 0;
right: 0;
height: 100%;
transition-duration: .3s;
transition: width .3s;
background: $gray-light;
overflow: scroll;
padding: 10px 20px;
&.right-sidebar-expanded {
......@@ -170,6 +167,14 @@
hr {
display: none;
}
.sidebar-collapsed-icon {
display: none;
}
.gutter-toggle {
border-left: 1px solid $border-gray-light;
}
}
.subscribe-button {
......@@ -181,7 +186,6 @@
&.right-sidebar-collapsed {
width: $sidebar_collapsed_width;
padding-top: 0;
overflow-x: hidden;
hr {
margin: 0;
......@@ -192,42 +196,25 @@
}
.block {
border-bottom: none;
width: $sidebar_collapsed_width - 1px;
margin-left: -19px;
padding: 15px 0 0 0;
border-bottom: none;
overflow: hidden;
}
}
.btn {
background: $gray-normal;
border: 1px solid $border-gray-normal;
&:hover {
background: $gray-dark;
border: 1px solid $border-gray-dark;
}
}
&.right-sidebar-collapsed {
.issuable-count,
.issuable-nav,
.assignee > *,
.milestone > *,
.labels > *,
.participants > *,
.light > *,
.project-reference > * {
.hide-collapsed {
display: none;
}
.gutter-toggle {
margin-left: -$gutter_inner_width + 4;
margin-left: -36px;
}
.sidebar-collapsed-icon {
display: block;
float: left;
width: 62px;
width: 100%;
text-align: center;
margin-left: -19px;
padding-bottom: 10px;
color: #999999;
......@@ -247,14 +234,15 @@
color: #999999;
}
}
}
}
&.right-sidebar-expanded {
.sidebar-collapsed-icon {
display: none;
.btn {
background: $gray-normal;
border: 1px solid $border-gray-normal;
&:hover {
background: $gray-dark;
border: 1px solid $border-gray-dark;
}
}
}
......@@ -263,4 +251,4 @@
small {
color: $gray-darkest;
}
}
\ No newline at end of file
}
......@@ -4,13 +4,7 @@
position: relative;
.issue-title {
margin-bottom: 5px;
font-size: $list-font-size;
font-weight: 600;
}
.issue-info {
color: $gl-gray;
margin-bottom: 2px;
}
.issue-check {
......
......@@ -148,15 +148,8 @@
position: relative;
.merge-request-title {
margin-bottom: 5px;
font-size: $list-font-size;
font-weight: 600;
}
.merge-request-info {
color: $gl-gray;
margin-bottom: 2px;
}
}
.merge-request-labels {
......
......@@ -51,9 +51,17 @@
.profile-link-holder {
display: inline;
a {
color: $blue-dark;
text-decoration: none;
}
}
// Middle dot divider between each element in a list of items.
.middle-dot-divider {
&:after {
content: "\00B7";
padding: 0px 6px;
content: "\00B7"; // Middle Dot
padding: 0 6px;
font-weight: bold;
}
......@@ -63,9 +71,46 @@
padding: 0;
}
}
}
a {
color: $blue-dark;
text-decoration: none;
.profile-user-bio {
// Limits the width of the user bio for readability.
max-width: 750px;
margin: auto;
}
.modal-profile-crop {
.modal-dialog {
width: 500px;
}
.modal-body {
p {
display: table;
margin: auto;
overflow: hidden;
}
img {
display: block;
max-width: 400px;
max-height: 400px;
}
.cropper-bg {
background: none;
}
.cropper-crop-box {
box-sizing: content-box;
border: 999px solid transparentize(#ccc, 0.5);
@include transform(translate(-999px, -999px));
}
}
}
@media (max-width: 520px) {
.modal-profile-crop .modal-dialog {
width: auto;
}
}
......@@ -32,6 +32,7 @@
.cover-controls {
.project-settings-dropdown {
margin-left: 10px;
display: inline-block;
}
}
......@@ -186,10 +187,10 @@
.dropdown-menu {
@include box-shadow(rgba(76, 86, 103, 0.247059) 0px 0px 1px 0px, rgba(31, 37, 50, 0.317647) 0px 2px 18px 0px);
@include border-radius (0px);
@include border-radius ($border-radius-default);
border: none;
padding: 16px 0;
padding: 10px 0;
font-size: 14px;
font-weight: 100;
......@@ -396,15 +397,10 @@ pre.light-well {
.project-full-name {
@include str-truncated;
font-weight: 600;
color: #4c4e54;
}
.project-controls {
float: right;
color: $gl-gray;
.controls {
line-height: 40px;
color: #7f8fa4;
a:hover {
text-decoration: none;
......@@ -414,16 +410,6 @@ pre.light-well {
margin-left: 10px;
}
}
.project-description {
color: #7f8fa4;
p {
@include str-truncated;
margin-bottom: 0;
color: #7f8fa4;
}
}
}
.bottom {
......
......@@ -2,30 +2,6 @@
padding: 2px;
}
.snippet-row {
.snippet-title {
font-size: 15px;
font-weight: bold;
line-height: 20px;
margin-bottom: 2px;
.monospace {
font-weight: normal;
}
}
.snippet-info {
color: #888;
font-size: 13px;
line-height: 24px;
a {
color: #888;
}
}
}
.snippet-holder {
margin-bottom: -$gl-padding;
......
......@@ -12,29 +12,10 @@
}
}
.todos {
.panel {
border-top: none;
margin-bottom: 0;
}
}
.todo-item {
font-size: $gl-font-size;
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
border-bottom: 1px solid $table-border-color;
color: #7f8fa4;
&.todo-inline {
.avatar {
position: relative;
top: -2px;
}
.todo-title {
line-height: 40px;
}
}
padding-left: $gl-avatar-size + $gl-padding-top;
color: $secondary-text;
a {
color: #4c4e54;
......@@ -48,7 +29,7 @@
@include str-truncated(calc(100% - 174px));
font-weight: 600;
.author_name {
.author-name {
color: #333;
}
}
......@@ -88,17 +69,7 @@
margin-bottom: 0;
}
}
.todo-note-icon {
color: #777;
float: left;
font-size: $gl-font-size;
line-height: 16px;
margin-right: 5px;
}
}
&:last-child { border:none }
}
@media (max-width: $screen-xs-max) {
......
......@@ -21,7 +21,7 @@
&:hover {
td {
background: $hover;
background: $row-hover;
}
cursor: pointer;
}
......
......@@ -3,4 +3,15 @@
margin: 35px 0 20px;
font-weight: bold;
}
.example {
&:before {
content: "Example";
color: #BBB;
}
padding: 15px;
border: 1px dashed #ddd;
margin-bottom: 15px;
}
}
......@@ -4,8 +4,3 @@
margin-right: auto;
padding-right: 7px;
}
.wiki-last-edit-by {
font-size: 80%;
font-weight: normal;
}
class Admin::AppearancesController < Admin::ApplicationController
before_action :set_appearance, except: :create
def show
end
def preview
end
def create
@appearance = Appearance.new(appearance_params)
if @appearance.save
redirect_to admin_appearances_path, notice: 'Appearance was successfully created.'
else
render action: 'show'
end
end
def update
if @appearance.update(appearance_params)
redirect_to admin_appearances_path, notice: 'Appearance was successfully updated.'
else
render action: 'show'
end
end
def logo
@appearance.remove_logo!
@appearance.save
redirect_to admin_appearances_path, notice: 'Logo was succesfully removed.'
end
def header_logos
@appearance.remove_header_logo!
@appearance.save
redirect_to admin_appearances_path, notice: 'Header logo was succesfully removed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appearance
@appearance = Appearance.last || Appearance.new
end
# Only allow a trusted parameter "white list" through.
def appearance_params
params.require(:appearance).permit(
:title, :description, :logo, :logo_cache, :header_logo, :header_logo_cache,
:updated_by
)
end
end
......@@ -15,7 +15,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
end
def destroy_all
@todos.each(&:done)
@todos.each(&:done!)
respond_to do |format|
format.html { redirect_to dashboard_todos_path, notice: 'All todos were marked as done.' }
......
class EmojisController < ApplicationController
layout false
def index
end
end
......@@ -65,6 +65,9 @@ class ProfilesController < Profiles::ApplicationController
def user_params
params.require(:user).permit(
:avatar_crop_x,
:avatar_crop_y,
:avatar_crop_size,
:avatar,
:bio,
:email,
......
......@@ -64,9 +64,9 @@ class Projects::RefsController < Projects::ApplicationController
}
end
if @logs.present?
@log_url = namespace_project_tree_url(@project.namespace, @project, tree_join(@ref, @path || '/'))
@more_log_url = logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: (@offset + @limit))
offset = (@offset + @limit)
if contents.size > offset
@more_log_url = logs_file_namespace_project_ref_path(@project.namespace, @project, @ref, @path || '', offset: offset)
end
respond_to do |format|
......
......@@ -55,14 +55,15 @@ class UploadsController < ApplicationController
"user" => User,
"project" => Project,
"note" => Note,
"group" => Group
"group" => Group,
"appearance" => Appearance
}
upload_models[params[:model]]
end
def upload_mount
upload_mounts = %w(avatar attachment file)
upload_mounts = %w(avatar attachment file logo header_logo)
if upload_mounts.include?(params[:mounted_as])
params[:mounted_as]
......
module AppearancesHelper
def brand_item
nil
end
def brand_title
'GitLab Community Edition'
if brand_item && brand_item.title
brand_item.title
else
'GitLab Community Edition'
end
end
def brand_image
nil
if brand_item.logo?
image_tag brand_item.logo
else
nil
end
end
def brand_text
nil
markdown(brand_item.description)
end
def brand_item
@appearance ||= Appearance.first
end
def brand_header_logo
render 'shared/logo.svg'
if brand_item && brand_item.header_logo?
image_tag brand_item.header_logo
else
render 'shared/logo.svg'
end
end
end
......@@ -6,6 +6,10 @@ module AuthHelper
Gitlab.config.ldap.enabled
end
def omniauth_enabled?
Gitlab.config.omniauth.enabled
end
def provider_has_icon?(name)
PROVIDERS_WITH_ICONS.include?(name.to_s)
end
......
......@@ -130,7 +130,7 @@ module CommitsHelper
if can_collaborate_with_project?
content_tag :span, 'data-toggle' => 'modal', 'data-target' => '#modal-revert-commit' do
link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'tooltip', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class}"
link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class}"
end
elsif can?(current_user, :fork_project, @project)
continue_params = {
......@@ -142,7 +142,7 @@ module CommitsHelper
namespace_key: current_user.namespace.id,
continue: continue_params)
link_to 'Revert', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', title: tooltip
link_to 'Revert', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip
end
end
......
class Appearance < ActiveRecord::Base
validates :title, presence: true
validates :description, presence: true
validates :logo, file_size: { maximum: 1.megabyte }
validates :header_logo, file_size: { maximum: 1.megabyte }
mount_uploader :logo, AttachmentUploader
mount_uploader :header_logo, AttachmentUploader
end
......@@ -232,7 +232,7 @@ class Commit
end
def reverts_commit?(commit)
description.include?(commit.revert_description)
description? && description.include?(commit.revert_description)
end
def merge_commit?
......
......@@ -27,7 +27,7 @@ class Milestone < ActiveRecord::Base
belongs_to :project
has_many :issues
has_many :labels, through: :issues
has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
has_many :merge_requests
has_many :participants, through: :issues, source: :assignee
......
......@@ -801,10 +801,7 @@ class Project < ActiveRecord::Base
end
def change_head(branch)
# Cached divergent commit counts are based on repository head
repository.expire_branch_cache
repository.expire_root_ref_cache
repository.before_change_head
gitlab_shell.update_repository_head(self.path_with_namespace, branch)
reload_default_branch
end
......
......@@ -245,15 +245,6 @@ class Repository
expire_emptiness_caches if empty?
end
# Expires _all_ caches, including those that would normally only be expired
# under specific conditions.
def expire_all_caches!
expire_cache
expire_root_ref_cache
expire_emptiness_caches
expire_has_visible_content_cache
end
def expire_branch_cache(branch_name = nil)
# When we push to the root branch we have to flush the cache for all other
# branches as their statistics are based on the commits relative to the
......@@ -307,6 +298,46 @@ class Repository
cache.expire(:branch_names)
end
# Runs code just before a repository is deleted.
def before_delete
expire_cache if exists?
expire_root_ref_cache
expire_emptiness_caches
end
# Runs code just before the HEAD of a repository is changed.
def before_change_head
# Cached divergent commit counts are based on repository head
expire_branch_cache
expire_root_ref_cache
end
# Runs code before creating a new tag.
def before_create_tag
expire_cache
end
# Runs code after a repository has been forked/imported.
def after_import
expire_emptiness_caches
end
# Runs code after a new commit has been pushed.
def after_push_commit(branch_name)
expire_cache(branch_name)
end
# Runs code after a new branch has been created.
def after_create_branch
expire_has_visible_content_cache
end
# Runs code after an existing branch has been removed.
def after_remove_branch
expire_has_visible_content_cache
end
def method_missing(m, *args, &block)
if m == :lookup && !block_given?
lookup_cache[m] ||= {}
......
......@@ -36,7 +36,7 @@ class Todo < ActiveRecord::Base
state_machine :state, initial: :pending do
event :done do
transition pending: :done
transition [:pending, :done] => :done
end
state :pending
......
......@@ -98,6 +98,9 @@ class User < ActiveRecord::Base
# Virtual attribute for authenticating by either username or email
attr_accessor :login
# Virtual attributes to define avatar cropping
attr_accessor :avatar_crop_x, :avatar_crop_y, :avatar_crop_size
#
# Relations
#
......@@ -163,6 +166,11 @@ class User < ActiveRecord::Base
validate :owns_public_email, if: ->(user) { user.public_email_changed? }
validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
validates :avatar_crop_x, :avatar_crop_y, :avatar_crop_size,
numericality: { only_integer: true },
presence: true,
if: ->(user) { user.avatar? }
before_validation :generate_password, on: :create
before_validation :restricted_signup_domains, on: :create
before_validation :sanitize_attrs
......
......@@ -16,13 +16,13 @@ class GitPushService < BaseService
# 5. Executes the project's services
#
def execute
@project.repository.expire_cache(branch_name)
@project.repository.after_push_commit(branch_name)
if push_remove_branch?
@project.repository.expire_has_visible_content_cache
@project.repository.after_remove_branch
@push_commits = []
elsif push_to_new_branch?
@project.repository.expire_has_visible_content_cache
@project.repository.after_create_branch
# Re-find the pushed commits.
if is_default_branch?
......
......@@ -2,7 +2,7 @@ class GitTagPushService
attr_accessor :project, :user, :push_data
def execute(project, user, oldrev, newrev, ref)
project.repository.expire_cache
project.repository.before_create_tag
@project, @user = project, user
@push_data = build_push_data(oldrev, newrev, ref)
......
......@@ -24,10 +24,14 @@ module MergeRequests
merge_requests.each do |merge_request|
next unless merge_request.merge_when_build_succeeds?
next unless merge_request.mergeable?
if merge_request.ci_commit && merge_request.ci_commit.success? && merge_request.mergeable?
MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params)
end
ci_commit = merge_request.ci_commit
next unless ci_commit
next unless ci_commit.sha == commit_status.sha
next unless ci_commit.success?
MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params)
end
end
......@@ -51,6 +55,8 @@ module MergeRequests
# This is for ref-less builds
branches ||= @project.repository.branch_names_contains(commit_status.sha)
return [] if branches.blank?
merge_requests = @project.origin_merge_requests.opened.where(source_branch: branches).to_a
merge_requests += @project.fork_merge_requests.opened.where(source_branch: branches).to_a
......
......@@ -13,6 +13,5 @@ module Notes
note
end
end
end
......@@ -76,11 +76,9 @@ module Projects
end
def flush_caches(project, wiki_path)
project.repository.expire_all_caches! if project.repository.exists?
project.repository.before_delete
wiki_repo = Repository.new(wiki_path, project)
wiki_repo.expire_all_caches! if wiki_repo.exists?
Repository.new(wiki_path, project).before_delete
end
end
end
......@@ -130,8 +130,8 @@ class TodoService
end
def handle_note(note, author)
# Skip system notes, like status changes and cross-references
return if note.system
# Skip system notes, notes on commit, and notes on project snippet
return if note.system? || ['Commit', 'Snippet'].include?(note.noteable_type)
project = note.project
target = note.noteable
......
......@@ -2,11 +2,22 @@
class AvatarUploader < CarrierWave::Uploader::Base
include UploaderHelper
include CarrierWave::MiniMagick
storage :file
after :store, :reset_events_cache
process :cropper
def cropper
return unless model.respond_to?(:avatar_crop_size) && model.valid?
manipulate! do |img|
img.crop "#{model.avatar_crop_size}x#{model.avatar_crop_size}+#{model.avatar_crop_x}+#{model.avatar_crop_y}"
end
end
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
......
......@@ -29,8 +29,11 @@ class UrlValidator < ActiveModel::EachValidator
end
def valid_url?(value)
return false if value.nil?
options = default_options.merge(self.options)
value.strip!
value =~ /\A#{URI.regexp(options[:protocols])}\z/
end
end
= form_for @appearance, url: admin_appearances_path, html: { class: 'form-horizontal'} do |f|
- if @appearance.errors.any?
.alert.alert-danger
- @appearance.errors.full_messages.each do |msg|
%p= msg
%fieldset.sign-in
%legend
Sign in/Sign up pages:
.form-group
= f.label :title, class: 'control-label'
.col-sm-10
= f.text_field :title, class: "form-control"
.form-group
= f.label :description, class: 'control-label'
.col-sm-10
= f.text_area :description, class: "form-control", rows: 10
.hint
Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('markdown', 'markdown'), target: '_blank'}.
.form-group
= f.label :logo, class: 'control-label'
.col-sm-10
- if @appearance.logo?
= image_tag @appearance.logo_url, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
= link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: ""
.hint
Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.
%fieldset.app_logo
%legend
Navigation bar:
.form-group
= f.label :header_logo, 'Header logo', class: 'control-label'
.col-sm-10
- if @appearance.header_logo?
= image_tag @appearance.header_logo_url, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
= link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: ""
.hint
Maximum file size is 1MB. Pages are optimized for a 72x72 px header logo
.form-actions
= f.submit 'Save', class: 'btn btn-save'
- if @appearance.persisted?
= link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank'
- if @appearance.updated_at
%span.pull-right
Last edit #{time_ago_with_tooltip(@appearance.updated_at)}
- page_title "Preview | Appearance"
%h3.page-title
Appearance settings - Preview
%hr
.ui-box
.title
Sign-in page
%div
.login-page
.container
.content
.login-title
%h1= brand_title
%hr
.container
.content
.row
.col-sm-7
.brand-image
= brand_image
.brand_text
= brand_text
.col-sm-4
.login-box
%h3.page-title Sign in
= text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email"
= password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password"
= button_tag "Sign in", class: "btn-create btn"
- page_title "Appearance"
%h3.page-title
Appearance settings
%p.light
You can modify the look and feel of GitLab here
= render 'form'
%li{class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo) }
.todo-item{class: 'todo-block'}
.todo-item.todo-block
= image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:''
.todo-title
%span.author_name
%span.author-name
= link_to_author todo
%span.todo_label
%span.todo-label
= todo_action_name(todo)
= todo_target_link(todo)
......
- page_title "Sign in"
%div
- if signin_enabled? || ldap_enabled?
- if signin_enabled? || ldap_enabled? || crowd_enabled?
= render 'devise/shared/signin_box'
-# Omniauth fits between signin/ldap signin and signup and does not have a surrounding box
- if Gitlab.config.omniauth.enabled && devise_mapping.omniauthable?
- if omniauth_enabled? && devise_mapping.omniauthable?
.clearfix.prepend-top-20
= render 'devise/shared/omniauth_box'
......@@ -14,6 +14,6 @@
= render 'devise/shared/signup_box'
-# Show a message if none of the mechanisms above are enabled
- if !signin_enabled? && !ldap_enabled? && !(Gitlab.config.omniauth.enabled && devise_mapping.omniauthable?)
- if !signin_enabled? && !ldap_enabled? && !(omniauth_enabled? && devise_mapping.omniauthable?)
%div
No authentication methods configured.
.emoji-menu
.emoji-menu-content
= text_field_tag :emoji_search, "", class: "emoji-search search-input form-control"
- AwardEmoji.emoji_by_category.each do |category, emojis|
%h5= AwardEmoji::CATEGORIES[category]
%ul
- emojis.each do |emoji|
%li
= emoji_icon(emoji["name"], emoji["unicode"], emoji["aliases"])
\ No newline at end of file
.top-area
.nav-controls
= form_tag request.original_url, method: :get, class: 'project-filter-form', id: 'project-filter-form' do |f|
= search_field_tag :filter_projects, params[:filter_projects], placeholder: 'Filter by name...', class: 'input-short project-filter-form-field form-control projects-list-filter', spellcheck: false, id: 'project-filter-form-field'
- if current_user && current_user.can_create_project?
= link_to new_project_path, class: 'btn btn-new' do
= icon('plus')
New Project
- if @projects.present?
= search_field_tag :filter_projects, nil, placeholder: 'Filter by name', class: 'projects-list-filter form-control', spellcheck: false
- if can? current_user, :create_projects, @group
= link_to new_project_path(namespace_id: @group.id), class: 'btn btn-new pull-right' do
= icon('plus')
New Project
.projects-list-holder
= render 'shared/projects/list', projects: @projects, projects_limit: 20, stars: false, skip_namespace: true
......@@ -32,10 +32,9 @@
%li.active
= link_to "#activity", 'data-toggle' => 'tab' do
Activity
- if @projects.present?
%li
= link_to "#projects", 'data-toggle' => 'tab' do
Projects
%li
= link_to "#projects", 'data-toggle' => 'tab' do
Projects
- if can?(current_user, :read_group, @group)
%div{ class: container_class }
......
......@@ -229,6 +229,10 @@
%td.shortcut
.key r
%td Reply (quoting selected text)
%tr
%td.shortcut
.key e
%td Edit issue
%tbody{ class: 'hidden-shortcut merge_requests', style: 'display:none' }
%tr
%th
......@@ -245,3 +249,7 @@
%td.shortcut
.key r
%td Reply (quoting selected text)
%tr
%td.shortcut
.key e
%td Edit merge request
......@@ -31,64 +31,91 @@
%h2#blocks Blocks
%h4
.lead
Content block separated with botton border
%code .content-block
.example
.content-block
%h4 Normal block inside content
= lorem
.content-block
%h4 Second block
= lorem
.lead
Gray content block with side padding using
%code .gray-content-block
.gray-content-block.middle-block
%h4 Normal block inside content
= lorem
.example
.gray-content-block
%h4 Normal block inside content
= lorem
.gray-content-block.second-block
%h4 Second block
= lorem
.gray-content-block.second-block
%h4 Second block
= lorem
%h4
.lead
Cover block for profile page with avatar, name and description
%code .cover-block
%br
.cover-block
.avatar-holder
= image_tag avatar_icon('admin@example.com', 90), class: "avatar s90", alt: ''
.cover-title
John Smith
.cover-desc
= lorem
.example
.cover-block
.avatar-holder
= image_tag avatar_icon('admin@example.com', 90), class: "avatar s90", alt: ''
.cover-title
John Smith
.cover-desc
= lorem
.cover-controls
= link_to '#', class: 'btn btn-gray' do
= icon('pencil')
&nbsp;
= link_to '#', class: 'btn btn-gray' do
= icon('rss')
.cover-controls
= link_to '#', class: 'btn btn-gray' do
= icon('pencil')
&nbsp;
= link_to '#', class: 'btn btn-gray' do
= icon('rss')
%h2#lists Lists
%h4
.lead
Simple list using
%code .content-list
%ul.content-list
%li
One item
%li
One item
%li
One item
%h4
%code .well-list
%ul.well-list
%li
One item
%li
One item
%li
One item
.example
%ul.content-list
%li
One item
%li
One item
%li
One item
%h4
%code .panel .well-list
.lead
List with avatar, title and description using
%code .content-list
.example
%ul.content-list
%li
= image_tag 'no_avatar.png', class: 'avatar s40'
.title Title
.description Description
%li
= image_tag 'no_avatar.png', class: 'avatar s40'
.title Title
.description Description
%li
= image_tag 'no_avatar.png', class: 'avatar s40'
.title Title
.description Description
.panel.panel-default
.panel-heading Your list
.lead
List with hover effect
%code .well-list
.example
%ul.well-list
%li
One item
......@@ -97,17 +124,18 @@
%li
One item
%h4
%code .bordered-list
%ul.bordered-list
%li
One item
%li
One item
%li
One item
.lead
List inside panel
.example
.panel.panel-default
.panel-heading Your list
%ul.well-list
%li
One item
%li
One item
%li
One item
%h2#tables Tables
......@@ -138,9 +166,9 @@
%h2#navs Navigation
%h4
.lead
Holder for top page navigation. Includes navigation, search field, sorting and button
%code .top-area
%p Holder for top page navigation. Includes navigation, search field, sorting and button
.example
.top-area
......@@ -161,9 +189,9 @@
= link_to 'New issue', '#', class: 'btn btn-new'
%h4
.lead
Only nav links without button and search
%code .nav-links
%p Only nav links without button and search
.example
%ul.nav-links
%li.active
......@@ -228,43 +256,47 @@
%h2#forms Forms
%h4
.lead
Horizontal form when label rendered inline with input
%code form.horizontal-form
%form.form-horizontal
.form-group
%label.col-sm-2.control-label{:for => "inputEmail3"} Email
.col-sm-10
%input#inputEmail3.form-control{:placeholder => "Email", :type => "email"}/
.form-group
%label.col-sm-2.control-label{:for => "inputPassword3"} Password
.col-sm-10
%input#inputPassword3.form-control{:placeholder => "Password", :type => "password"}/
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
%label
%input{:type => "checkbox"}/
Remember me
.form-group
.col-sm-offset-2.col-sm-10
%button.btn.btn-default{:type => "submit"} Sign in
%h4
.example
%form.form-horizontal
.form-group
%label.col-sm-2.control-label{:for => "inputEmail3"} Email
.col-sm-10
%input#inputEmail3.form-control{:placeholder => "Email", :type => "email"}/
.form-group
%label.col-sm-2.control-label{:for => "inputPassword3"} Password
.col-sm-10
%input#inputPassword3.form-control{:placeholder => "Password", :type => "password"}/
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
%label
%input{:type => "checkbox"}/
Remember me
.form-group
.col-sm-offset-2.col-sm-10
%button.btn.btn-default{:type => "submit"} Sign in
.lead
Form when label rendered above input
%code form
%form
.form-group
%label{:for => "exampleInputEmail1"} Email address
%input#exampleInputEmail1.form-control{:placeholder => "Enter email", :type => "email"}/
.form-group
%label{:for => "exampleInputPassword1"} Password
%input#exampleInputPassword1.form-control{:placeholder => "Password", :type => "password"}/
.checkbox
%label
%input{:type => "checkbox"}/
Remember me
%button.btn.btn-default{:type => "submit"} Sign in
.example
%form
.form-group
%label{:for => "exampleInputEmail1"} Email address
%input#exampleInputEmail1.form-control{:placeholder => "Enter email", :type => "email"}/
.form-group
%label{:for => "exampleInputPassword1"} Password
%input#exampleInputPassword1.form-control{:placeholder => "Password", :type => "password"}/
.checkbox
%label
%input{:type => "checkbox"}/
Remember me
%button.btn.btn-default{:type => "submit"} Sign in
%h2#file File
%h4
......
......@@ -44,6 +44,7 @@
= favicon_link_tag 'touch-icon-ipad.png', rel: 'apple-touch-icon', sizes: '76x76'
= favicon_link_tag 'touch-icon-iphone-retina.png', rel: 'apple-touch-icon', sizes: '120x120'
= favicon_link_tag 'touch-icon-ipad-retina.png', rel: 'apple-touch-icon', sizes: '152x152'
%link{rel: 'mask-icon', href: image_path('logo.svg'), color: 'rgb(226, 67, 41)'}
-# Windows 8 pinned site tile
%meta{name: 'msapplication-TileImage', content: image_path('msapplication-tile.png')}
......
......@@ -56,6 +56,11 @@
= icon('cog fw')
%span
Background Jobs
= nav_link(controller: :appearances) do
= link_to admin_appearances_path, title: 'Appearances' do
= icon('image')
%span
Appearance
= nav_link(controller: :applications) do
= link_to admin_applications_path, title: 'Applications' do
......
- page_title "Applications"
- header_title page_title, applications_profile_path
.gray-content-block.top-block
.alert.alert-help.prepend-top-default
- if user_oauth_applications?
Manage applications that can use GitLab as an OAuth provider,
and applications that you've authorized to use your account.
......
- page_title "Audit Log"
- header_title page_title, audit_log_profile_path
.gray-content-block.top-block
.alert.alert-help.prepend-top-default
History of authentications
.prepend-top-default
......
- page_title "Emails"
- header_title page_title, profile_emails_path
.gray-content-block.top-block
Control emails linked to your account
%ul.prepend-top-default
%li
Your
%b Primary Email
will be used for avatar detection and web based operations, such as edits and merges.
%li
Your
%b Notification Email
will be used for account notifications.
%li
Your
%b Public Email
will be displayed on your public profile.
%li
All email addresses will be used to identify your commits.
.alert.alert-help.prepend-top-default
%ul
%li
Your
%b Primary Email
will be used for avatar detection and web based operations, such as edits and merges.
%li
Your
%b Notification Email
will be used for account notifications.
%li
Your
%b Public Email
will be displayed on your public profile.
%li
All email addresses will be used to identify your commits.
.panel.panel-default
.panel-heading
......
- page_title "SSH Keys"
- header_title page_title, profile_keys_path
.gray-content-block.top-block
.pull-right
.top-area
.nav-text
Before you can add an SSH key you need to
= link_to "generate it.", help_page_path("ssh", "README")
.nav-controls
= link_to new_profile_key_path, class: "btn btn-new" do
= icon('plus')
Add SSH Key
.oneline
Before you can add an SSH key you need to
= link_to "generate it.", help_page_path("ssh", "README")
.prepend-top-default
= render 'key_table'
- page_title "Notifications"
- header_title page_title, profile_notifications_path
.gray-content-block.top-block
These are your global notification settings.
.prepend-top-default
= form_for @user, url: profile_notifications_path, method: :put, html: { class: 'update-notifications form-horizontal global-notifications-form' } do |f|
-if @user.errors.any?
......
- page_title "Password"
- header_title page_title, edit_profile_password_path
.gray-content-block.top-block
.alert.alert-help.prepend-top-default
- if @user.password_automatically_set?
Set your password.
- else
......
- page_title 'Preferences'
- header_title page_title, profile_preferences_path
- @blank_container = true
.alert.alert-help
.alert.alert-help.prepend-top-default
These settings allow you to customize the appearance and behavior of the site.
They are saved with your account and will persist to any device you use to
access the site.
......
.gray-content-block.top-block
.alert.alert-help.prepend-top-default
This information will appear on your profile.
- if current_user.ldap_user?
Some options are unavailable for LDAP accounts
......@@ -90,6 +90,9 @@
&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
......@@ -99,3 +102,19 @@
.form-actions
= f.submit 'Save changes', class: "btn btn-success"
= link_to "Cancel", user_path(current_user), class: "btn btn-cancel"
.modal.modal-profile-crop
.modal-dialog
.modal-content
.modal-header
%button.close{type: 'button', data: {dismiss: 'modal'}}
%span
&times;
%h4.modal-title
Crop your new profile picture
.modal-body
%p
%img.modal-profile-crop-image
.modal-footer
%button.btn.btn-primary.js-upload-user-avatar{:type => "button"}
Set new profile picture
......@@ -3,7 +3,7 @@
%h3.page-title Blame view
#tree-holder.tree-holder
#blob-content-holder.tree-holder
.file-holder
.file-title
= blob_icon @blob.mode, @blob.name
......@@ -33,7 +33,9 @@
%td.line-numbers
- line_count = blame_group[:lines].count
- (current_line...(current_line + line_count)).each do |i|
%a.diff-line-num= i
%a.diff-line-num{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i}
= icon("link")
= i
\
- current_line += line_count
%td.lines
......
......@@ -51,9 +51,11 @@
%th Name
%th Duration
%th Finished at
- if @project.build_coverage_enabled?
%th Coverage
%th
- @builds.each do |build|
= render 'projects/commit_statuses/commit_status', commit_status: build, commit_sha: true, stage: true, allow_retry: true
= render 'projects/commit_statuses/commit_status', commit_status: build, commit_sha: true, stage: true, coverage: @project.build_coverage_enabled?, allow_retry: true
= paginate @builds, theme: 'gitlab'
- @blank_container = true
.project-edit-container.prepend-top-default
.project-edit-errors
.project-edit-content
......
......@@ -18,7 +18,7 @@
= link_to "adding README", new_readme_path, class: 'underlined-link'
file to this project.
- if can?(current_user, :download_code, @project)
- if can?(current_user, :push_code, @project)
%div{ class: container_class }
.prepend-top-20
.empty_wrapper
......
- content_for :note_actions do
- if can?(current_user, :update_issue, @issue)
= link_to 'Reopen Issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen Issue'
= link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close Issue'
= link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
= link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
#notes
= render 'projects/notes/notes_with_form'
......@@ -5,7 +5,7 @@
.issue-title
%span.issue-title-text
= link_to_gfm issue.title, issue_path(issue), class: "row_title"
= link_to_gfm issue.title, issue_path(issue), class: "title"
%ul.controls.light
- if issue.closed?
%li
......
......@@ -8,12 +8,12 @@
.detail-page-header
.pull-right
- if can?(current_user, :create_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'btn btn-nr btn-grouped new-issue-link btn-success', title: 'New Issue', id: 'new_issue_link' do
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: 'btn btn-nr btn-grouped new-issue-link btn-success', title: 'New issue', id: 'new_issue_link' do
= icon('plus')
New Issue
New issue
- if can?(current_user, :update_issue, @issue)
= link_to 'Reopen', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen Issue'
= link_to 'Close', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close #{issue_button_visibility(@issue, true)}", title: 'Close Issue'
= link_to 'Reopen issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen issue'
= link_to 'Close issue', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close #{issue_button_visibility(@issue, true)}", title: 'Close issue'
= link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: 'btn btn-nr btn-grouped issuable-edit' do
= icon('pencil-square-o')
......
%li{ class: mr_css_classes(merge_request) }
.merge-request-title
%span.merge-request-title-text
= link_to_gfm merge_request.title, merge_request_path(merge_request), class: "row_title"
= link_to_gfm merge_request.title, merge_request_path(merge_request), class: "title"
%ul.controls.light
- if merge_request.merged?
%li
......
......@@ -8,12 +8,9 @@
row.find("td.tree_time_ago").html('#{escape_javascript time_ago_with_tooltip(commit.committed_date)}');
row.find("td.tree_commit").html('#{escape_javascript render("projects/tree/tree_commit_column", commit: commit)}');
- if @logs.present?
- if @more_log_url
:plain
var current_url = location.href.replace(/\/?$/, '/');
var log_url = "#{escape_javascript(@log_url)}".replace(/\/?$/, '/');
if(current_url == log_url) {
if($('#tree-slider').length) {
// Load more commit logs for each file in tree
// if we still on the same page
var url = "#{escape_javascript(@more_log_url)}";
......
%span.pull-right
- if (@page && @page.persisted?)
= link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
Page History
- if can?(current_user, :create_wiki, @project)
= link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
- if can?(current_user, :admin_wiki, @project)
= link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-remove" do
= icon('trash')
Delete
- if (@page && @page.persisted?)
= link_to namespace_project_wiki_history_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
Page History
- if can?(current_user, :create_wiki, @project)
= link_to namespace_project_wiki_edit_path(@project.namespace, @project, @page), class: "btn btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
- if can?(current_user, :admin_wiki, @project)
= link_to namespace_project_wiki_path(@project.namespace, @project, @page), data: { confirm: "Are you sure you want to delete this page?"}, method: :delete, class: "btn btn-remove" do
= icon('trash')
Delete
......@@ -16,4 +16,4 @@
= icon('plus')
New Page
= render 'projects/wikis/new'
= render 'projects/wikis/new'
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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