Skip to content
Snippets Groups Projects
Commit c922092b authored by Valery Sizov's avatar Valery Sizov
Browse files

Merge remote-tracking branch 'origin/master' into ce_upstream

parents 9f6a62ea fd231ff9
No related branches found
No related tags found
No related merge requests found
Showing
with 263 additions and 77 deletions
Loading
Loading
@@ -4,12 +4,28 @@ v 8.3.0 (unreleased)
- Merge when build succeeds (Zeger-Jan van de Weg)
v 8.4.0 (unreleased)
- Implement new UI for group page
- Implement search inside emoji picker
- Add API support for looking up a user by username (Stan Hu)
- Add project permissions to all project API endpoints (Stan Hu)
- Expose Git's version in the admin area
- Add "Frequently used" category to emoji picker
- Add CAS support (tduehr)
- Add link to merge request on build detail page.
- Revert back upvote and downvote button to the issue and MR pages
v 8.3.2 (unreleased)
- Enable "Add key" button when user fills in a proper key
v 8.3.1
- Fix Error 500 when global milestones have slashes (Stan Hu)
- Fix Error 500 when doing a search in dashboard before visiting any project (Stan Hu)
- Fix LDAP identity and user retrieval when special characters are used
- Move Sidekiq-cron configuration to gitlab.yml
- Enable forcing Two-Factor authentication sitewide, with optional grace period
 
v 8.3.0
- Add CAS support (tduehr)
- Bump rack-attack to 4.3.1 for security fix (Stan Hu)
- API support for starred projects for authorized user (Zeger-Jan van de Weg)
- Add link to merge request on build detail page.
- Add open_issues_count to project API (Stan Hu)
- Expand character set of usernames created by Omniauth (Corey Hinshaw)
- Add button to automatically merge a merge request when the build succeeds (Zeger-Jan van de Weg)
Loading
Loading
@@ -70,7 +86,6 @@ v 8.3.0
- Do not show build status unless builds are enabled and `.gitlab-ci.yml` is present
- Persist runners registration token in database
- Fix online editor should not remove newlines at the end of the file
- Expose Git's version in the admin area
 
v 8.2.3
- Fix application settings cache not expiring after changes (Stan Hu)
Loading
Loading
Loading
Loading
@@ -177,7 +177,7 @@ gem 'd3_rails', '~> 3.5.5'
gem "cal-heatmap-rails", "~> 0.0.1"
 
# underscore-rails
gem "underscore-rails", "~> 1.4.4"
gem "underscore-rails", "~> 1.8.0"
 
# Sanitize user input
gem "sanitize", '~> 2.0'
Loading
Loading
@@ -195,7 +195,7 @@ gem 'mousetrap-rails', '~> 1.4.6'
# Detect and convert string character encoding
gem 'charlock_holmes', '~> 0.7.3'
 
