mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-28 10:04:07 +01:00
use twitter/typeahead for autocomplete. make go to project|context|tag work and show
project details in a popover
This commit is contained in:
parent
31386db3df
commit
c0edd1749c
19 changed files with 1924 additions and 187 deletions
|
|
@ -12,13 +12,10 @@
|
||||||
//
|
//
|
||||||
//= require jquery
|
//= require jquery
|
||||||
//= require jquery_ujs
|
//= require jquery_ujs
|
||||||
//= require twitter/bootstrap
|
//= require twitter/bootstrap/bootstrap-tooltip
|
||||||
|
//= require twitter/bootstrap/bootstrap-popover
|
||||||
//= require mousetrap
|
//= require mousetrap
|
||||||
|
|
||||||
// Stuff in app/assets
|
|
||||||
//= require tracks.js
|
|
||||||
//= require keybindings.js
|
|
||||||
|
|
||||||
// Stuff in vendor/assets
|
// Stuff in vendor/assets
|
||||||
// require jquery-ui-1.10.0.custom.min
|
// require jquery-ui-1.10.0.custom.min
|
||||||
// require jquery.ui.touch-punch.min
|
// require jquery.ui.touch-punch.min
|
||||||
|
|
@ -28,5 +25,10 @@
|
||||||
// require jquery.simulate.drag-sortable
|
// require jquery.simulate.drag-sortable
|
||||||
// require jquery.truncator
|
// require jquery.truncator
|
||||||
|
|
||||||
|
//= require typeahead
|
||||||
//= require jquery.cookie
|
//= require jquery.cookie
|
||||||
//= require swf_fu
|
//= require swf_fu
|
||||||
|
|
||||||
|
// Stuff in app/assets
|
||||||
|
//= require tracks.js
|
||||||
|
//= require keybindings.js
|
||||||
|
|
@ -48,13 +48,13 @@ $ ->
|
||||||
|
|
||||||
# GO TO
|
# GO TO
|
||||||
Mousetrap.bind 'G', -> TracksApp.go_menu()
|
Mousetrap.bind 'G', -> TracksApp.go_menu()
|
||||||
Mousetrap.bind 'g h', -> TracksApp.go_home()
|
Mousetrap.bind 'g h', -> TracksApp.go_home_page()
|
||||||
Mousetrap.bind 'g c', -> alert("go context")
|
Mousetrap.bind 'g c', -> TracksApp.go_context()
|
||||||
Mousetrap.bind 'g C', -> TracksApp.go_contexts()
|
Mousetrap.bind 'g C', -> TracksApp.go_contexts_page()
|
||||||
Mousetrap.bind 'g t', -> alert("go tag")
|
Mousetrap.bind 'g t', -> TracksApp.go_tag()
|
||||||
Mousetrap.bind 'g p', -> TracksApp.go_project()
|
Mousetrap.bind 'g p', -> TracksApp.go_project()
|
||||||
Mousetrap.bind 'g P', -> TracksApp.go_projects()
|
Mousetrap.bind 'g P', -> TracksApp.go_projects_page()
|
||||||
Mousetrap.bind 'g s', -> TracksApp.go_starred()
|
Mousetrap.bind 'g s', -> TracksApp.go_starred_page()
|
||||||
|
|
||||||
# VIEW
|
# VIEW
|
||||||
Mousetrap.bind 'v p', -> TracksApp.group_view_by_project()
|
Mousetrap.bind 'v p', -> TracksApp.group_view_by_project()
|
||||||
|
|
@ -62,4 +62,5 @@ $ ->
|
||||||
|
|
||||||
# Item Selection
|
# Item Selection
|
||||||
Mousetrap.bind 'j', -> TracksApp.selectNext()
|
Mousetrap.bind 'j', -> TracksApp.selectNext()
|
||||||
Mousetrap.bind 'k', -> TracksApp.selectPrev()
|
Mousetrap.bind 'k', -> TracksApp.selectPrev()
|
||||||
|
Mousetrap.bind 'n', -> TracksApp.toggleNoteOfSelectedTodo()
|
||||||
|
|
@ -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)
|
|
||||||
177
app/assets/javascripts/tracks.js.coffee.erb
Normal file
177
app/assets/javascripts/tracks.js.coffee.erb
Normal file
|
|
@ -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()
|
||||||
|
|
@ -13,4 +13,4 @@
|
||||||
*= require mousetrap
|
*= require mousetrap
|
||||||
*= require_tree ../../../vendor/assets/stylesheets
|
*= require_tree ../../../vendor/assets/stylesheets
|
||||||
*= require tracks
|
*= require tracks
|
||||||
*/
|
*/
|
||||||
|
|
@ -170,7 +170,7 @@ div.todos-container {
|
||||||
overflow-y: visible;
|
overflow-y: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#tracks-go-project-dialog {
|
div#tracks-go-item-dialog {
|
||||||
input.input-medium {
|
input.input-medium {
|
||||||
width : 95%;
|
width : 95%;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,9 @@ class ContextsController < ApplicationController
|
||||||
headers['Content-Type']=Mime::TEXT.to_s
|
headers['Content-Type']=Mime::TEXT.to_s
|
||||||
render :action => 'index', :layout => false, :content_type => Mime::TEXT
|
render :action => 'index', :layout => false, :content_type => Mime::TEXT
|
||||||
end
|
end
|
||||||
format.autocomplete &render_autocomplete
|
format.autocomplete do
|
||||||
|
render :text => for_autocomplete(@all_contexts, params[:query] || params[:term])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -220,12 +222,6 @@ class ContextsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_autocomplete
|
|
||||||
lambda do
|
|
||||||
render :text => for_autocomplete(current_user.contexts, params[:term])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def feed_options
|
def feed_options
|
||||||
Context.feed_options(current_user)
|
Context.feed_options(current_user)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -685,12 +685,13 @@ class TodosController < ApplicationController
|
||||||
|
|
||||||
def tags
|
def tags
|
||||||
# TODO: limit to current_user
|
# TODO: limit to current_user
|
||||||
tags_beginning = Tag.where('name like ?', params[:term]+'%')
|
term = params[:query] || param[:term]
|
||||||
tags_all = Tag.where('name like ?', '%'+params[:term]+'%')
|
tags_beginning = Tag.where('name like ?', term+'%')
|
||||||
|
tags_all = Tag.where('name like ?', '%'+term+'%')
|
||||||
tags_all= tags_all - tags_beginning
|
tags_all= tags_all - tags_beginning
|
||||||
|
|
||||||
respond_to do |format|
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,6 @@ module ProjectsHelper
|
||||||
end
|
end
|
||||||
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
|
def project_next_prev
|
||||||
content_tag(:div, :id=>"project-next-prev") do
|
content_tag(:div, :id=>"project-next-prev") do
|
||||||
html = ""
|
html = ""
|
||||||
|
|
@ -49,7 +43,7 @@ module ProjectsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_edit_project (project, descriptor = sanitize(project.name))
|
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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
<%= render partial: "shared/add_new_action" %>
|
<%= render partial: "shared/add_new_action" %>
|
||||||
<%= render partial: "shared/goto" %>
|
<%= render partial: "shared/goto" %>
|
||||||
<%= render partial: "todos/todo_sub_menu" %>
|
<%= render partial: "todos/todo_sub_menu" %>
|
||||||
<%= render partial: "projects/go_project" %>
|
<%= render partial: "projects/goto_item" %>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<%
|
<%
|
||||||
# Javascripts
|
# Javascripts
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
<div id="tracks-go-project-dialog" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
||||||
<h3 id="myModalLabel">Go to project</h3>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<form class="form-search">
|
|
||||||
<input type="text" id="tracks-goto-project" class="input-medium search-query ajax-typeahead" placeholder="Type (part of) project name"
|
|
||||||
data-link="/projects.autocomplete" autocomplete="off">
|
|
||||||
<input type="hidden" id="tracks-json-result">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
|
||||||
<button class="btn btn-primary">Go to project</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
16
app/views/projects/_goto_item.html.erb
Normal file
16
app/views/projects/_goto_item.html.erb
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<div id="tracks-go-item-dialog" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h3 id="myModalLabel">...</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form class="form-search" action="/goto" method="get" data-link="/goto">
|
||||||
|
<input type="text" id="tracks-goto-item" class="input-medium search-query ajax-typeahead" placeholder="..."
|
||||||
|
data-link="/from_go_item_dialog.autocomplete" autocomplete="off">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||||
|
<button class="btn btn-primary">Go to project</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<% project = project_settings -%>
|
<% project = project_settings -%>
|
||||||
<div id="<%= dom_id(project) %>" class="project">
|
<div id='<%= dom_id(project) %>' class='project'>
|
||||||
<div class="project_settings"><%= t('projects.this_project') %>
|
<div class='project_settings'><%= t('projects.this_project') %>
|
||||||
<% if project.completed? -%><%= t('projects.was_marked_complete') %>
|
<% if project.completed? -%><%= t('projects.was_marked_complete') %>
|
||||||
<% elsif project.hidden? -%><%= t('projects.was_marked_hidden') %>
|
<% elsif project.hidden? -%><%= t('projects.was_marked_hidden') %>
|
||||||
<% else -%><%= t('projects.is_active') %>
|
<% else -%><%= t('projects.is_active') %>
|
||||||
|
|
@ -18,9 +18,9 @@
|
||||||
<%= link_to_edit_project(project, t('projects.edit_project_settings')) %>
|
<%= link_to_edit_project(project, t('projects.edit_project_settings')) %>
|
||||||
</div>
|
</div>
|
||||||
<% unless project.description.blank? -%>
|
<% unless project.description.blank? -%>
|
||||||
<div class="project_description"><%= Tracks::Utils.render_text(project.description) %></div>
|
<div class='project_description'><%= Tracks::Utils.render_text(project.description) %></div>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
</div>
|
</div>
|
||||||
<div id="<%= dom_id(project, 'edit') %>" class="edit-form" style="display:none;">
|
<div id='<%= dom_id(project, 'edit') %>' class='edit-form' style='display:none;'>
|
||||||
<div class="placeholder"> </div>
|
<div class='placeholder'> </div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="container project">
|
<h2 id="project_name_container"><%= show_project_name(project) %> </h2>
|
||||||
<h2 id="project_name_container">
|
<a
|
||||||
<%= show_project_name(project) %>
|
role="button" title=""
|
||||||
</h2>
|
data-placement="bottom" rel="tracks-popover" href="#"
|
||||||
<%= show_project_settings(project) %>
|
data-original-title="Details of project" data-html="true"
|
||||||
</div>
|
data-content="<%= render(partial: "project_settings", object: project) %>"><i class="icon-info-sign"></i></a>
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,13 @@
|
||||||
<div id="display_box">
|
<div id="display_box">
|
||||||
<%= project_next_prev %>
|
<%= project_next_prev %>
|
||||||
|
|
||||||
<%= render :partial => "project_settings_container", :locals => {:project => @project} %>
|
<% cache @project do %>
|
||||||
|
<%= render :partial => "project_settings_container", :locals => {:project => @project} %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%= empty_message_holder("not_done_context", @not_done_todos.empty?) %>
|
<% cache("not_done_project", @not_done_todos.empty?) do -%>
|
||||||
|
<%= render partial: "todos/empty_message_container", locals: {:show => @not_done_todos.empty?, :container_name => "not_done"} %>
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
<%= show_grouped_todos({:collapsible => false, :show_empty_containers => false, :parent_container_type => 'project' }) %>
|
<%= show_grouped_todos({:collapsible => false, :show_empty_containers => false, :parent_container_type => 'project' }) %>
|
||||||
|
|
||||||
|
|
@ -35,12 +39,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="new-note" style="display:none;">
|
<div id="new-note" style="display:none;">
|
||||||
<%= render :partial => "notes/note_edit_form", :object => @new_note, :locals => {:submit_text => t('projects.add_note_submit')} %>
|
<%# render :partial => "notes/note_edit_form", :object => @new_note, :locals => {:submit_text => t('projects.add_note_submit')} %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="input_box">
|
|
||||||
<%= render :partial => "shared/add_new_item_form" %>
|
|
||||||
<%= render :file => "sidebar/sidebar" %>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -23,6 +23,10 @@
|
||||||
<li><span class="badge">v</span> then <span class="badge">p</span>: group the actions on the page by project</li>
|
<li><span class="badge">v</span> then <span class="badge">p</span>: group the actions on the page by project</li>
|
||||||
<li><span class="badge">v</span> then <span class="badge">c</span>: group the actions on the page by context</li>
|
<li><span class="badge">v</span> then <span class="badge">c</span>: group the actions on the page by context</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<p>Handling actions:</p>
|
||||||
|
<ul>
|
||||||
|
<li><span class="badge">n</span>: Toggle the notes of the selected action</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
hidden_options = options.clone
|
hidden_options = options.clone
|
||||||
done_options = options.clone
|
done_options = options.clone
|
||||||
-%>
|
-%>
|
||||||
<% cache("not_done_with_tag_#{@tag_name}", @not_done_todos.empty?) do -%>
|
<% cache ["not_done_with_tag_#{@tag_name}", @not_done_todos.empty?] do -%>
|
||||||
<%= render partial: "empty_message_container", locals: {:show => @not_done_todos.empty?, :container_name => "not_done_with_tag"} %>
|
<%= render partial: "empty_message_container", locals: {:show => @not_done_todos.empty?, :container_name => "not_done_with_tag"} %>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
|
|
|
||||||
1633
vendor/assets/javascripts/typeahead.js
vendored
Normal file
1633
vendor/assets/javascripts/typeahead.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
49
vendor/assets/stylesheets/typeahead.js-bootstrap.css
vendored
Normal file
49
vendor/assets/stylesheets/typeahead.js-bootstrap.css
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
.twitter-typeahead .tt-query,
|
||||||
|
.twitter-typeahead .tt-hint {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-dropdown-menu {
|
||||||
|
min-width: 160px;
|
||||||
|
margin-top: 2px;
|
||||||
|
padding: 5px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border: 1px solid rgba(0,0,0,.2);
|
||||||
|
*border-right-width: 2px;
|
||||||
|
*border-bottom-width: 2px;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
-moz-border-radius: 6px;
|
||||||
|
border-radius: 6px;
|
||||||
|
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||||
|
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||||
|
box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||||
|
-webkit-background-clip: padding-box;
|
||||||
|
-moz-background-clip: padding;
|
||||||
|
background-clip: padding-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-suggestion {
|
||||||
|
display: block;
|
||||||
|
padding: 3px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-suggestion.tt-cursor {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #0081c2;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0077b3);
|
||||||
|
background-image: linear-gradient(to bottom, #0088cc, #0077b3);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-suggestion.tt-cursor a {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tt-suggestion p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue