summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo Sumaran <alfredo@gitlab.com>2017-04-14 14:43:20 +0000
committerAlfredo Sumaran <alfredo@gitlab.com>2017-04-14 14:43:20 +0000
commite04aef5ccec442c18f3df90db270af26ec9a79f2 (patch)
tree9a4f98d9562db9cf583150ac49ee53f31e153fb7
parent3c9318a8c58f638f57cfe86cb2f84625445996c8 (diff)
parent04e2dde538b7a91de0ffdd09d355e9c990b4c7b1 (diff)
downloadgitlab-ce-e04aef5ccec442c18f3df90db270af26ec9a79f2.tar.gz
Merge branch 'frontend_prevent_authored_awardable_votes' into 'master'
frontend prevent authored votes Closes #21881 See merge request !6260
-rw-r--r--app/assets/javascripts/awards_handler.js44
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js4
-rw-r--r--app/assets/stylesheets/framework/awards.scss20
-rw-r--r--app/helpers/issues_helper.rb8
-rw-r--r--app/views/award_emoji/_awards_block.html.haml4
-rw-r--r--app/views/projects/notes/_note.html.haml3
-rw-r--r--changelogs/unreleased/6260-frontend-prevent-authored-votes.yml4
-rw-r--r--spec/javascripts/awards_handler_spec.js25
8 files changed, 100 insertions, 12 deletions
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index ce426741637..d8a73b0f5e7 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -1,3 +1,5 @@
+/* global Flash */
+
import Cookies from 'js-cookie';
import emojiMap from 'emojis/digests.json';
@@ -124,6 +126,8 @@ AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) {
}
const $menu = $('.emoji-menu');
+ const $thumbsBtn = $menu.find('[data-name="thumbsup"], [data-name="thumbsdown"]').parent();
+ const $userAuthored = this.isUserAuthored($addBtn);
if ($menu.length) {
if ($menu.is('.is-visible')) {
$addBtn.removeClass('is-active');
@@ -147,6 +151,8 @@ AwardsHandler.prototype.showEmojiMenu = function showEmojiMenu($addBtn) {
}, 200);
});
}
+
+ $thumbsBtn.toggleClass('disabled', $userAuthored);
};
// Create the emoji menu with the first category of emojis.
@@ -259,7 +265,8 @@ AwardsHandler.prototype.addAward = function addAward(
callback,
) {
const normalizedEmoji = this.normalizeEmojiName(emoji);
- this.postEmoji(awardUrl, normalizedEmoji, () => {
+ const $emojiButton = this.findEmojiIcon(votesBlock, normalizedEmoji).parent();
+ this.postEmoji($emojiButton, awardUrl, normalizedEmoji, () => {
this.addAwardToEmojiBar(votesBlock, normalizedEmoji, checkMutuality);
return typeof callback === 'function' ? callback() : undefined;
});
@@ -324,6 +331,10 @@ AwardsHandler.prototype.isActive = function isActive($emojiButton) {
return $emojiButton.hasClass('active');
};
+AwardsHandler.prototype.isUserAuthored = function isUserAuthored($button) {
+ return $button.hasClass('js-user-authored');
+};
+
AwardsHandler.prototype.decrementCounter = function decrementCounter($emojiButton, emoji) {
const counter = $('.js-counter', $emojiButton);
const counterNumber = parseInt(counter.text(), 10);
@@ -428,20 +439,35 @@ AwardsHandler.prototype.createEmoji = function createEmoji(votesBlock, emoji) {
});
};
-AwardsHandler.prototype.postEmoji = function postEmoji(awardUrl, emoji, callback) {
- return $.post(awardUrl, {
- name: emoji,
- }, (data) => {
- if (data.ok) {
- callback();
- }
- });
+AwardsHandler.prototype.postEmoji = function postEmoji($emojiButton, awardUrl, emoji, callback) {
+ if (this.isUserAuthored($emojiButton)) {
+ this.userAuthored($emojiButton);
+ } else {
+ $.post(awardUrl, {
+ name: emoji,
+ }, (data) => {
+ if (data.ok) {
+ callback();
+ }
+ }).fail(() => new Flash('Something went wrong on our end.'));
+ }
};
AwardsHandler.prototype.findEmojiIcon = function findEmojiIcon(votesBlock, emoji) {
return votesBlock.find(`.js-emoji-btn [data-name="${emoji}"]`);
};
+AwardsHandler.prototype.userAuthored = function userAuthored($emojiButton) {
+ const oldTitle = this.getAwardTooltip($emojiButton);
+ const newTitle = 'You cannot vote on your own issue, MR and note';
+ gl.utils.updateTooltipTitle($emojiButton, newTitle).tooltip('show');
+ // Restore tooltip back to award list
+ return setTimeout(() => {
+ $emojiButton.tooltip('hide');
+ gl.utils.updateTooltipTitle($emojiButton, oldTitle);
+ }, 2800);
+};
+
AwardsHandler.prototype.scrollToAwards = function scrollToAwards() {
const options = {
scrollTop: $('.awards').offset().top - 110,
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index e1e6ca25446..33c900e264b 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -47,6 +47,10 @@
}
};
+ gl.utils.updateTooltipTitle = function($tooltipEl, newTitle) {
+ return $tooltipEl.attr('title', newTitle).tooltip('fixTitle');
+ };
+
w.gl.utils.disableButtonIfEmptyField = function(field_selector, button_selector, event_name) {
event_name = event_name || 'input';
var closest_submit, field, that;
diff --git a/app/assets/stylesheets/framework/awards.scss b/app/assets/stylesheets/framework/awards.scss
index b849cc2d853..f614f262316 100644
--- a/app/assets/stylesheets/framework/awards.scss
+++ b/app/assets/stylesheets/framework/awards.scss
@@ -38,6 +38,15 @@
height: 300px;
overflow-y: scroll;
}
+
+ .disabled {
+ cursor: default;
+ opacity: 0.5;
+
+ &:hover {
+ transform: none;
+ }
+ }
}
.emoji-search {
@@ -154,6 +163,17 @@
}
}
+ &.user-authored {
+ cursor: default;
+ opacity: 0.65;
+
+ &:hover,
+ &:active {
+ background-color: $white-light;
+ border-color: $border-color;
+ }
+ }
+
&.btn {
&:focus {
outline: 0;
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 6978b0c89fd..82288f1da35 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -110,6 +110,14 @@ module IssuesHelper
end
end
+ def award_user_authored_class(award)
+ if award == 'thumbsdown' || award == 'thumbsup'
+ 'user-authored js-user-authored'
+ else
+ ''
+ end
+ end
+
def awards_sort(awards)
awards.sort_by do |award, notes|
if award == "thumbsup"
diff --git a/app/views/award_emoji/_awards_block.html.haml b/app/views/award_emoji/_awards_block.html.haml
index 3ca45fbf751..9aabfb49a29 100644
--- a/app/views/award_emoji/_awards_block.html.haml
+++ b/app/views/award_emoji/_awards_block.html.haml
@@ -1,8 +1,9 @@
- grouped_emojis = awardable.grouped_awards(with_thumbs: inline)
+- user_authored = awardable.user_authored?(current_user)
.awards.js-awards-block{ class: ("hidden" if !inline && grouped_emojis.empty?), data: { award_url: toggle_award_url(awardable) } }
- awards_sort(grouped_emojis).each do |emoji, awards|
%button.btn.award-control.js-emoji-btn.has-tooltip{ type: "button",
- class: (award_state_class(awards, current_user)),
+ class: [(award_state_class(awards, current_user)), (award_user_authored_class(emoji) if user_authored)],
data: { placement: "bottom", title: award_user_list(awards, current_user) } }
= emoji_icon(emoji)
%span.award-control-text.js-counter
@@ -12,6 +13,7 @@
.award-menu-holder.js-award-holder
%button.btn.award-control.has-tooltip.js-add-award{ type: 'button',
'aria-label': 'Add emoji',
+ class: ("js-user-authored" if user_authored),
data: { title: 'Add emoji', placement: "bottom" } }
%span{ class: "award-control-icon award-control-icon-neutral" }= custom_icon('emoji_slightly_smiling_face')
%span{ class: "award-control-icon award-control-icon-positive" }= custom_icon('emoji_smiley')
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 1f021ad77e5..a6fbe2c441f 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -59,7 +59,8 @@
- if current_user
- if note.emoji_awardable?
- = link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do
+ - user_authored = note.user_authored?(current_user)
+ = link_to '#', title: 'Award Emoji', class: "note-action-button note-emoji-button js-add-award js-note-emoji #{'js-user-authored' if user_authored}", data: { position: 'right' } do
= icon('spinner spin')
%span{ class: "link-highlight award-control-icon-neutral" }= custom_icon('emoji_slightly_smiling_face')
%span{ class: "link-highlight award-control-icon-positive" }= custom_icon('emoji_smiley')
diff --git a/changelogs/unreleased/6260-frontend-prevent-authored-votes.yml b/changelogs/unreleased/6260-frontend-prevent-authored-votes.yml
new file mode 100644
index 00000000000..82e852fa197
--- /dev/null
+++ b/changelogs/unreleased/6260-frontend-prevent-authored-votes.yml
@@ -0,0 +1,4 @@
+---
+title: 'Frontend prevent authored votes'
+merge_request: 6260
+author: Barthc
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index ea7753c7a1d..d6d50304086 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -3,6 +3,8 @@
import Cookies from 'js-cookie';
import AwardsHandler from '~/awards_handler';
+require('~/lib/utils/common_utils');
+
(function() {
var awardsHandler, lazyAssert, urlRoot, openAndWaitForEmojiMenu;
@@ -28,7 +30,7 @@ import AwardsHandler from '~/awards_handler';
loadFixtures('issues/issue_with_comment.html.raw');
awardsHandler = new AwardsHandler;
spyOn(awardsHandler, 'postEmoji').and.callFake((function(_this) {
- return function(url, emoji, cb) {
+ return function(button, url, emoji, cb) {
return cb();
};
})(this));
@@ -115,6 +117,27 @@ import AwardsHandler from '~/awards_handler';
return expect($emojiButton.next('.js-counter').text()).toBe('4');
});
});
+ describe('::userAuthored', function() {
+ it('should update tooltip to user authored title', function() {
+ var $thumbsUpEmoji, $votesBlock;
+ $votesBlock = $('.js-awards-block').eq(0);
+ $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.userAuthored($thumbsUpEmoji);
+ return expect($thumbsUpEmoji.data("original-title")).toBe("You cannot vote on your own issue, MR and note");
+ });
+ it('should restore tooltip back to initial vote list', function() {
+ var $thumbsUpEmoji, $votesBlock;
+ jasmine.clock().install();
+ $votesBlock = $('.js-awards-block').eq(0);
+ $thumbsUpEmoji = $votesBlock.find('[data-name=thumbsup]').parent();
+ $thumbsUpEmoji.attr('data-title', 'sam');
+ awardsHandler.userAuthored($thumbsUpEmoji);
+ jasmine.clock().tick(2801);
+ jasmine.clock().uninstall();
+ return expect($thumbsUpEmoji.data("original-title")).toBe("sam");
+ });
+ });
describe('::getAwardUrl', function() {
return it('returns the url for request', function() {
return expect(awardsHandler.getAwardUrl()).toBe('http://test.host/frontend-fixtures/issues-project/issues/1/toggle_award_emoji');