summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClement Ho <ClemMakesApps@gmail.com>2016-08-08 16:19:46 -0500
committerClement Ho <ClemMakesApps@gmail.com>2016-10-26 16:28:56 -0500
commitf610f69ab92827c49e9cbb528cacc26af10be081 (patch)
treeca255d2f6aa66340a856b1fd8e013a74d46353a5
parent5a4e6721786dd080cd40ca4ea23fc4202a85e73f (diff)
downloadgitlab-ce-f610f69ab92827c49e9cbb528cacc26af10be081.tar.gz
Add todo toggle event
-rw-r--r--CHANGELOG.md1
-rw-r--r--app/assets/javascripts/header.js9
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js3
-rw-r--r--app/assets/javascripts/right_sidebar.js11
-rw-r--r--app/assets/javascripts/sidebar.js.es67
-rw-r--r--app/assets/javascripts/todos.js.es63
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml2
-rw-r--r--spec/features/todos/todos_spec.rb1
-rw-r--r--spec/javascripts/dashboard_spec.js.es638
-rw-r--r--spec/javascripts/fixtures/dashboard.html.haml45
-rw-r--r--spec/javascripts/fixtures/header.html.haml35
-rw-r--r--spec/javascripts/fixtures/right_sidebar.html.haml4
-rw-r--r--spec/javascripts/fixtures/todos.json4
-rw-r--r--spec/javascripts/header_spec.js54
-rw-r--r--spec/javascripts/right_sidebar_spec.js19
15 files changed, 223 insertions, 13 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86878e5af6c..197a74fd4b6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -77,6 +77,7 @@ Please view this file on the master branch, on stable branches it's out of date.
- Add more tests for calendar contribution (ClemMakesApps)
- Update Gitlab Shell to fix some problems with moving projects between storages
- Cache rendered markdown in the database, rather than Redis
+ - Add todo toggle event (ClemMakesApps)
- Avoid database queries on Banzai::ReferenceParser::BaseParser for nodes without references
- Simplify Mentionable concern instance methods
- API: Ability to retrieve version information (Robert Schilling)
diff --git a/app/assets/javascripts/header.js b/app/assets/javascripts/header.js
new file mode 100644
index 00000000000..5215ce9c4ba
--- /dev/null
+++ b/app/assets/javascripts/header.js
@@ -0,0 +1,9 @@
+(function() {
+
+ $(document).on('todo:toggle', function(e, count) {
+ var $todoPendingCount = $('.todos-pending-count');
+ $todoPendingCount.text(gl.text.addDelimiter(count));
+ $todoPendingCount.toggleClass('hidden', count === 0);
+ });
+
+})();
diff --git a/app/assets/javascripts/lib/utils/text_utility.js b/app/assets/javascripts/lib/utils/text_utility.js
index d761a844be9..6206c7f9237 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js
+++ b/app/assets/javascripts/lib/utils/text_utility.js
@@ -7,6 +7,9 @@
if ((base = w.gl).text == null) {
base.text = {};
}
+ gl.text.addDelimiter = function(text) {
+ return text ? text.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") : text;
+ }
gl.text.randomString = function() {
return Math.random().toString(36).substring(7);
};
diff --git a/app/assets/javascripts/right_sidebar.js b/app/assets/javascripts/right_sidebar.js
index e3d5f413c77..9f2385a3de8 100644
--- a/app/assets/javascripts/right_sidebar.js
+++ b/app/assets/javascripts/right_sidebar.js
@@ -74,16 +74,11 @@
};
Sidebar.prototype.todoUpdateDone = function(data, $btn, $btnText, $todoLoading) {
- var $todoPendingCount;
- $todoPendingCount = $('.todos-pending-count');
- $todoPendingCount.text(data.count);
+ $(document).trigger('todo:toggle', 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'));
diff --git a/app/assets/javascripts/sidebar.js.es6 b/app/assets/javascripts/sidebar.js.es6
index 755fac8107b..50c9440de5f 100644
--- a/app/assets/javascripts/sidebar.js.es6
+++ b/app/assets/javascripts/sidebar.js.es6
@@ -37,7 +37,8 @@
.on('click', sidebarToggleSelector, () => this.toggleSidebar())
.on('click', pinnedToggleSelector, () => this.togglePinnedState())
.on('click', 'html, body', (e) => this.handleClickEvent(e))
- .on('page:change', () => this.renderState());
+ .on('page:change', () => this.renderState())
+ .on('todo:toggle', (e, count) => this.updateTodoCount(count));
this.renderState();
}
@@ -52,6 +53,10 @@
}
}
+ updateTodoCount(count) {
+ $('.js-todos-count').text(gl.text.addDelimiter(count));
+ }
+
toggleSidebar() {
this.isExpanded = !this.isExpanded;
this.renderState();
diff --git a/app/assets/javascripts/todos.js.es6 b/app/assets/javascripts/todos.js.es6
index 055228c5df8..42539ef43e2 100644
--- a/app/assets/javascripts/todos.js.es6
+++ b/app/assets/javascripts/todos.js.es6
@@ -97,7 +97,8 @@
}
updateBadges(data) {
- $('.todos-pending .badge, .todos-pending-count').text(data.count);
+ $(document).trigger('todo:toggle', data.count);
+ $('.todos-pending .badge').text(data.count);
return $('.todos-done .badge').text(data.done_count);
}
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 67f558c854b..3b1295dc3c0 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -7,7 +7,7 @@
= link_to dashboard_todos_path, title: 'Todos' do
%span
Todos
- %span.count= number_with_delimiter(todos_pending_count)
+ %span.count.js-todos-count= number_with_delimiter(todos_pending_count)
= nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity', title: 'Activity' do
%span
diff --git a/spec/features/todos/todos_spec.rb b/spec/features/todos/todos_spec.rb
index bf93c1d1251..230543cd175 100644
--- a/spec/features/todos/todos_spec.rb
+++ b/spec/features/todos/todos_spec.rb
@@ -132,7 +132,6 @@ describe 'Dashboard Todos', feature: true do
end
it 'shows "All done" message!' do
- within('.todos-pending-count') { expect(page).to have_content '0' }
expect(page).to have_content 'To do 0'
expect(page).to have_content "You're all done!"
expect(page).not_to have_selector('.gl-pagination')
diff --git a/spec/javascripts/dashboard_spec.js.es6 b/spec/javascripts/dashboard_spec.js.es6
new file mode 100644
index 00000000000..8021145d8e8
--- /dev/null
+++ b/spec/javascripts/dashboard_spec.js.es6
@@ -0,0 +1,38 @@
+/*= require sidebar */
+/*= require jquery */
+/*= require jquery.cookie */
+/*= require lib/utils/text_utility */
+
+((global) => {
+ describe('Dashboard', () => {
+ const fixtureTemplate = 'dashboard.html';
+
+ function todosCountText() {
+ return $('.js-todos-count').text();
+ }
+
+ function triggerToggle(newCount) {
+ $(document).trigger('todo:toggle', newCount);
+ }
+
+ fixture.preload(fixtureTemplate);
+ beforeEach(() => {
+ fixture.load(fixtureTemplate);
+ new global.Sidebar();
+ });
+
+ it('should update todos-count after receiving the todo:toggle event', () => {
+ triggerToggle(5);
+ expect(todosCountText()).toEqual('5');
+ });
+
+ it('should display todos-count with delimiter', () => {
+ triggerToggle(1000);
+ expect(todosCountText()).toEqual('1,000');
+
+ triggerToggle(1000000);
+ expect(todosCountText()).toEqual('1,000,000');
+ });
+ });
+
+})(window.gl);
diff --git a/spec/javascripts/fixtures/dashboard.html.haml b/spec/javascripts/fixtures/dashboard.html.haml
new file mode 100644
index 00000000000..32446acfd60
--- /dev/null
+++ b/spec/javascripts/fixtures/dashboard.html.haml
@@ -0,0 +1,45 @@
+%ul.nav.nav-sidebar
+ %li.home.active
+ %a.dashboard-shortcuts-projects
+ %span
+ Projects
+ %li
+ %a
+ %span
+ Todos
+ %span.count.js-todos-count
+ 1
+ %li
+ %a.dashboard-shortcuts-activity
+ %span
+ Activity
+ %li
+ %a
+ %span
+ Groups
+ %li
+ %a
+ %span
+ Milestones
+ %li
+ %a.dashboard-shortcuts-issues
+ %span
+ Issues
+ %span
+ 1
+ %li
+ %a.dashboard-shortcuts-merge_requests
+ %span
+ Merge Requests
+ %li
+ %a
+ %span
+ Snippets
+ %li
+ %a
+ %span
+ Help
+ %li
+ %a
+ %span
+ Profile Settings
diff --git a/spec/javascripts/fixtures/header.html.haml b/spec/javascripts/fixtures/header.html.haml
new file mode 100644
index 00000000000..4db2ef604de
--- /dev/null
+++ b/spec/javascripts/fixtures/header.html.haml
@@ -0,0 +1,35 @@
+%header.navbar.navbar-fixed-top.navbar-gitlab.nav_header_class
+ .container-fluid
+ .header-content
+ %button.side-nav-toggle
+ %span.sr-only
+ Toggle navigation
+ %i.fa.fa-bars
+ %button.navbar-toggle
+ %span.sr-only
+ Toggle navigation
+ %i.fa.fa-ellipsis-v
+ .navbar-collapse.collapse
+ %ui.nav.navbar-nav
+ %li.hidden-sm.hidden-xs
+ %li.visible-sm.visible-xs
+ %li
+ %a
+ %i.fa.fa-bell.fa-fw
+ %span.badge.todos-pending-count
+ %li
+ %a
+ %i.fa.fa-plus.fa-fw
+ %li.header-user.dropdown
+ %a
+ %img
+ %span.caret
+ .dropdown-menu-nav
+ .dropdown-menu-align-right
+ %ul
+ %li
+ %a.profile-link
+ %li
+ %a
+ %li.divider
+ %li.sign-out-link
diff --git a/spec/javascripts/fixtures/right_sidebar.html.haml b/spec/javascripts/fixtures/right_sidebar.html.haml
index 95efaff4b69..d48b77cf0ce 100644
--- a/spec/javascripts/fixtures/right_sidebar.html.haml
+++ b/spec/javascripts/fixtures/right_sidebar.html.haml
@@ -5,6 +5,10 @@
%div.block.issuable-sidebar-header
%a.gutter-toggle.pull-right.js-sidebar-toggle
%i.fa.fa-angle-double-left
+ %button.btn.btn-default.issuable-header-btn.pull-right.js-issuable-todo{ type: "button", data: { todo_text: "Add Todo", mark_text: "Mark Done", issuable_id: "1", issuable_type: "issue", url: "/todos" }}
+ %span.js-issuable-todo-text
+ Add Todo
+ %i.fa.fa-spin.fa-spinner.js-issuable-todo-loading.hidden
%form.issuable-context-form
%div.block.labels
diff --git a/spec/javascripts/fixtures/todos.json b/spec/javascripts/fixtures/todos.json
new file mode 100644
index 00000000000..62c2387d515
--- /dev/null
+++ b/spec/javascripts/fixtures/todos.json
@@ -0,0 +1,4 @@
+{
+ "count": 1,
+ "delete_path": "/dashboard/todos/1"
+} \ No newline at end of file
diff --git a/spec/javascripts/header_spec.js b/spec/javascripts/header_spec.js
new file mode 100644
index 00000000000..b9d023a9aae
--- /dev/null
+++ b/spec/javascripts/header_spec.js
@@ -0,0 +1,54 @@
+/*= require header */
+/*= require lib/utils/text_utility */
+/*= require jquery */
+
+(function() {
+
+ describe('Header', function() {
+ var todosPendingCount = '.todos-pending-count';
+ var fixtureTemplate = 'header.html';
+
+ function isTodosCountHidden() {
+ return $(todosPendingCount).hasClass('hidden');
+ }
+
+ function triggerToggle(newCount) {
+ $(document).trigger('todo:toggle', newCount);
+ }
+
+ fixture.preload(fixtureTemplate);
+ beforeEach(function() {
+ fixture.load(fixtureTemplate);
+ });
+
+ it('should update todos-pending-count after receiving the todo:toggle event', function() {
+ triggerToggle(5);
+ expect($(todosPendingCount).text()).toEqual('5');
+ });
+
+ it('should hide todos-pending-count when it is 0', function() {
+ triggerToggle(0);
+ expect(isTodosCountHidden()).toEqual(true);
+ });
+
+ it('should show todos-pending-count when it is more than 0', function() {
+ triggerToggle(10);
+ expect(isTodosCountHidden()).toEqual(false);
+ });
+
+ describe('when todos-pending-count is 1000', function() {
+ beforeEach(function() {
+ triggerToggle(1000);
+ });
+
+ it('should show todos-pending-count', function() {
+ expect(isTodosCountHidden()).toEqual(false);
+ });
+
+ it('should add delimiter to todos-pending-count', function() {
+ expect($(todosPendingCount).text()).toEqual('1,000');
+ });
+ });
+ });
+
+}).call(this);
diff --git a/spec/javascripts/right_sidebar_spec.js b/spec/javascripts/right_sidebar_spec.js
index c937a4706f7..9c7f44c6427 100644
--- a/spec/javascripts/right_sidebar_spec.js
+++ b/spec/javascripts/right_sidebar_spec.js
@@ -3,6 +3,8 @@
/*= require jquery */
/*= require jquery.cookie */
+/*= require extensions/jquery.js */
+
(function() {
var $aside, $icon, $labelsIcon, $page, $toggle, assertSidebarState;
@@ -55,12 +57,27 @@
$labelsIcon.click();
return assertSidebarState('expanded');
});
- return it('should collapse when the icon arrow clicked while it is floating on page', function() {
+ it('should collapse when the icon arrow clicked while it is floating on page', function() {
$labelsIcon.click();
assertSidebarState('expanded');
$toggle.click();
return assertSidebarState('collapsed');
});
+
+ it('should broadcast todo:toggle event when add todo clicked', function() {
+ spyOn(jQuery, 'ajax').and.callFake(function() {
+ var d = $.Deferred();
+ var response = fixture.load('todos.json');
+ d.resolve(response);
+ return d.promise();
+ });
+
+ var todoToggleSpy = spyOnEvent(document, 'todo:toggle');
+
+ $('.js-issuable-todo').click();
+
+ expect(todoToggleSpy.calls.count()).toEqual(1);
+ })
});
}).call(this);