diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 250672c7..8a56bca9 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -12,13 +12,10 @@ // //= require jquery //= require jquery_ujs -//= require twitter/bootstrap +//= require twitter/bootstrap/bootstrap-tooltip +//= require twitter/bootstrap/bootstrap-popover //= require mousetrap -// Stuff in app/assets -//= require tracks.js -//= require keybindings.js - // Stuff in vendor/assets // require jquery-ui-1.10.0.custom.min // require jquery.ui.touch-punch.min @@ -28,5 +25,10 @@ // require jquery.simulate.drag-sortable // require jquery.truncator +//= require typeahead //= require jquery.cookie //= require swf_fu + +// Stuff in app/assets +//= require tracks.js +//= require keybindings.js \ No newline at end of file diff --git a/app/assets/javascripts/keybindings.js.coffee b/app/assets/javascripts/keybindings.js.coffee index b6033a44..ded2a4e8 100644 --- a/app/assets/javascripts/keybindings.js.coffee +++ b/app/assets/javascripts/keybindings.js.coffee @@ -48,13 +48,13 @@ $ -> # GO TO 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 t', -> alert("go tag") + Mousetrap.bind 'g h', -> TracksApp.go_home_page() + Mousetrap.bind 'g c', -> TracksApp.go_context() + Mousetrap.bind 'g C', -> TracksApp.go_contexts_page() + Mousetrap.bind 'g t', -> TracksApp.go_tag() Mousetrap.bind 'g p', -> TracksApp.go_project() - Mousetrap.bind 'g P', -> TracksApp.go_projects() - Mousetrap.bind 'g s', -> TracksApp.go_starred() + Mousetrap.bind 'g P', -> TracksApp.go_projects_page() + Mousetrap.bind 'g s', -> TracksApp.go_starred_page() # VIEW Mousetrap.bind 'v p', -> TracksApp.group_view_by_project() @@ -62,4 +62,5 @@ $ -> # Item Selection Mousetrap.bind 'j', -> TracksApp.selectNext() - Mousetrap.bind 'k', -> TracksApp.selectPrev() \ No newline at end of file + Mousetrap.bind 'k', -> TracksApp.selectPrev() + Mousetrap.bind 'n', -> TracksApp.toggleNoteOfSelectedTodo() \ No newline at end of file diff --git a/app/assets/javascripts/tracks.js.coffee b/app/assets/javascripts/tracks.js.coffee deleted file mode 100644 index ad929d7d..00000000 --- a/app/assets/javascripts/tracks.js.coffee +++ /dev/null @@ -1,118 +0,0 @@ -# Tracks specific coffeescript - -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" - - # TODO: refactor to work for contexts and projects and tags - 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() - - go_menu: -> $('div#tracks-goto-dialog').modal() - add_todo: -> $('div#tracks-add-action-dialog').modal() - - 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") - - 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") - - 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") - - 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()) - - show_note: (node) -> - notes_id = node.attr("data-note-id") - notes_div = $("div#" + notes_id ) - notes_div.toggleClass("hide") - todo_item = $(this).parent().parent().parent().parent().parent() - TracksApp.selectTodo(todo_item) - - refresh_page: -> - location.reload(true) - - group_view_by: (state) -> - $.cookie('group_view_by', state) - - group_view_by_context: -> - TracksApp.group_view_by('context') - TracksApp.refresh_page() - - group_view_by_project: -> - TracksApp.group_view_by('project') - TracksApp.refresh_page() - - -# 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.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 -> TracksApp.show_note( $(this) ) - $("span.todo-item-description-container").click -> TracksApp.selectTodo( $(this).parent().parent().parent() ) - - $('.ajax-typeahead').typeahead - minLength: 2, - 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) \ No newline at end of file diff --git a/app/assets/javascripts/tracks.js.coffee.erb b/app/assets/javascripts/tracks.js.coffee.erb new file mode 100644 index 00000000..daf6674f --- /dev/null +++ b/app/assets/javascripts/tracks.js.coffee.erb @@ -0,0 +1,177 @@ +# Tracks specific coffeescript + +TracksApp = + dialog_data: { + project: { + title: "Go to project" + placeholder: "Type (part of) project name" + autocomplete_link: "<%= Rails.application.routes.url_helpers.projects_path(format: :autocomplete) %>" + target_link: "<%= Rails.application.routes.url_helpers.project_path "" %>" + target_id: "id" # json/datum field containing id to use + } + context: { + title: "Go to context" + placeholder: "Type (part of) context name" + autocomplete_link: "<%= Rails.application.routes.url_helpers.contexts_path(format: :autocomplete) %>" + target_link: "<%= Rails.application.routes.url_helpers.context_path ""%>" + target_id: "id" # json/datum field containing id to use + } + tag: { + title: "Go to tagged actions" + placeholder: "Type (part of) tag name" + autocomplete_link: "<%= Rails.application.routes.url_helpers.tags_autocomplete_path %>" + target_link: "<%= Rails.application.routes.url_helpers.tag_path "" %>" + # json/datum field containing id to use. For tag it is the tag name, not the id field + target_id: "value" + } + } + + goto_page: (page) -> window.location.href = page + go_home_page: -> TracksApp.goto_page "<%= Rails.application.routes.url_helpers.root_path %>" + go_contexts_page: -> TracksApp.goto_page "<%= Rails.application.routes.url_helpers.contexts_path %>" + go_projects_page: -> TracksApp.goto_page "<%= Rails.application.routes.url_helpers.projects_path %>" + go_starred_page: -> TracksApp.goto_page "<%= Rails.application.routes.url_helpers.tag_path("starred") %>" + + show_item_dialog: (settings) -> + dialog = $('div#tracks-go-item-dialog') + # clear input field and set attributes + dialog.find("input#tracks-goto-item").typeahead("val", "") + dialog.find("input#tracks-goto-item").attr("placeholder", settings.placeholder) + dialog.find("input#tracks-goto-item").attr("data-link", settings.autocomplete_link) + dialog.find("form").attr("data-link", settings.target_link) + dialog.find("form").attr("data-id", settings.target_id) + # set title of dialog + dialog.find("h3#myModalLabel").html(settings.title) + # set focus to input field when dialog is shown + dialog.on 'shown', -> + # twitter-typeahead adds span around search field with display:inline-block. This causes + # the search field to ignore the width set in tracks.css + $("span.twitter-typeahead").css("display", "block") + $("input#tracks-goto-item").focus() + # show the dialog + dialog.modal() + + go_project: -> TracksApp.show_item_dialog(TracksApp.dialog_data.project) + go_context: -> TracksApp.show_item_dialog(TracksApp.dialog_data.context) + go_tag: -> TracksApp.show_item_dialog(TracksApp.dialog_data.tag) + + go_menu: -> $('div#tracks-goto-dialog').modal() + add_todo: -> $('div#tracks-add-action-dialog').modal() + + 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") + + 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") + + 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") + + 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()) + + toggleNoteOfSelectedTodo: -> + selected_item = $("div.todo-item.selected-item") + notes_id = selected_item.find("i.icon-book").attr("data-note-id") + notes_div = $("div#" + notes_id ) + notes_div.toggleClass("hide") + + toggleNoteOfTodo: (node) -> + todo_item = $(this).parent().parent().parent().parent().parent() + TracksApp.selectTodo(todo_item) + TracksApp.toggleNoteOfSelectedTodo() + + refresh_page: -> + location.reload(true) + + group_view_by: (state) -> + $.cookie('group_view_by', state) + + group_view_by_context: -> + TracksApp.group_view_by('context') + TracksApp.refresh_page() + + group_view_by_project: -> + TracksApp.group_view_by('project') + TracksApp.refresh_page() + + +# 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.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 -> TracksApp.toggleNoteOfTodo( $(this) ) + $("span.todo-item-description-container").click -> TracksApp.selectTodo( $(this).parent().parent().parent() ) + + autocompleteDataset = new Dataset + limit: 7 + remote: + url: "/wrong-url-from-tracks-js.autocomplete" + replace: (url, query) -> + # replace url with data-link attribute + $("input#tracks-goto-item").attr("data-link")+"?query="+query + + autocompleteDataset.initialize() + + $('input.ajax-typeahead').typeahead + minLength: 2 + hint: true + autoselect: true + sections: + highlight: true + source: autocompleteDataset + + $('input.ajax-typeahead').on "typeahead:selected", (ev, datum) -> + form = $("div#tracks-go-item-dialog form") + base_url = form.attr("data-link") + base_id = datum[form.attr("data-id")] + form.attr("action", base_url + base_id) + form.submit() + + $('a[rel="tracks-popover"]').popover() \ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index b14f486e..f1e794d4 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -13,4 +13,4 @@ *= require mousetrap *= require_tree ../../../vendor/assets/stylesheets *= require tracks -*/ +*/ \ No newline at end of file diff --git a/app/assets/stylesheets/tracks.css.scss b/app/assets/stylesheets/tracks.css.scss index d4cfe78e..247bc090 100644 --- a/app/assets/stylesheets/tracks.css.scss +++ b/app/assets/stylesheets/tracks.css.scss @@ -170,7 +170,7 @@ div.todos-container { overflow-y: visible; } -div#tracks-go-project-dialog { +div#tracks-go-item-dialog { input.input-medium { width : 95%; } diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb index c2c99d31..3d0725c3 100644 --- a/app/controllers/contexts_controller.rb +++ b/app/controllers/contexts_controller.rb @@ -31,7 +31,9 @@ class ContextsController < ApplicationController headers['Content-Type']=Mime::TEXT.to_s render :action => 'index', :layout => false, :content_type => Mime::TEXT end - format.autocomplete &render_autocomplete + format.autocomplete do + render :text => for_autocomplete(@all_contexts, params[:query] || params[:term]) + end end end @@ -220,12 +222,6 @@ class ContextsController < ApplicationController end end - def render_autocomplete - lambda do - render :text => for_autocomplete(current_user.contexts, params[:term]) - end - end - def feed_options Context.feed_options(current_user) end diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb index ea823b25..03e5971e 100644 --- a/app/controllers/todos_controller.rb +++ b/app/controllers/todos_controller.rb @@ -685,12 +685,13 @@ class TodosController < ApplicationController def tags # TODO: limit to current_user - tags_beginning = Tag.where('name like ?', params[:term]+'%') - tags_all = Tag.where('name like ?', '%'+params[:term]+'%') + term = params[:query] || param[:term] + tags_beginning = Tag.where('name like ?', term+'%') + tags_all = Tag.where('name like ?', '%'+term+'%') tags_all= tags_all - tags_beginning respond_to do |format| - format.autocomplete { render :text => for_autocomplete(tags_beginning+tags_all, params[:term]) } + format.autocomplete { render :text => for_autocomplete(tags_beginning+tags_all, term) } end end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 82b5f351..a6be59de 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -8,12 +8,6 @@ module ProjectsHelper end end - def show_project_settings(project) - content_tag(:div, :id => dom_id(project, "container"), :class=>"list") do - render :partial => "projects/project_settings", :object => project - end - end - def project_next_prev content_tag(:div, :id=>"project-next-prev") do html = "" @@ -49,7 +43,7 @@ module ProjectsHelper end def link_to_edit_project (project, descriptor = sanitize(project.name)) - link_to_edit(:project, project, descriptor) + link_to_edit(:project, project, descriptor).sub!('"',"'") end end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 0b9f152a..1a55fdd3 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -49,7 +49,7 @@ <%= render partial: "shared/add_new_action" %> <%= render partial: "shared/goto" %> <%= render partial: "todos/todo_sub_menu" %> - <%= render partial: "projects/go_project" %> + <%= render partial: "projects/goto_item" %> <% end -%> <% # Javascripts diff --git a/app/views/projects/_go_project.html.erb b/app/views/projects/_go_project.html.erb deleted file mode 100644 index d6b5d6d6..00000000 --- a/app/views/projects/_go_project.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -
\ No newline at end of file diff --git a/app/views/projects/_goto_item.html.erb b/app/views/projects/_goto_item.html.erb new file mode 100644 index 00000000..530628a9 --- /dev/null +++ b/app/views/projects/_goto_item.html.erb @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/app/views/projects/_project_settings.html.erb b/app/views/projects/_project_settings.html.erb index 86311954..befc8cbc 100644 --- a/app/views/projects/_project_settings.html.erb +++ b/app/views/projects/_project_settings.html.erb @@ -1,6 +1,6 @@ <% project = project_settings -%> -Handling actions:
+