gem "sass-rails", '~> 4.0.5'
gem "sass-rails", '~> 5.0.0'
gem "coffee-rails", '~> 4.1.0'
gem "uglifier", '~> 2.7.2'
gem 'turbolinks', '~> 2.5.0'
Loading
Loading
@@ -207,9 +207,9 @@ gem 'font-awesome-rails', '~> 4.2'
gem 'gitlab_emoji', '~> 0.2.0'
gem 'gon', '~> 6.0.1'
gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'jquery-rails', '~> 3.1.3'
gem 'jquery-rails', '~> 4.0.0'
gem 'jquery-scrollto-rails', '~> 1.4.3'
gem 'jquery-ui-rails', '~> 4.2.1'
gem 'jquery-ui-rails', '~> 5.0.0'
gem 'nprogress-rails', '~> 0.1.6.7'
gem 'raphael-rails', '~> 2.1.2'
gem 'request_store', '~> 1.2.0'
Loading
Loading
Loading
Loading
@@ -377,15 +377,16 @@ GEM
inflecto (0.0.2)
ipaddress (0.8.0)
jquery-atwho-rails (1.3.2)
jquery-rails (3.1.4)
railties (>= 3.0, < 5.0)
jquery-rails (4.0.5)
rails-dom-testing (~> 1.0)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-scrollto-rails (1.4.3)
railties (> 3.1, < 5.0)
jquery-turbolinks (2.1.0)
railties (>= 3.1.0)
turbolinks
jquery-ui-rails (4.2.1)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
json (1.8.3)
jwt (1.5.2)
Loading
Loading
@@ -652,12 +653,13 @@ GEM
safe_yaml (1.0.4)
sanitize (2.1.0)
nokogiri (>= 1.4.4)
sass (3.2.19)
sass-rails (4.0.5)
sass (3.4.20)
sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0)
sass (~> 3.2.2)
sprockets (~> 2.8, < 3.0)
sprockets-rails (~> 2.0)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sawyer (0.6.0)
addressable (~> 2.3.5)
faraday (~> 0.8, < 0.10)
Loading
Loading
@@ -772,7 +774,7 @@ GEM
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
underscore-rails (1.4.4)
underscore-rails (1.8.3)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
Loading
Loading
@@ -886,10 +888,10 @@ DEPENDENCIES
html-pipeline (~> 1.11.0)
httparty (~> 0.13.3)
jquery-atwho-rails (~> 1.3.2)
jquery-rails (~> 3.1.3)
jquery-rails (~> 4.0.0)
jquery-scrollto-rails (~> 1.4.3)
jquery-turbolinks (~> 2.1.0)
jquery-ui-rails (~> 4.2.1)
jquery-ui-rails (~> 5.0.0)
kaminari (~> 0.16.3)
letter_opener (~> 1.1.2)
mail_room (~> 0.6.1)
Loading
Loading
@@ -943,7 +945,7 @@ DEPENDENCIES
rubocop (~> 0.35.0)
ruby-fogbugz (~> 0.2.1)
sanitize (~> 2.0)
sass-rails (~> 4.0.5)
sass-rails (~> 5.0.0)
sdoc (~> 0.3.20)
seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9)
Loading
Loading
@@ -972,7 +974,7 @@ DEPENDENCIES
tinder (~> 1.10.0)
turbolinks (~> 2.5.0)
uglifier (~> 2.7.2)
underscore-rails (~> 1.4.4)
underscore-rails (~> 1.8.0)
unf (~> 0.1.4)
unicorn (~> 4.8.2)
unicorn-worker-killer (~> 0.4.2)
Loading
Loading
app/assets/images/brand_logo.png

26.4 KiB

app/assets/images/emoji.png

813 KiB

app/assets/images/gitlab_logo.png

5.07 KiB

Loading
Loading
@@ -5,7 +5,7 @@
# the compiled file.
#
#= require jquery
#= require jquery.ui.all
#= require jquery-ui
#= require jquery_ujs
#= require jquery.cookie
#= require jquery.endless-scroll
Loading
Loading
class @AwardsHandler
constructor: (@post_emoji_url, @noteable_type, @noteable_id, @aliases) ->
$(".add-award").click (event)->
event.stopPropagation()
event.preventDefault()
$(".emoji-menu").show()
$("html").click ->
if !$(event.target).closest(".emoji-menu").length
if $(".emoji-menu").is(":visible")
$(".emoji-menu").hide()
@renderFrequentlyUsedBlock()
@setupSearch()
 
addAward: (emoji) ->
emoji = @normilizeEmojiName(emoji)
@postEmoji emoji, =>
@addAwardToEmojiBar(emoji)
$(".emoji-menu").hide()
addAwardToEmojiBar: (emoji, custom_path = '') ->
addAwardToEmojiBar: (emoji) ->
@addEmojiToFrequentlyUsedList(emoji)
emoji = @normilizeEmojiName(emoji)
if @exist(emoji)
if @isActive(emoji)
Loading
Loading
@@ -17,7 +33,7 @@ class @AwardsHandler
counter.parent().addClass("active")
@addMeToAuthorList(emoji)
else
@createEmoji(emoji, custom_path)
@createEmoji(emoji)
 
exist: (emoji) ->
@findEmojiIcon(emoji).length > 0
Loading
Loading
@@ -27,15 +43,19 @@ class @AwardsHandler
 
decrementCounter: (emoji) ->
counter = @findEmojiIcon(emoji).siblings(".counter")
emojiIcon = counter.parent()
 
if parseInt(counter.text()) > 1
counter.text(parseInt(counter.text()) - 1)
counter.parent().removeClass("active")
emojiIcon.removeClass("active")
@removeMeFromAuthorList(emoji)
else if emoji =="thumbsup" || emoji == "thumbsdown"
emojiIcon.tooltip("destroy")
counter.text(0)
emojiIcon.removeClass("active")
else
award = counter.parent()
award.tooltip("destroy")
award.remove()
emojiIcon.tooltip("destroy")
emojiIcon.remove()
 
