From 45ca47aa9e0246cb3064d02151808aeb8ed5c2f2 Mon Sep 17 00:00:00 2001 From: Fatih Acet Date: Wed, 10 Aug 2016 15:56:33 +0300 Subject: Added lock/unlock issue discussion widget into right sidebar. --- app/assets/javascripts/right_sidebar.js | 201 ---------------------- app/assets/javascripts/right_sidebar.js.es6 | 218 ++++++++++++++++++++++++ app/assets/stylesheets/pages/issuable.scss | 4 + app/views/shared/issuable/_lock_issue.html.haml | 21 +++ app/views/shared/issuable/_sidebar.html.haml | 3 + 5 files changed, 246 insertions(+), 201 deletions(-) delete mode 100644 app/assets/javascripts/right_sidebar.js create mode 100644 app/assets/javascripts/right_sidebar.js.es6 create mode 100644 app/views/shared/issuable/_lock_issue.html.haml diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js deleted file mode 100644 index dc4d5113826..00000000000 --- a/app/assets/javascripts/right_sidebar.js +++ /dev/null @@ -1,201 +0,0 @@ -(function() { - var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - - this.Sidebar = (function() { - function Sidebar(currentUser) { - this.toggleTodo = bind(this.toggleTodo, this); - this.sidebar = $('aside'); - this.addEventListeners(); - } - - Sidebar.prototype.addEventListeners = function() { - this.sidebar.on('click', '.sidebar-collapsed-icon', this, this.sidebarCollapseClicked); - $('.dropdown').on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden); - $('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading); - $('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded); - $(document).off('click', '.js-sidebar-toggle').on('click', '.js-sidebar-toggle', function(e, triggered) { - var $allGutterToggleIcons, $this, $thisIcon; - e.preventDefault(); - $this = $(this); - $thisIcon = $this.find('i'); - $allGutterToggleIcons = $('.js-sidebar-toggle i'); - if ($thisIcon.hasClass('fa-angle-double-right')) { - $allGutterToggleIcons.removeClass('fa-angle-double-right').addClass('fa-angle-double-left'); - $('aside.right-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); - $('.page-with-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); - } else { - $allGutterToggleIcons.removeClass('fa-angle-double-left').addClass('fa-angle-double-right'); - $('aside.right-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); - $('.page-with-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); - } - if (!triggered) { - return $.cookie("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'), { - path: '/' - }); - } - }); - return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo); - }; - - Sidebar.prototype.toggleTodo = function(e) { - var $btnText, $this, $todoLoading, ajaxType, url; - $this = $(e.currentTarget); - $todoLoading = $('.js-issuable-todo-loading'); - $btnText = $('.js-issuable-todo-text', $this); - ajaxType = $this.attr('data-delete-path') ? 'DELETE' : 'POST'; - if ($this.attr('data-delete-path')) { - url = "" + ($this.attr('data-delete-path')); - } else { - url = "" + ($this.data('url')); - } - return $.ajax({ - url: url, - type: ajaxType, - dataType: 'json', - data: { - issuable_id: $this.data('issuable-id'), - issuable_type: $this.data('issuable-type') - }, - beforeSend: (function(_this) { - return function() { - return _this.beforeTodoSend($this, $todoLoading); - }; - })(this) - }).done((function(_this) { - return function(data) { - return _this.todoUpdateDone(data, $this, $btnText, $todoLoading); - }; - })(this)); - }; - - Sidebar.prototype.beforeTodoSend = function($btn, $todoLoading) { - $btn.disable(); - return $todoLoading.removeClass('hidden'); - }; - - Sidebar.prototype.todoUpdateDone = function(data, $btn, $btnText, $todoLoading) { - var $todoPendingCount; - $todoPendingCount = $('.todos-pending-count'); - $todoPendingCount.text(data.count); - $btn.enable(); - $todoLoading.addClass('hidden'); - if (data.count === 0) { - $todoPendingCount.addClass('hidden'); - } else { - $todoPendingCount.removeClass('hidden'); - } - if (data.delete_path != null) { - $btn.attr('aria-label', $btn.data('mark-text')).attr('data-delete-path', data.delete_path); - return $btnText.text($btn.data('mark-text')); - } else { - $btn.attr('aria-label', $btn.data('todo-text')).removeAttr('data-delete-path'); - return $btnText.text($btn.data('todo-text')); - } - }; - - Sidebar.prototype.sidebarDropdownLoading = function(e) { - var $loading, $sidebarCollapsedIcon, i, img; - $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon'); - img = $sidebarCollapsedIcon.find('img'); - i = $sidebarCollapsedIcon.find('i'); - $loading = $(''); - if (img.length) { - img.before($loading); - return img.hide(); - } else if (i.length) { - i.before($loading); - return i.hide(); - } - }; - - Sidebar.prototype.sidebarDropdownLoaded = function(e) { - var $sidebarCollapsedIcon, i, img; - $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon'); - img = $sidebarCollapsedIcon.find('img'); - $sidebarCollapsedIcon.find('i.fa-spin').remove(); - i = $sidebarCollapsedIcon.find('i'); - if (img.length) { - return img.show(); - } else { - return i.show(); - } - }; - - Sidebar.prototype.sidebarCollapseClicked = function(e) { - var $block, sidebar; - if ($(e.currentTarget).hasClass('dont-change-state')) { - return; - } - sidebar = e.data; - e.preventDefault(); - $block = $(this).closest('.block'); - return sidebar.openDropdown($block); - }; - - Sidebar.prototype.openDropdown = function(blockOrName) { - var $block; - $block = _.isString(blockOrName) ? this.getBlock(blockOrName) : blockOrName; - $block.find('.edit-link').trigger('click'); - if (!this.isOpen()) { - this.setCollapseAfterUpdate($block); - return this.toggleSidebar('open'); - } - }; - - Sidebar.prototype.setCollapseAfterUpdate = function($block) { - $block.addClass('collapse-after-update'); - return $('.page-with-sidebar').addClass('with-overlay'); - }; - - Sidebar.prototype.onSidebarDropdownHidden = function(e) { - var $block, sidebar; - sidebar = e.data; - e.preventDefault(); - $block = $(this).closest('.block'); - return sidebar.sidebarDropdownHidden($block); - }; - - Sidebar.prototype.sidebarDropdownHidden = function($block) { - if ($block.hasClass('collapse-after-update')) { - $block.removeClass('collapse-after-update'); - $('.page-with-sidebar').removeClass('with-overlay'); - return this.toggleSidebar('hide'); - } - }; - - Sidebar.prototype.triggerOpenSidebar = function() { - return this.sidebar.find('.js-sidebar-toggle').trigger('click'); - }; - - Sidebar.prototype.toggleSidebar = function(action) { - if (action == null) { - action = 'toggle'; - } - if (action === 'toggle') { - this.triggerOpenSidebar(); - } - if (action === 'open') { - if (!this.isOpen()) { - this.triggerOpenSidebar(); - } - } - if (action === 'hide') { - if (this.isOpen()) { - return this.triggerOpenSidebar(); - } - } - }; - - Sidebar.prototype.isOpen = function() { - return this.sidebar.is('.right-sidebar-expanded'); - }; - - Sidebar.prototype.getBlock = function(name) { - return this.sidebar.find(".block." + name); - }; - - return Sidebar; - - })(); - -}).call(this); diff --git a/app/assets/javascripts/right_sidebar.js.es6 b/app/assets/javascripts/right_sidebar.js.es6 new file mode 100644 index 00000000000..dff3083fc90 --- /dev/null +++ b/app/assets/javascripts/right_sidebar.js.es6 @@ -0,0 +1,218 @@ +/*= require lib/vue */ + +(function() { + var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + + this.Sidebar = (function() { + function Sidebar(currentUser) { + this.toggleTodo = bind(this.toggleTodo, this); + this.sidebar = $('aside.right-sidebar'); + this.addEventListeners(); + this.initVue() + } + + Sidebar.prototype.addEventListeners = function() { + this.sidebar.on('click', '.sidebar-collapsed-icon', this, this.sidebarCollapseClicked); + $('.dropdown').on('hidden.gl.dropdown', this, this.onSidebarDropdownHidden); + $('.dropdown').on('loading.gl.dropdown', this.sidebarDropdownLoading); + $('.dropdown').on('loaded.gl.dropdown', this.sidebarDropdownLoaded); + $(document).off('click', '.js-sidebar-toggle').on('click', '.js-sidebar-toggle', function(e, triggered) { + var $allGutterToggleIcons, $this, $thisIcon; + e.preventDefault(); + $this = $(this); + $thisIcon = $this.find('i'); + $allGutterToggleIcons = $('.js-sidebar-toggle i'); + if ($thisIcon.hasClass('fa-angle-double-right')) { + $allGutterToggleIcons.removeClass('fa-angle-double-right').addClass('fa-angle-double-left'); + $('aside.right-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); + $('.page-with-sidebar').removeClass('right-sidebar-expanded').addClass('right-sidebar-collapsed'); + } else { + $allGutterToggleIcons.removeClass('fa-angle-double-left').addClass('fa-angle-double-right'); + $('aside.right-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); + $('.page-with-sidebar').removeClass('right-sidebar-collapsed').addClass('right-sidebar-expanded'); + } + if (!triggered) { + return $.cookie("collapsed_gutter", $('.right-sidebar').hasClass('right-sidebar-collapsed'), { + path: '/' + }); + } + }); + return $(document).off('click', '.js-issuable-todo').on('click', '.js-issuable-todo', this.toggleTodo); + }; + + Sidebar.prototype.toggleTodo = function(e) { + var $btnText, $this, $todoLoading, ajaxType, url; + $this = $(e.currentTarget); + $todoLoading = $('.js-issuable-todo-loading'); + $btnText = $('.js-issuable-todo-text', $this); + ajaxType = $this.attr('data-delete-path') ? 'DELETE' : 'POST'; + if ($this.attr('data-delete-path')) { + url = "" + ($this.attr('data-delete-path')); + } else { + url = "" + ($this.data('url')); + } + return $.ajax({ + url: url, + type: ajaxType, + dataType: 'json', + data: { + issuable_id: $this.data('issuable-id'), + issuable_type: $this.data('issuable-type') + }, + beforeSend: (function(_this) { + return function() { + return _this.beforeTodoSend($this, $todoLoading); + }; + })(this) + }).done((function(_this) { + return function(data) { + return _this.todoUpdateDone(data, $this, $btnText, $todoLoading); + }; + })(this)); + }; + + Sidebar.prototype.beforeTodoSend = function($btn, $todoLoading) { + $btn.disable(); + return $todoLoading.removeClass('hidden'); + }; + + Sidebar.prototype.todoUpdateDone = function(data, $btn, $btnText, $todoLoading) { + var $todoPendingCount; + $todoPendingCount = $('.todos-pending-count'); + $todoPendingCount.text(data.count); + $btn.enable(); + $todoLoading.addClass('hidden'); + if (data.count === 0) { + $todoPendingCount.addClass('hidden'); + } else { + $todoPendingCount.removeClass('hidden'); + } + if (data.delete_path != null) { + $btn.attr('aria-label', $btn.data('mark-text')).attr('data-delete-path', data.delete_path); + return $btnText.text($btn.data('mark-text')); + } else { + $btn.attr('aria-label', $btn.data('todo-text')).removeAttr('data-delete-path'); + return $btnText.text($btn.data('todo-text')); + } + }; + + Sidebar.prototype.sidebarDropdownLoading = function(e) { + var $loading, $sidebarCollapsedIcon, i, img; + $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon'); + img = $sidebarCollapsedIcon.find('img'); + i = $sidebarCollapsedIcon.find('i'); + $loading = $(''); + if (img.length) { + img.before($loading); + return img.hide(); + } else if (i.length) { + i.before($loading); + return i.hide(); + } + }; + + Sidebar.prototype.sidebarDropdownLoaded = function(e) { + var $sidebarCollapsedIcon, i, img; + $sidebarCollapsedIcon = $(this).closest('.block').find('.sidebar-collapsed-icon'); + img = $sidebarCollapsedIcon.find('img'); + $sidebarCollapsedIcon.find('i.fa-spin').remove(); + i = $sidebarCollapsedIcon.find('i'); + if (img.length) { + return img.show(); + } else { + return i.show(); + } + }; + + Sidebar.prototype.sidebarCollapseClicked = function(e) { + var $block, sidebar; + if ($(e.currentTarget).hasClass('dont-change-state')) { + return; + } + sidebar = e.data; + e.preventDefault(); + $block = $(this).closest('.block'); + return sidebar.openDropdown($block); + }; + + Sidebar.prototype.openDropdown = function(blockOrName) { + var $block; + $block = _.isString(blockOrName) ? this.getBlock(blockOrName) : blockOrName; + $block.find('.edit-link').trigger('click'); + if (!this.isOpen()) { + this.setCollapseAfterUpdate($block); + return this.toggleSidebar('open'); + } + }; + + Sidebar.prototype.setCollapseAfterUpdate = function($block) { + $block.addClass('collapse-after-update'); + return $('.page-with-sidebar').addClass('with-overlay'); + }; + + Sidebar.prototype.onSidebarDropdownHidden = function(e) { + var $block, sidebar; + sidebar = e.data; + e.preventDefault(); + $block = $(this).closest('.block'); + return sidebar.sidebarDropdownHidden($block); + }; + + Sidebar.prototype.sidebarDropdownHidden = function($block) { + if ($block.hasClass('collapse-after-update')) { + $block.removeClass('collapse-after-update'); + $('.page-with-sidebar').removeClass('with-overlay'); + return this.toggleSidebar('hide'); + } + }; + + Sidebar.prototype.triggerOpenSidebar = function() { + return this.sidebar.find('.js-sidebar-toggle').trigger('click'); + }; + + Sidebar.prototype.toggleSidebar = function(action) { + if (action == null) { + action = 'toggle'; + } + if (action === 'toggle') { + this.triggerOpenSidebar(); + } + if (action === 'open') { + if (!this.isOpen()) { + this.triggerOpenSidebar(); + } + } + if (action === 'hide') { + if (this.isOpen()) { + return this.triggerOpenSidebar(); + } + } + }; + + Sidebar.prototype.isOpen = function() { + return this.sidebar.is('.right-sidebar-expanded'); + }; + + Sidebar.prototype.getBlock = function(name) { + return this.sidebar.find(".block." + name); + }; + + Sidebar.prototype.initVue = function() { + new Vue({ + el: this.sidebar.find('.lock-issue-block')[0], + name: 'RightSidebarLockIssueBlock', + data: { locked: false }, + methods: { + toggleLock(e) { + e.stopImmediatePropagation(); + this.locked = !this.locked; + } + } + }); + }; + + return Sidebar; + + })(); + +}).call(this); diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss index 7a50bc9c832..17e85ade6af 100644 --- a/app/assets/stylesheets/pages/issuable.scss +++ b/app/assets/stylesheets/pages/issuable.scss @@ -395,3 +395,7 @@ display: inline-block; line-height: 18px; } + +.lock-issue-block .state-icon { + float: right; +} diff --git a/app/views/shared/issuable/_lock_issue.html.haml b/app/views/shared/issuable/_lock_issue.html.haml new file mode 100644 index 00000000000..ed06e8575a1 --- /dev/null +++ b/app/views/shared/issuable/_lock_issue.html.haml @@ -0,0 +1,21 @@ +.block.light.lock-issue-block{data: {locked: locked}} + %template{"v-if" => "locked"} + .sidebar-collapsed-icon + = icon('lock') + .title.hide-collapsed + Lock issue + = icon('lock', class: 'state-icon') + %button.btn.btn-block.btn-default.hide-collapsed{"type" => "button", "@click" => "toggleLock"} + %span Unlock + + %template{"v-if" => "!locked"} + .sidebar-collapsed-icon + = icon('unlock-alt') + .title.hide-collapsed + Lock issue + = icon('unlock-alt', class: 'state-icon') + %button.btn.btn-block.btn-default.hide-collapsed{"type" => "button", "@click" => "toggleLock"} + %span Lock + + .hide-collapsed + Locking this issue will prevent other users from commenting. Project members will still be able to leave comment. diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml index 8e2fcbdfab8..ffa8bebad2d 100644 --- a/app/views/shared/issuable/_sidebar.html.haml +++ b/app/views/shared/issuable/_sidebar.html.haml @@ -154,6 +154,9 @@ .subscribed{class: ( 'hidden' unless subscribed )} You're receiving notifications because you're subscribed to this thread. + - if current_user + = render "shared/issuable/lock_issue", locked: 'false' + - project_ref = cross_project_reference(@project, issuable) .block.project-reference .sidebar-collapsed-icon.dont-change-state -- cgit v1.2.3