improve project show page and improve caching

This commit is contained in:
Reinier Balt 2013-08-08 18:21:56 +02:00
parent 8151cd9473
commit 2fc3f65368
10 changed files with 143 additions and 85 deletions

View file

@ -14,6 +14,9 @@
//= require jquery_ujs
//= require twitter/bootstrap/bootstrap-tooltip
//= require twitter/bootstrap/bootstrap-popover
//= require twitter/bootstrap/bootstrap-modal
//= require twitter/bootstrap/bootstrap-tab
//= require twitter/bootstrap/bootstrap-button
//= require mousetrap
// Stuff in vendor/assets

View file

@ -75,12 +75,15 @@ TracksApp =
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")
# do nothing if the new_todo is already selected
unless new_todo.attr("id") == selected_item.attr("id")
selected_item.find("div.todo-sub-menu").addClass("hide")
selected_item.find("span.todo-item-detail").addClass("hide")
TracksApp.noteOfTodo(selected_item).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
@ -111,16 +114,16 @@ TracksApp =
unless TracksApp.selectPrevNext(false)?
TracksApp.selectTodo($("div.todo-item").first())
noteOfTodo: (todo) ->
notes_id = todo.find("i.icon-book").attr("data-note-id")
$("div#" + notes_id )
toggleNoteOfTodo: (todo) ->
TracksApp.noteOfTodo(todo).toggleClass("hide")
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()
TracksApp.toggleNoteOfTodo(selected_item)
refresh_page: ->
location.reload(true)
@ -142,12 +145,12 @@ 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() )
$("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()
$("span.todo-description-icons i.icon-book").click -> TracksApp.toggleNoteOfTodo( $(this).parent().parent().parent().parent().parent() )
$("span.todo-item-description-container").click -> TracksApp.selectTodo( $(this).parent().parent().parent() )
autocompleteDataset = new Dataset
limit: 7
@ -174,4 +177,12 @@ $ ->
form.attr("action", base_url + base_id)
form.submit()
$('a[rel="tracks-popover"]').popover()
$('a[rel="tracks-popover"]').popover()
$('div.project-description button.close').on "click", ->
$(this).parent().addClass("hide")
$("a.tracks-badge-description").removeClass("hide")
$("a.tracks-badge-description").on "click", ->
$("div.project-description").removeClass("hide")
$(this).addClass("hide")

View file

@ -164,6 +164,30 @@ div.todos-container {
}
}
/* Project */
div.project-details {
font-style: italic;
}
div.project-description {
margin-top: 10px;
margin-bottom: 20px;
}
h3.project-name-container {
margin: 15px 0 0 0;
line-height: 25px;
}
div.project-badges {
}
div#project-next-prev {
margin: 0 0 0 0;
text-align: center;
}
/* Dialogs */
.modal-body {

View file

@ -45,6 +45,8 @@ class ContextsController < ApplicationController
@done = @context.todos.completed.limit(@max_completed).reorder("todos.completed_at DESC, todos.created_at DESC").includes(Todo::DEFAULT_INCLUDES)
@not_done_todos = @context.todos.active.reorder("todos.due IS NULL, todos.due ASC, todos.created_at ASC").includes(Todo::DEFAULT_INCLUDES)
@todos_without_project = @not_done_todos.select{|t| t.project.nil?}
@last_updated_todo_without_project = @todos_without_project
.inject(@todos_without_project.first){ |last, todo| todo.updated_at > last.updated_at ? todo : last }
@deferred_todos = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
@pending_todos = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES)

View file

@ -8,13 +8,40 @@ module ProjectsHelper
end
end
def project_details(project)
state = {
"complete" => "projects.was_marked_complete",
"hidden" => "projects.was_marked_hidden",
"active" => "projects.is_active"}
default_context = project.default_context.nil? ?
t('projects.with_no_default_context') :
t('projects.with_default_context', :context_name => project.default_context.name)
tags = project.default_tags.blank? ? t('projects.with_no_default_tags') : t('projects.with_default_tags', :tags => project.default_tags)
created_at = format_date(project.created_at)
modified_at = format_date(project.updated_at)
"#{t('projects.this_project')} #{t(state[project.state])} #{default_context} #{tags}." +
"#{t('projects.this_project')} was created at #{created_at} and last modified at #{modified_at}"
end
def project_next_prev
content_tag(:div, :id=>"project-next-prev") do
html = ""
html << link_to_project(@previous_project, "&laquo; #{@previous_project.shortened_name}".html_safe) if @previous_project
html << " | " if @previous_project && @next_project
html << link_to_project(@next_project, "#{@next_project.shortened_name} &raquo;".html_safe) if @next_project
html.html_safe
content_tag(:div, {class: "pagination", id: "project-next-prev"}) do
content_tag(:small) do
content_tag(:ul) do
html = ""
html << content_tag(:li) do
link_to_project(@previous_project, "&laquo; #{@previous_project.shortened_name}".html_safe)
end if @previous_project
html << content_tag(:li) do
link_to_project(@next_project, "#{@next_project.shortened_name} &raquo;".html_safe)
end if @next_project
html.html_safe
end
end
end
end

View file