removeMeFromAuthorList: (emoji) ->
award_block = @findEmojiIcon(emoji).parent()
Loading
Loading
@@ -54,35 +74,39 @@ class @AwardsHandler
resetTooltip: (award) ->
award.tooltip("destroy")
 
# "destroy" call is asynchronous, this is why we need to set timeout.
# "destroy" call is asynchronous and there is no appropriate callback on it, this is why we need to set timeout.
setTimeout (->
award.tooltip()
), 200
 
createEmoji: (emoji, custom_path) ->
createEmoji: (emoji) ->
emojiCssClass = @resolveNameToCssClass(emoji)
nodes = []
nodes.push("<div class='award active' title='me'>")
nodes.push("<div class='icon' data-emoji='" + emoji + "'>")
nodes.push(@getImage(emoji, custom_path))
nodes.push("<div class='icon emoji-icon #{emojiCssClass}' data-emoji='#{emoji}'></div>")
nodes.push("<div class='counter'>1</div>")
nodes.push("</div>")
nodes.push("<div class='counter'>1")
nodes.push("</div></div>")
 
$(".awards-controls").before(nodes.join("\n"))
emoji_node = $(nodes.join("\n")).insertBefore(".awards-controls").find(".emoji-icon").data("emoji", emoji)
 
$(".award").tooltip()
 
getImage: (emoji, custom_path) ->
if custom_path
$("<img>").attr({src: custom_path, width: 20, height: 20}).wrap("<div>").parent().html()
resolveNameToCssClass: (emoji) ->
emoji_icon = $(".emoji-menu-content [data-emoji='#{emoji}']")
if emoji_icon.length > 0
unicodeName = emoji_icon.data("unicode-name")
else
$("li[data-emoji='" + emoji + "']").html()
# Find by alias
unicodeName = $(".emoji-menu-content [data-aliases*=':#{emoji}:']").data("unicode-name")
 
"emoji-#{unicodeName}"
 
postEmoji: (emoji, callback) ->
$.post @post_emoji_url, { note: {
note: ":" + emoji + ":"
note: ":#{emoji}:"
noteable_type: @noteable_type
noteable_id: @noteable_id
}},(data) ->
Loading
Loading
@@ -90,7 +114,7 @@ class @AwardsHandler
callback.call()
 
findEmojiIcon: (emoji) ->
$(".icon[data-emoji='" + emoji + "']")
$(".award [data-emoji='#{emoji}']")
 
