From 79fdd5d62567339e5400814c35835ef44e305274 Mon Sep 17 00:00:00 2001 From: Reinier Balt Date: Sat, 20 Jul 2013 23:21:24 +0200 Subject: [PATCH] implement go to project with autocomplete --- Gemfile.lock | 48 +++--- app/assets/javascripts/keybindings.js.coffee | 10 +- app/assets/javascripts/tracks.js.coffee | 148 +++++++++++-------- app/assets/stylesheets/tracks.css.scss | 17 +++ app/controllers/projects_controller.rb | 3 +- app/views/contexts/_context.html.erb | 2 +- app/views/layouts/application.html.erb | 4 +- app/views/projects/_go_project.html.erb | 17 +++ app/views/projects/_project.html.erb | 2 +- app/views/shared/_goto.html.erb | 29 ++++ app/views/shared/_navbar.html.erb | 18 ++- config/initializers/rack-mini-profiler.rb | 12 +- 12 files changed, 210 insertions(+), 100 deletions(-) create mode 100644 app/views/projects/_go_project.html.erb create mode 100644 app/views/shared/_goto.html.erb diff --git a/Gemfile.lock b/Gemfile.lock index dc6239be..bae5324f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,6 @@ -GIT - remote: https://github.com/rails/actionpack-xml_parser - revision: 246653ab3670f329176c1e77e6cd1a632466f06e - specs: - actionpack-xml_parser (1.0.0) - actionpack (>= 4.0.0.rc1, < 4.1) - GIT remote: git://github.com/seyhunak/twitter-bootstrap-rails.git - revision: 9a0a31096ecee572638132d5ed94bc5500f74330 + revision: 3ebe7b161a7699e56431d546aa98034483a3bb3c branch: master specs: twitter-bootstrap-rails (2.2.7) @@ -16,6 +9,13 @@ GIT rails (>= 3.1) railties (>= 3.1) +GIT + remote: https://github.com/rails/actionpack-xml_parser + revision: 246653ab3670f329176c1e77e6cd1a632466f06e + specs: + actionpack-xml_parser (1.0.0) + actionpack (>= 4.0.0.rc1, < 4.1) + GEM remote: https://rubygems.org/ specs: @@ -74,13 +74,14 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.6.2) + coffee-script-source (1.6.3) commonjs (0.2.6) - cucumber (1.3.2) + cucumber (1.3.5) builder (>= 2.1.2) diff-lcs (>= 1.1.3) gherkin (~> 2.12.0) - multi_json (~> 1.3) + multi_json (~> 1.7.5) + multi_test (>= 0.0.2) cucumber-rails (1.3.0) capybara (>= 1.1.2) cucumber (>= 1.1.8) @@ -101,7 +102,7 @@ GEM hike (1.2.3) htmlentities (4.3.1) i18n (0.6.4) - jquery-rails (3.0.1) + jquery-rails (3.0.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) less (2.3.2) @@ -115,13 +116,14 @@ GEM treetop (~> 1.4.8) metaclass (0.0.1) mime-types (1.23) - mini_portile (0.5.0) + mini_portile (0.5.1) minitest (4.7.5) mocha (0.14.0) metaclass (~> 0.0.1) - mousetrap-rails (0.0.10) + mousetrap-rails (0.0.11) multi_json (1.7.7) - mysql2 (0.3.11) + multi_test (0.0.2) + mysql2 (0.3.13) nokogiri (1.6.0) mini_portile (~> 0.5.0) polyglot (0.3.3) @@ -147,12 +149,12 @@ GEM thor (>= 0.18.1, < 2.0) rake (10.1.0) ref (1.0.5) - rspec-expectations (2.13.0) + rspec-expectations (2.14.0) diff-lcs (>= 1.1.3, < 2.0) rubyzip (0.9.9) - safe_yaml (0.9.3) - sanitize (2.0.4) - nokogiri (~> 1.6.0) + safe_yaml (0.9.4) + sanitize (2.0.6) + nokogiri (>= 1.4.4) sass (3.2.9) sass-rails (4.0.0) railties (>= 4.0.0.beta, < 5.0) @@ -187,17 +189,17 @@ GEM thread_safe (0.1.0) atomic tilt (1.4.1) - timecop (0.6.1) - tolk (1.3.9) + timecop (0.6.2) + tolk (1.3.11) safe_yaml (~> 0.8) will_paginate treetop (1.4.14) polyglot polyglot (>= 0.3.1) - turbolinks (1.2.0) + turbolinks (1.3.0) coffee-rails tzinfo (0.3.37) - uglifier (2.1.1) + uglifier (2.1.2) execjs (>= 0.3.0) multi_json (~> 1.0, >= 1.0.2) uniform_notifier (1.2.0) diff --git a/app/assets/javascripts/keybindings.js.coffee b/app/assets/javascripts/keybindings.js.coffee index 4d543f2b..7e50096c 100644 --- a/app/assets/javascripts/keybindings.js.coffee +++ b/app/assets/javascripts/keybindings.js.coffee @@ -47,12 +47,14 @@ $ -> # ADD: a is bound in navbar # GO TO - # Mousetrap.bind 'g h', TracksApp.go_home + Mousetrap.bind 'G', -> TracksApp.go_menu() + Mousetrap.bind 'g h', -> TracksApp.go_home() Mousetrap.bind 'g c', -> alert("go context") - # Mousetrap.bind 'g C', TracksApp.go_contexts + Mousetrap.bind 'g C', -> TracksApp.go_contexts() Mousetrap.bind 'g t', -> alert("go tag") - Mousetrap.bind 'g p', -> alert("go project") - # Mousetrap.bind 'g P', TracksApp.go_projects + Mousetrap.bind 'g p', -> TracksApp.go_project() + Mousetrap.bind 'g P', -> TracksApp.go_projects() + Mousetrap.bind 'g s', -> TracksApp.go_starred() # VIEW Mousetrap.bind 'v p', -> alert("group by project") diff --git a/app/assets/javascripts/tracks.js.coffee b/app/assets/javascripts/tracks.js.coffee index 74b158d2..60db63db 100644 --- a/app/assets/javascripts/tracks.js.coffee +++ b/app/assets/javascripts/tracks.js.coffee @@ -1,80 +1,104 @@ # Tracks specific coffeescript -# TracksApp = -# goto_page: (page) -> window.location.href = page -# go_home: this.goto_page "/" -# go_contexts: this.goto_page "/contexts" -# go_projects: this.goto_page "/projects" TracksApp = + goto_page: (page) -> window.location.href = page + go_home: -> TracksApp.goto_page "/" + go_contexts: -> TracksApp.goto_page "/contexts" + go_projects: -> TracksApp.goto_page "/projects" + go_starred: -> TracksApp.goto_page "/tag/starred" - createSubmenu: (todo, itemToAddBefore) -> - template_clone = $("div.todo-sub-menu-template").clone() - itemToAddBefore.before(template_clone) - todo_menu = todo.find("div.todo-sub-menu-template") - todo_menu.removeClass("todo-sub-menu-template") - todo_menu.addClass("todo-sub-menu") - todo_menu.removeClass("hide") + go_project: -> + $("input#tracks-goto-project").val("") + $('div#tracks-go-project-dialog').on 'shown', -> $("input#tracks-goto-project").focus() + $('div#tracks-go-project-dialog').modal() - appendTodoSubMenu: (todo) -> - if todo.find("div.todo-sub-menu").length is 0 - notes_row = todo.find(".todo-notes").parent() - submenu = TracksApp.createSubmenu(todo, notes_row) - else - todo.find("div.todo-sub-menu").removeClass("hide") + go_menu: -> $('div#tracks-goto-dialog').modal() + add_todo: -> $('div#tracks-add-action-dialog').modal() - selectTodo: (new_todo) -> - selected_item = $("div.todo-item.selected-item") - selected_item.find("div.todo-sub-menu").addClass("hide") - selected_item.find("span.todo-item-detail").addClass("hide") - selected_item.removeClass("selected-item") - TracksApp.appendTodoSubMenu(new_todo) - new_todo.find("span.todo-item-detail").removeClass("hide") - new_todo.addClass("selected-item") + createSubmenu: (todo, itemToAddBefore) -> + template_clone = $("div.todo-sub-menu-template").clone() + itemToAddBefore.before(template_clone) + todo_menu = todo.find("div.todo-sub-menu-template") + todo_menu.removeClass("todo-sub-menu-template") + todo_menu.addClass("todo-sub-menu") + todo_menu.removeClass("hide") - selectPrevNext: (go_next) -> - current = prev = next = null - stop = false - $("div.todo-item").each -> - if stop - next = $(this) - return false + appendTodoSubMenu: (todo) -> + if todo.find("div.todo-sub-menu").length is 0 + notes_row = todo.find(".todo-notes").parent() + submenu = TracksApp.createSubmenu(todo, notes_row) + else + todo.find("div.todo-sub-menu").removeClass("hide") - prev = current - current = $(this) + selectTodo: (new_todo) -> + selected_item = $("div.todo-item.selected-item") + selected_item.find("div.todo-sub-menu").addClass("hide") + selected_item.find("span.todo-item-detail").addClass("hide") + selected_item.removeClass("selected-item") + TracksApp.appendTodoSubMenu(new_todo) + new_todo.find("span.todo-item-detail").removeClass("hide") + new_todo.addClass("selected-item") - if $(this).hasClass("selected-item") - stop = true - - if go_next - TracksApp.selectTodo(prev) if prev? - return prev - else - TracksApp.selectTodo(next) if next? - return next - - selectPrev: -> - unless TracksApp.selectPrevNext(true)? - TracksApp.selectTodo($("div.todo-item").last()) - - selectNext: -> - unless TracksApp.selectPrevNext(false)? - TracksApp.selectTodo($("div.todo-item").first()) + selectPrevNext: (go_next) -> + current = prev = next = null + stop = false + $("div.todo-item").each -> + if stop + next = $(this) + return false + + prev = current + current = $(this) + + if $(this).hasClass("selected-item") + stop = true + + if go_next + TracksApp.selectTodo(prev) if prev? + return prev + else + TracksApp.selectTodo(next) if next? + return next + + selectPrev: -> + unless TracksApp.selectPrevNext(true)? + TracksApp.selectTodo($("div.todo-item").last()) + + selectNext: -> + unless TracksApp.selectPrevNext(false)? + TracksApp.selectTodo($("div.todo-item").first()) # Make TracksApp globally accessible. From http://stackoverflow.com/questions/4214731/coffeescript-global-variables root = exports ? this root.TracksApp = TracksApp $ -> - $("a#menu-keyboard-shotcuts").click -> $('div#tracks-shortcuts-dialog').modal() + $("a#menu-keyboard-shotcuts").click -> $('div#tracks-shortcuts-dialog').modal() - $("a.button-add-todo").click -> $('div#tracks-add-action-dialog').modal() + $("a.button-add-todo").click -> TracksApp.add_todo() + $("a.button-home").click -> TracksApp.go_home() + $("a.button-goto").click -> TracksApp.go_menu() - $("i.icon-book").click -> - notes_id = $( this ).attr("data-note-id") - notes_div = $("div#" + notes_id ) - notes_div.toggleClass("hide") - todo_item = $(this).parent().parent().parent().parent() - TracksApp.selectTodo(todo_item) + $("i.icon-book").click -> + notes_id = $( this ).attr("data-note-id") + notes_div = $("div#" + notes_id ) + notes_div.toggleClass("hide") + todo_item = $(this).parent().parent().parent().parent() + TracksApp.selectTodo(todo_item) - $("span.todo-item-description-container").click -> - TracksApp.selectTodo( $(this).parent().parent().parent() ) \ No newline at end of file + $("span.todo-item-description-container").click -> + TracksApp.selectTodo( $(this).parent().parent().parent() ) + + $('.ajax-typeahead').typeahead + minLength: 3, + source: (query, process) -> + typeaheadURL = $(this)[0].$element[0].dataset.link + return $.ajax + url: typeaheadURL, + type: 'get', + data: {"query": query}, + dataType: 'json', + success: (json) -> + $("input#tracks-json-result").val(json) + map = $.map json, (data, item) -> data.value + return process(map) diff --git a/app/assets/stylesheets/tracks.css.scss b/app/assets/stylesheets/tracks.css.scss index ef3d4449..3cff04ca 100644 --- a/app/assets/stylesheets/tracks.css.scss +++ b/app/assets/stylesheets/tracks.css.scss @@ -19,6 +19,9 @@ div.tracks-middle { div.btn-toolbar { margin: 0px 15px 0px 0px; } + input { + width: 100px; + } } div#tracks-login-navbar { @@ -149,6 +152,20 @@ div.todos-container { } } +/* Dialogs */ + +.modal-body { + overflow-y: visible; +} + +div#tracks-go-project-dialog { + input.input-medium { + width : 95%; + } +} + +/* Generic */ + div.hide_me { display: none; } \ No newline at end of file diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index eb3c2d21..7552cc6d 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -52,7 +52,8 @@ class ProjectsController < ApplicationController end format.autocomplete do projects = current_user.projects.active + current_user.projects.hidden - render :text => for_autocomplete(projects, params[:term]) + term = params[:term] || params[:query] + render :text => for_autocomplete(projects, term) end end end diff --git a/app/views/contexts/_context.html.erb b/app/views/contexts/_context.html.erb index 7bab6ffa..137b96eb 100644 --- a/app/views/contexts/_context.html.erb +++ b/app/views/contexts/_context.html.erb @@ -1,7 +1,7 @@ <% @not_done = @not_done_todos.select {|t| t.context_id == context.id } # invalidate the cache every day because of staleness or -# rendering of "due in x days" that change without touching updated at of the todo +# showing of "due in x days" that change without touching updated at of the todo cache [context, source_view_key, current_user.date.strftime("%Y%m%d"), @tag_name] do -%> <%= diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 079b2814..22799a4e 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -44,10 +44,12 @@ <% cache [:footer] do -%> <%= render partial: "shared/footer" %> - <% # dialogs -%> + <% # dialogs / partials -%> <%= render partial: "shared/keyboard_shortcuts" %> <%= render partial: "shared/add_new_action" %> + <%= render partial: "shared/goto" %> <%= render partial: "todos/todo_sub_menu" %> + <%= render partial: "projects/go_project" %> <% end -%> <% # Javascripts diff --git a/app/views/projects/_go_project.html.erb b/app/views/projects/_go_project.html.erb new file mode 100644 index 00000000..592b7381 --- /dev/null +++ b/app/views/projects/_go_project.html.erb @@ -0,0 +1,17 @@ +` \ No newline at end of file diff --git a/app/views/projects/_project.html.erb b/app/views/projects/_project.html.erb index 70102cec..7c2367cf 100644 --- a/app/views/projects/_project.html.erb +++ b/app/views/projects/_project.html.erb @@ -1,7 +1,7 @@ <% @not_done = @not_done_todos.select {|t| t.project_id == project.id } # invalidate the cache every day because of staleness or -# rendering of "due in x days" that change without touching updated at of the todo +# showing of "due in x days" that change without touching updated at of the todo cache [project, source_view_key, current_user.date.strftime("%Y%m%d"), @tag_name] do -%> <%= diff --git a/app/views/shared/_goto.html.erb b/app/views/shared/_goto.html.erb new file mode 100644 index 00000000..f01e2a7a --- /dev/null +++ b/app/views/shared/_goto.html.erb @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/app/views/shared/_navbar.html.erb b/app/views/shared/_navbar.html.erb index 94962f81..aac54d55 100644 --- a/app/views/shared/_navbar.html.erb +++ b/app/views/shared/_navbar.html.erb @@ -3,13 +3,19 @@
- A - B - C + + + <%= @badge_count || @count %> +
+ + + +
+
- \ No newline at end of file diff --git a/config/initializers/rack-mini-profiler.rb b/config/initializers/rack-mini-profiler.rb index 93d2e299..815d7377 100644 --- a/config/initializers/rack-mini-profiler.rb +++ b/config/initializers/rack-mini-profiler.rb @@ -1,2 +1,12 @@ # Have Mini Profiler show up on the right -Rack::MiniProfiler.config.position = 'right' \ No newline at end of file +Rack::MiniProfiler.config.position = 'right' + +# Have Mini Profiler start in hidden mode - display with short cut (defaulted to 'Alt+P') +Rack::MiniProfiler.config.start_hidden = true + +# Don't collect backtraces on SQL queries that take less than 5 ms to execute +# (necessary on Rubies earlier than 2.0) +# Rack::MiniProfiler.config.backtrace_threshold_ms = 5 + +# Use memory storage +Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore \ No newline at end of file