@ -8,16 +8,24 @@
show_empty_containers = (@group_view_by == 'context')
-%>
<% cache("not_done_context", @not_done_todos.empty?) do -%>
<% cache ["not_done_context", @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 => show_empty_containers, :parent_container_type => 'context'}) %>
<% if @group_view_by == 'project' -%>
<%= show_todos_without_project(@todos_without_project, {:collapsible => false, :parent_container_type => 'context', :title_param => @context.name}) -%>
<% if @group_view_by == 'project'
cache [@last_updated_todo_without_project, @context, "todos_without_project"] do -%>
<%= show_todos_without_project(@todos_without_project,
{:collapsible => false, :parent_container_type => 'context', :title_param => @context.name}) -%>
<% end -%>
<% end -%>
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<% cache [@context, "deferred_pending"] do -%>
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<% end -%>
<%= show_done_todos(@done, done_todo_options) unless @done.nil? %>
<% # use the first completed todo (which is the last one to be completed) as cache invariant
cache [@context, @done.first, "context_completed"] do -%>
<%= show_done_todos(@done, done_todo_options) unless @done.nil? %>
<% end -%>

View file

@ -1,26 +0,0 @@
<% project = project_settings -%>
<div id='<%= dom_id(project) %>' class='project'>
<div class='project_settings'><%= t('projects.this_project') %>
<% if project.completed? -%><%= t('projects.was_marked_complete') %>
<% elsif project.hidden? -%><%= t('projects.was_marked_hidden') %>
<% else -%><%= t('projects.is_active') %>
<% end -%>
<% if project.default_context.nil? -%>
<%= t('projects.with_no_default_context') %>
<% else -%>
<%= t('projects.with_default_context', :context_name => project.default_context.name) %>
<% end -%>
<% if project.default_tags.nil? || project.default_tags.blank? -%>
<%= t('projects.with_no_default_tags') %>.
<% else -%>
<%= t('projects.with_default_tags', :tags => project.default_tags) %>.
<% end -%>
<%= link_to_edit_project(project, t('projects.edit_project_settings')) %>
</div>
<% unless project.description.blank? -%>
<div class='project_description'><%= Tracks::Utils.render_text(project.description) %></div>
<% end -%>
</div>
<div id='<%= dom_id(project, 'edit') %>' class='edit-form' style='display:none;'>
<div class='placeholder'> </div>
</div>

View file

@ -1,6 +1,18 @@
<h2 id="project_name_container"><%= show_project_name(project) %> </h2>
<a
role="button" title=""
data-placement="bottom" rel="tracks-popover" href="#"
data-original-title="Details of project" data-html="true"
data-content="<%= render(partial: "project_settings", object: project) %>"><i class="icon-info-sign"></i></a>
<h3 class="project-name-container"><%= show_project_name(project) %> </h3>
<div class="project-badges">
<a class="badge" title=""
data-placement="bottom" rel="tracks-popover" href="#"
data-original-title="<%= project.name %>" data-html="true"
data-content="<div class='project-details'><%= project_details(project) %></div>">
<i class="icon-info-sign"></i> Details
</a>
<a class="badge hide tracks-badge-description" title="Show project description" href="#">
<i class="icon-book"></i> Description
</a>
</div>
<% unless project.description.blank? %>
<div class='project-description alert alert-info'>
<button type="button" class="close">&times;</button>
<small><%= Tracks::Utils.render_text(project.description) %></small>
</div>
<% end %>

View file

@ -17,29 +17,26 @@
<%= render :partial => "project_settings_container", :locals => {:project => @project} %>
<% end %>
<% cache("not_done_project", @not_done_todos.empty?) do -%>
<% 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_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<% cache [@project, "deferred_pending"] do -%>
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<% end -%>
<%= show_done_todos(@done, done_todo_options) unless @done.nil? %>
<% # use the first completed todo (which is the last one to be completed) as cache invariant
cache [@project, @done.first, "project_completed"] do -%>
<%= show_done_todos(@done, done_todo_options) unless @done.nil? %>
<% end -%>
<%# TODO: new note impl -%>
<div class="container">
<div id="notes">
<div class="add_note_link"><%= link_to t('projects.add_note'), '#' %> </div>
<h2><%= t('projects.notes') %></h2>
<div id="empty-n" style="display:<%= @project.notes.empty? ? 'block' : 'none'%>;">
<div class="message"><p><%= t('projects.no_notes_attached') %></p></div>
</div>
<%= render :partial => "notes/notes_summary", :collection => @project.notes %>
</div>
</div>
<div id="new-note" style="display:none;">
<%# render :partial => "notes/note_edit_form", :object => @new_note, :locals => {:submit_text => t('projects.add_note_submit')} %>
</div>
</div>

View file

@ -8,15 +8,15 @@
<%= show_grouped_todos %>
<% if @group_view_by == 'project'
# use the last updated todo without a project as cache invariant.
# Changing an exisiting todo or adding a new one will result in a new cache key
cache [@last_updated_todo_without_project, "todos_without_project"] do -%>
<%= show_todos_without_project(@todos_without_project) %>
<% end
end
# use the last updated todo without a project as cache invariant.
# Changing an exisiting todo or adding a new one will result in a new cache key
cache [@last_updated_todo_without_project, "todos_without_project"] do -%>
<%= show_todos_without_project(@todos_without_project) %>
<% end
end
-%>
<% # use the first completed todo (which is the last one to be completed) as cache invariant
cache [@done.first, "home_completed"] do %>
<%= show_done_todos(@done, {:parent_container_type => @group_view_by, :collapsible => true}) unless @done.nil? %>
cache [@done.first, "home_completed"] do %>
<%= show_done_todos(@done, {:parent_container_type => @group_view_by, :collapsible => true}) unless @done.nil? %>
<% end %>