Commit 9b3b521d authored by Andriy Dyadyura's avatar Andriy Dyadyura

Merge branch 'master' of https://gitlab.com/gitlab-org/gitlab-ce into button-height

parents f30f518f e1e39b61
......@@ -190,7 +190,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'
......@@ -202,9 +202,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'
......
......@@ -372,15 +372,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)
......@@ -647,12 +648,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)
......@@ -878,10 +880,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)
......@@ -934,7 +936,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)
......
......@@ -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
......
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()
addAward: (emoji) ->
emoji = @normilizeEmojiName(emoji)
@postEmoji emoji, =>
@addAwardToEmojiBar(emoji)
$(".emoji-menu").hide()
addAwardToEmojiBar: (emoji, custom_path = '') ->
addAwardToEmojiBar: (emoji) ->
emoji = @normilizeEmojiName(emoji)
if @exist(emoji)
if @isActive(emoji)
......@@ -17,7 +28,7 @@ class @AwardsHandler
counter.parent().addClass("active")
@addMeToAuthorList(emoji)
else
@createEmoji(emoji, custom_path)
@createEmoji(emoji)
exist: (emoji) ->
@findEmojiIcon(emoji).length > 0
......@@ -54,31 +65,29 @@ 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()
else
$("li[data-emoji='" + emoji + "']").html()
resolveNameToCssClass: (emoji) ->
unicodeName = $(".emoji-menu-content [data-emoji='?']".replace("?", emoji)).data("unicode-name")
"emoji-" + unicodeName
postEmoji: (emoji, callback) ->
$.post @post_emoji_url, { note: {
......@@ -90,7 +99,7 @@ class @AwardsHandler
callback.call()
findEmojiIcon: (emoji) ->
$(".icon[data-emoji='" + emoji + "']")
$(".award [data-emoji='" + emoji + "']")
scrollToAwards: ->
$('body, html').animate({
......
......@@ -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()
###
......
......@@ -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
......@@ -48,4 +48,4 @@
/*
* Styles for JS behaviors.
*/
@import "behaviors.scss";
\ No newline at end of file
@import "behaviors.scss";
......@@ -2,6 +2,12 @@
@include clearfix;
line-height: 34px;
.emoji-icon {
width: 20px;
height: 20px;
margin: 7px 0 0 5px;
}
.award {
@include border-radius(5px);
......@@ -40,6 +46,7 @@
}
.awards-controls {
position: relative;
margin-left: 10px;
float: left;
......@@ -55,32 +62,60 @@
}
}
.awards-menu {
padding: $gl-padding;
min-width: 214px;
> li {
cursor: pointer;
width: 30px;
height: 30px;
text-align: center;
@include border-radius(5px);
.emoji-menu{
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175);
box-shadow: 0 6px 12px rgba(0,0,0,.175);
.emoji-menu-content {
padding: $gl-padding;
width: 300px;
height: 300px;
overflow-y: scroll;
h5 {
clear: left;
}
img {
margin-bottom: 2px;
ul {
list-style-type: none;
margin-left: -20px;
margin-bottom: 20px;
overflow: auto;
}
&:hover {
background-color: #ccc;
li {
cursor: pointer;
width: 30px;
height: 30px;
text-align: center;
float: left;
margin: 3px;
list-decorate: none;
@include border-radius(5px);
&:hover {
background-color: #ccc;
}
}
}
}
}
.awards-menu{
li {
float: left;
margin: 3px;
}
}
}
This diff is collapsed.
......@@ -19,8 +19,10 @@ module Ci
@error = e.message
@status = false
rescue
@error = "Undefined error"
@error = 'Undefined error'
@status = false
ensure
render :show
end
end
end
......@@ -139,7 +139,6 @@ class Projects::NotesController < Projects::ApplicationController
discussion_id: note.discussion_id,
html: note_to_html(note),
award: note.is_award,
emoji_path: note.is_award ? view_context.image_url(::AwardEmoji.path_to_emoji_image(note.note)) : "",
note: note.note,
discussion_html: note_to_discussion_html(note),
discussion_with_diff_html: note_to_discussion_with_diff_html(note)
......
......@@ -94,11 +94,13 @@ module IssuesHelper
end.sort.to_sentence(last_word_connector: ', or ')
end
def url_to_emoji(name)
emoji_path = ::AwardEmoji.path_to_emoji_image(name)
url_to_image(emoji_path)
rescue StandardError
""
def emoji_icon(name, unicode = nil)
unicode ||= Emoji.emoji_filename(name)
content_tag :div, "",
class: "icon emoji-icon emoji-#{unicode}",
"data-emoji" => name,
"data-unicode-name" => unicode
end
def emoji_author_list(notes, current_user)
......@@ -109,10 +111,6 @@ module IssuesHelper
list.join(", ")
end
def emoji_list
::AwardEmoji::EMOJI_LIST
end
def note_active_class(notes, current_user)
if current_user && notes.pluck(:author_id).include?(current_user.id)
"active"
......
......@@ -134,4 +134,8 @@ class ApplicationSetting < ActiveRecord::Base
/x)
self.restricted_signup_domains.reject! { |d| d.empty? }
end
def runners_registration_token
ensure_runners_registration_token!
end
end
......@@ -18,15 +18,16 @@ module TokenAuthenticatable
define_method("ensure_#{token_field}") do
current_token = read_attribute(token_field)
if current_token.blank?
write_attribute(token_field, generate_token_for(token_field))
else
current_token
end
current_token.blank? ? write_new_token(token_field) : current_token
end
define_method("ensure_#{token_field}!") do
send("reset_#{token_field}!") if read_attribute(token_field).blank?
read_attribute(token_field)
end
define_method("reset_#{token_field}!") do
write_attribute(token_field, generate_token_for(token_field))
write_new_token(token_field)
save!
end
end
......@@ -34,7 +35,12 @@ module TokenAuthenticatable
private
def generate_token_for(token_field)
def write_new_token(token_field)
new_token = generate_token(token_field)
write_attribute(token_field, new_token)
end
def generate_token(token_field)
loop do
token = Devise.friendly_token
break token unless self.class.unscoped.find_by(token_field => token)
......
......@@ -3,7 +3,7 @@
To register a new runner you should enter the following registration token.
With this token the runner will request a unique runner token and use that for future communication.
Registration token is
%code{ id: 'runners-token' } #{current_application_settings.ensure_runners_registration_token}
%code{ id: 'runners-token' } #{current_application_settings.runners_registration_token}
.bs-callout.clearfix
.pull-left
......
......@@ -41,5 +41,3 @@
%i.fa.fa-remove.incorrect-syntax
%b Error:
= @error
:plain
$(".results").html("#{escape_javascript(render "create")}")
\ No newline at end of file
%h2 Check your .gitlab-ci.yml
%hr
= form_tag ci_lint_path, method: :post, remote: true do
.control-group
= label_tag :content, "Content of .gitlab-ci.yml", class: 'control-label'
.controls
= text_area_tag :content, nil, class: 'form-control span1', rows: 7, require: true
.row
= form_tag ci_lint_path, method: :post do
.form-group
= label_tag :content, 'Content of .gitlab-ci.yml', class: 'control-label text-nowrap'
.col-sm-12
= text_area_tag :content, nil, class: 'form-control span1', rows: 7, require: true
.col-sm-12
.pull-left.prepend-top-10
= submit_tag 'Validate', class: 'btn btn-success submit-yml'
.control-group.clearfix
.controls.pull-left.prepend-top-10
= submit_tag "Validate", class: 'btn btn-success submit-yml'
%p.text-center.loading
%i.fa.fa-refresh.fa-spin
.results.prepend-top-20
:javascript
$(".loading").hide();
$('form').bind('ajax:beforeSend', function() {
$(".loading").show();
});
$('form').bind('ajax:complete', function() {
$(".loading").hide();
});
.row.prepend-top-20
.col-sm-12
.results
= render partial: 'create' if defined?(@status)
.awards.votes-block
- votable.notes.awards.grouped_awards.each do |emoji, notes|
.award{class: (note_active_class(notes, current_user)), title: emoji_author_list(notes, current_user)}
.icon{"data-emoji" => "#{emoji}"}
= image_tag url_to_emoji(emoji), height: "20px", width: "20px"
= emoji_icon(emoji)
.counter
= notes.count
- if current_user
.dropdown.awards-controls
.awards-controls
%a.add-award{"data-toggle" => "dropdown", "data-target" => "#", "href" => "#"}
= icon('smile-o')
%ul.dropdown-menu.awards-menu
- emoji_list.each do |emoji|
%li{"data-emoji" => "#{emoji}"}= image_tag url_to_emoji(emoji), height: "20px", width: "20px"
.emoji-menu
.emoji-menu-content
- AwardEmoji.emoji_by_category.each do |category, emojis|
%h5= AwardEmoji::CATEGORIES[category]
%ul
- emojis.each do |emoji|
%li
= emoji_icon(emoji["name"], emoji["unicode"])
- if current_user
:coffeescript
......@@ -20,10 +24,16 @@
noteable_type = "#{votable.class.name.underscore}"
noteable_id = "#{votable.id}"
aliases = #{AwardEmoji::ALIASES.to_json}
window.awards_handler = new AwardsHandler(post_emoji_url, noteable_type, noteable_id, aliases)
$(".awards-menu li").click (e)->
emoji = $(this).data("emoji")
window.awards_handler = new AwardsHandler(
post_emoji_url,
noteable_type,
noteable_id,
aliases
)
$(".emoji-menu-content li").click (e)->
emoji = $(this).find(".emoji-icon").data("emoji")
awards_handler.addAward(emoji)
$(".awards").on "click", ".award", (e)->
......@@ -31,3 +41,5 @@
awards_handler.addAward(emoji)
$(".award").tooltip()
$(".emoji-menu-content").niceScroll({cursorwidth: "7px", autohidemode: false})
......@@ -24,6 +24,7 @@
### Examples
+ [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
+ [Test and deploy Ruby applications to Heroku](examples/test-and-deploy-ruby-application-to-heroku.md)
+ [Test and deploy Python applications to Heroku](examples/test-and-deploy-python-application-to-heroku.md)
+ [Test Clojure applications](examples/test-clojure-application.md)
......
......@@ -13,6 +13,11 @@ Feature: Award Emoji
Then I have award added
And I can remove it by clicking to icon
@javascript
Scenario: I can see the list of emoji categories
Given I click to emoji-picker
Then I can see the activity and food categories
@javascript
Scenario: I add award emoji using regular comment
Given I leave comment with a single emoji
......
......@@ -15,8 +15,8 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps
end
step 'I click to emoji in the picker' do
page.within '.awards-menu' do
page.first('img').click
page.within '.emoji-menu' do
page.first('.emoji-icon').click
end
end
......@@ -27,6 +27,13 @@ class Spinach::Features::AwardEmoji < Spinach::FeatureSteps
end
end
step 'I can see the activity and food categories' do
page.within '.emoji-menu' do
expect(page).to_not have_selector 'Activity'
expect(page).to_not have_selector 'Food'
end
end
step 'I have award added' do
page.within '.awards' do
expect(page).to have_selector '.award'
......
class AwardEmoji
EMOJI_LIST = [
"+1", "-1", "100", "blush", "heart", "smile", "rage",
"beers", "disappointed", "ok_hand",
"helicopter", "shit", "airplane", "alarm_clock",
"ambulance", "anguished", "two_hearts", "wink"
]
ALIASES = {
pout: "rage",
satisfied: "laughing",
......@@ -37,11 +30,41 @@ class AwardEmoji
squirrel: "shipit"
}.with_indifferent_access
def self.path_to_emoji_image(name)
"emoji/#{Emoji.emoji_filename(name)}.png"
end
CATEGORIES = {
other: "Other",
objects: "Objects",
places: "Places",
travel_places: "Travel",
emoticons: "Emoticons",
objects_symbols: "Symbols",
nature: "Nature",
celebration: "Celebration",
people: "People",
activity: "Activity",
flags: "Flags",
food_drink: "Food"
}.with_indifferent_access
def self.normilize_emoji_name(name)
ALIASES[name] || name
end
def self.emoji_by_category
unless @emoji_by_category
@emoji_by_category = {}
emojis_added = []
Emoji.emojis.each do |emoji_name, data|
next if emojis_added.include?(data["name"])
emojis_added << data["name"]
@emoji_by_category[data["category"]] ||= []
@emoji_by_category[data["category"]] << data
end
@emoji_by_category = @emoji_by_category.sort.to_h
end
@emoji_by_category
end
end
......@@ -19,7 +19,7 @@ module Ci
end
def runner_registration_token_valid?
params[:token] == current_application_settings.ensure_runners_registration_token
params[:token] == current_application_settings.runners_registration_token
end
def update_runner_last_contact
......
......@@ -63,7 +63,7 @@ describe "Admin Runners" do
end
describe 'runners registration token' do
let!(:token) { current_application_settings.ensure_runners_registration_token }
let!(:token) { current_application_settings.runners_registration_token }
before { visit admin_runners_path }
it 'has a registration token' do
......
require 'spec_helper'
describe 'CI Lint' do
before do
login_as :user
end
describe 'YAML parsing' do
before do
visit ci_lint_path
fill_in 'content', with: yaml_content
click_on 'Validate'
end
context 'YAML is correct' do
let(:yaml_content) do
File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
end
it 'Yaml parsing' do
within "table" do
expect(page).to have_content('Job - rspec')
expect(page).to have_content('Job - spinach')
expect(page).to have_content('Deploy Job - staging')
expect(page).to have_content('Deploy Job - production')
end
end
end
context 'YAML is incorrect' do
let(:yaml_content) { '' }
it 'displays information about an error' do
expect(page).to have_content('Status: syntax is incorrect')
expect(page).to have_content('Error: Please provide content of .gitlab-ci.yml')
end
end
end
end
require 'spec_helper'
describe "Lint" do
before do
login_as :user
end
it "Yaml parsing", js: true do
content = File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
visit ci_lint_path
fill_in "content", with: content
click_on "Validate"
within "table" do
expect(page).to have_content("Job - rspec")
expect(page).to have_content("Job - spinach")
expect(page).to have_content("Deploy Job - staging")
expect(page).to have_content("Deploy Job - production")
end
end
it "Yaml parsing with error", js: true do
visit ci_lint_path
fill_in "content", with: ""
click_on "Validate"
expect(page).to have_content("Status: syntax is incorrect")
expect(page).to have_content("Error: Please provide content of .gitlab-ci.yml")
end
end
......@@ -127,18 +127,6 @@ describe IssuesHelper do
it { is_expected.to eq("!1, !2, or !3") }
end
describe "#url_to_emoji" do
it "returns url" do
expect(url_to_emoji("smile")).to include("emoji/1F604.png")
end
end
describe "#emoji_list" do
it "returns url" do
expect(emoji_list).to be_kind_of(Array)
end
end
describe "#note_active_class" do
before do
@note = create :note
......
......@@ -2,7 +2,8 @@ require 'spec_helper'
shared_examples 'TokenAuthenticatable' do
describe 'dynamically defined methods' do
it { expect(described_class).to be_private_method_defined(:generate_token_for) }
it { expect(described_class).to be_private_method_defined(:generate_token) }
it { expect(described_class).to be_private_method_defined(:write_new_token) }
it { expect(described_class).to respond_to("find_by_#{token_field}") }
it { is_expected.to respond_to("ensure_#{token_field}") }
it { is_expected.to respond_to("reset_#{token_field}!") }
......@@ -24,11 +25,11 @@ describe ApplicationSetting, 'TokenAuthenticatable' do
it_behaves_like 'TokenAuthenticatable'
describe 'generating new token' do
subject { described_class.new }
let(:token) { subject.send(token_field) }
context 'token is not generated yet' do
it { expect(token).to be nil }
describe 'token field accessor' do
subject { described_class.new.send(token_field) }
it { is_expected.to_not be_blank }
end
describe 'ensured token' do
subject { described_class.new.send("ensure_#{token_field}") }
......@@ -36,11 +37,21 @@ describe ApplicationSetting, 'TokenAuthenticatable' do
it { is_expected.to be_a String }
it { is_expected.to_not be_blank }
end
describe 'ensured! token' do
subject { described_class.new.send("ensure_#{token_field}!") }
it 'should persist new token' do
expect(subject).to eq described_class.current[token_field]
end
end
end
context 'token is generated' do
before { subject.send("reset_#{token_field}!") }
it { expect(token).to be_a String }
it 'persists a new token 'do
expect(subject.send(:read_attribute, token_field)).to be_a String
end
end
end
......
......@@ -8,7 +8,6 @@ describe Ci::API::API do
before do
stub_gitlab_calls
stub_application_setting(ensure_runners_registration_token: registration_token)
stub_application_setting(runners_registration_token: registration_token)
end
......
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