scrollToAwards: ->
$('body, html').animate({
Loading
Loading
@@ -99,3 +123,43 @@ class @AwardsHandler
 
normilizeEmojiName: (emoji) ->
@aliases[emoji] || emoji
addEmojiToFrequentlyUsedList: (emoji) ->
frequently_used_emojis = @getFrequentlyUsedEmojis()
frequently_used_emojis.push(emoji)
$.cookie('frequently_used_emojis', frequently_used_emojis.join(","), { expires: 365 })
getFrequentlyUsedEmojis: ->
frequently_used_emojis = ($.cookie('frequently_used_emojis') || "").split(",")
_.compact(_.uniq(frequently_used_emojis))
renderFrequentlyUsedBlock: ->
frequently_used_emojis = @getFrequentlyUsedEmojis()
ul = $("<ul>")
for emoji in frequently_used_emojis
do (emoji) ->
$(".emoji-menu-content [data-emoji='#{emoji}']").closest("li").clone().appendTo(ul)
$("input.emoji-search").after(ul).after($("<h5>").text("Frequently used"))
setupSearch: ->
$("input.emoji-search").keyup (ev) =>
term = $(ev.target).val()
# Clean previous search results
$("ul.emoji-search,h5.emoji-search").remove()
if term
# Generate a search result block
h5 = $("<h5>").text("Search results").addClass("emoji-search")
found_emojis = @searchEmojis(term).show()
ul = $("<ul>").addClass("emoji-search").append(found_emojis)
$(".emoji-menu-content ul, .emoji-menu-content h5").hide()
$(".emoji-menu-content").append(h5).append(ul)
else
$(".emoji-menu-content").children().show()
searchEmojis: (term)->
$(".emoji-menu-content [data-emoji*='#{term}']").closest("li").clone()
Loading
Loading
@@ -35,7 +35,7 @@ class @BlobFileDropzone
return
 
this.on 'sending', (file, xhr, formData) ->
formData.append('new_branch', form.find('.js-new-branch').val())
formData.append('target_branch', form.find('.js-target-branch').val())
formData.append('create_merge_request', form.find('.js-create-merge-request').val())
formData.append('commit_message', form.find('.js-commit-message').val())
return
Loading
Loading
Loading
Loading
@@ -18,7 +18,7 @@ class @MergeRequestWidget
if data.state == "merged"
urlSuffix = if deleteSourceBranch then '?delete_source=true' else ''
 
window.location.href = window.location.href + urlSuffix
window.location.href = window.location.pathname + urlSuffix
else if data.merge_error
$('.mr-widget-body').html("<h4>" + data.merge_error + "</h4>")
else
Loading
Loading
class @NewBranchForm
constructor: (form, availableRefs) ->
@branchNameError = form.find('.js-branch-name-error')
@name = form.find('.js-branch-name')
@ref = form.find('#ref')
@setupAvailableRefs(availableRefs)
@setupRestrictions()
@addBinding()
@init()
addBinding: ->
@name.on 'blur', @validate
init: ->
@name.trigger 'blur' if @name.val().length > 0
setupAvailableRefs: (availableRefs) ->
@ref.autocomplete
source: availableRefs,
minLength: 1
setupRestrictions: ->
startsWith = {
pattern: /^(\/|\.)/g,
prefix: "can't start with",
conjunction: "or"
}
endsWith = {
pattern: /(\/|\.|\.lock)$/g,
prefix: "can't end in",
conjunction: "or"
}
invalid = {
pattern: /(\s|~|\^|:|\?|\*|\[|\\|\.\.|@\{|\/{2,}){1}/g
prefix: "can't contain",
conjunction: ", "
}
single = {
pattern: /^@+$/g
prefix: "can't be",
conjunction: "or"
}
@restrictions = [startsWith, invalid, endsWith, single]
validate: =>
@branchNameError.empty()
unique = (values, value) ->
values.push(value) unless value in values
values
formatter = (values, restriction) ->
formatted = values.map (value) ->
switch
when /\s/.test value then 'spaces'
when /\/{2,}/g.test value then 'consecutive slashes'
else "'#{value}'"
"#{restriction.prefix} #{formatted.join(restriction.conjunction)}"
validator = (errors, restriction) =>
matched = @name.val().match(restriction.pattern)
if matched
errors.concat formatter(matched.reduce(unique, []), restriction)
else
errors
errors = @restrictions.reduce validator, []
if errors.length > 0
errorMessage = $("<span/>").text(errors.join(', '))
@branchNameError.append(errorMessage)
class @NewCommitForm
constructor: (form) ->
@newBranch = form.find('.js-new-branch')
@newBranch = form.find('.js-target-branch')
@originalBranch = form.find('.js-original-branch')
@createMergeRequest = form.find('.js-create-merge-request')
@createMergeRequestContainer = form.find('.js-create-merge-request-container')
Loading
Loading
Loading
Loading
@@ -127,7 +127,7 @@ class @Notes
@initTaskList()
 
if note.award
awards_handler.addAwardToEmojiBar(note.note, note.emoji_path)
awards_handler.addAwardToEmojiBar(note.note)
awards_handler.scrollToAwards()
 
###
Loading
Loading
class @Project
constructor: ->
# Git protocol switcher
$('.js-protocol-switch').click ->
$('ul.clone-options-dropdown a').click ->
return if $(@).hasClass('active')
 
 
Loading
Loading
@@ -10,7 +10,8 @@ class @Project
# Add the active class for the clicked button
$(@).toggleClass('active')
 
url = $(@).data('clone')
url = $("#project_clone").val()
console.log("url",url)
 
# Update the input field
$('#project_clone').val(url)
Loading
Loading
Loading
Loading
@@ -8,17 +8,17 @@ class @ProjectsList
 
$(".projects-list-filter").keyup ->
terms = $(this).val()
uiBox = $(this).closest('.projects-list-holder')
uiBox = $('div.projects-list-holder')
if terms == "" || terms == undefined
uiBox.find(".projects-list li").show()
uiBox.find("ul.projects-list li").show()
else
uiBox.find(".projects-list li").each (index) ->
name = $(this).find(".filter-title").text()
uiBox.find("ul.projects-list li").each (index) ->
name = $(this).find("span.filter-title").text()
 
if name.toLowerCase().search(terms.toLowerCase()) == -1
$(this).hide()
else
$(this).show()
uiBox.find(".projects-list li.bottom").hide()
uiBox.find("ul.projects-list li.bottom").hide()
 
 
class @Star
constructor: ->
$('.project-home-panel .toggle-star').on('ajax:success', (e, data, status, xhr) ->
$this = $(this)
$starSpan = $this.find('span')
$starIcon = $this.find('i')
toggleStar = (isStarred) ->
$this.parent().find('span.count').text data.star_count
if isStarred
$starSpan.removeClass('starred').text 'Star'
$starIcon.removeClass('fa-star').addClass 'fa-star-o'
else
$starSpan.addClass('starred').text 'Unstar'
$starIcon.removeClass('fa-star-o').addClass 'fa-star'
return
toggleStar $starSpan.hasClass('starred')
return
).on 'ajax:error', (e, xhr, status, error) ->
new Flash('Star toggle failed. Try again later.', 'alert')
return
\ No newline at end of file
Loading
Loading
@@ -2,8 +2,8 @@
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require jquery.ui.datepicker
*= require jquery.ui.autocomplete
*= require jquery-ui/datepicker
*= require jquery-ui/autocomplete
*= require jquery.atwho
*= require select2
*= require_self
Loading
Loading
@@ -48,4 +48,4 @@
/*
* Styles for JS behaviors.
*/
@import "behaviors.scss";
\ No newline at end of file
@import "behaviors.scss";
@mixin btn-default {
@include border-radius(2px);
@include border-radius(3px);
border-width: 1px;
border-style: solid;
text-transform: uppercase;
font-size: 13px;
font-weight: 600;
font-size: 15px;
font-weight: 500;
line-height: 18px;
padding: 11px $gl-padding;
letter-spacing: .4px;
Loading
Loading
@@ -18,7 +17,7 @@
 
@mixin btn-middle {
@include btn-default;
@include border-radius(2px);
@include border-radius(3px);
padding: 11px 24px;
}
 
Loading
Loading
@@ -51,6 +50,10 @@
@include btn-color($blue-light, $border-blue-light, $blue-normal, $border-blue-normal, $blue-dark, $border-blue-dark, #FFFFFF);
}
 
@mixin btn-blue-medium {
@include btn-color($blue-medium-light, $border-blue-light, $blue-medium, $border-blue-normal, $blue-medium-dark, $border-blue-dark, #FFFFFF);
}
@mixin btn-orange {
@include btn-color($orange-light, $border-orange-light, $orange-normal, $border-orange-normal, $orange-dark, $border-orange-dark, #FFFFFF);
}
Loading
Loading
@@ -60,7 +63,7 @@
}
 
@mixin btn-gray {
@include btn-color($gray-light, $border-gray-light, $gray-normal, $border-gray-normal, $gray-dark, $border-gray-dark, #313236);
@include btn-color($gray-light, $border-gray-light, $gray-normal, $border-gray-light, $gray-dark, $border-gray-dark, #313236);
}
 
@mixin btn-white {
Loading
Loading
@@ -75,6 +78,10 @@
padding: 5px 10px;
}
 
&.btn-nr {
padding: 7px 10px;
}
&.btn-xs {
padding: 1px 5px;
}
Loading
Loading
@@ -91,11 +98,15 @@
@include btn-gray;
}
 
&.btn-primary,
&.btn-primary {
@include btn-blue-medium;
}
&.btn-info {
@include btn-blue;
}
 
&.btn-close,
&.btn-warning {
@include btn-orange;
}
Loading
Loading
@@ -110,20 +121,8 @@
float: right;
}
 
&.btn-close {
color: $gl-danger;
border-color: $gl-danger;
&:hover {
color: #B94A48;
}
}
&.btn-reopen {
color: $gl-success;
border-color: $gl-success;
&:hover {
color: #468847;
}
/* should be same as parent class for now */
}
 
&.btn-grouped {
Loading
Loading
Loading
Loading
@@ -383,7 +383,7 @@ table {
}
}
 
.center-top-menu {
.center-top-menu, .left-top-menu {
@include nav-menu;
text-align: center;
margin-top: 5px;
Loading
Loading
@@ -417,6 +417,11 @@ table {
}
}
 
.left-top-menu {
text-align: left;
border-bottom: 1px solid #EEE;
}
.center-middle-menu {
@include nav-menu;
padding: 0;
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@
*/
 
.status-box {
@include border-radius(2px);
@include border-radius(3px);
 
display: block;
float: left;
Loading
Loading
@@ -25,7 +25,7 @@
}
 
&.status-box-open {
background-color: #019875;
background-color: $green-light;
color: #FFF;
}
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment