mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-16 15:20:13 +01:00
initial changes to add an option to select either context or project as grouping of todos on home or tag page
* new menu item in view menu * js to toggle view * store setting in cookie to keep de choice of view persistent * refactor index and tag page of todos to look more alike * refactor context and project partials to look more alike
This commit is contained in:
parent
55aa387ab9
commit
f22dfc1f9b
15 changed files with 160 additions and 84 deletions
|
|
@ -318,6 +318,17 @@ var TracksPages = {
|
|||
}
|
||||
});
|
||||
|
||||
$("a#group_view_by_link").click(function () {
|
||||
var state = $(this).attr("x_current_group_by")
|
||||
if(state =='context'){
|
||||
state='project';
|
||||
} else {
|
||||
state='context';
|
||||
}
|
||||
$.cookie('group_view_by', state);
|
||||
refresh_page();
|
||||
});
|
||||
|
||||
/* fade flashes and alerts in automatically */
|
||||
$(".alert").fadeOut(8000);
|
||||
}
|
||||
|
|
@ -696,7 +707,7 @@ var ProjectListPage = {
|
|||
},
|
||||
setup_behavior: function() {
|
||||
/* in-place edit of project name */
|
||||
$('div#project_name').editable(ProjectListPage.save_project_name, {
|
||||
$('span#project_name').editable(ProjectListPage.save_project_name, {
|
||||
style: 'padding: 0px; width=100%;',
|
||||
submit: i18n['common.ok'],
|
||||
cancel: i18n['common.cancel'],
|
||||
|
|
|
|||
|
|
@ -128,9 +128,9 @@ class ProjectsController < ApplicationController
|
|||
init_data_for_sidebar unless mobile?
|
||||
@page_title = t('projects.page_title', :project => @project.name)
|
||||
|
||||
@not_done = @project.todos.active_or_hidden.includes(Todo::DEFAULT_INCLUDES)
|
||||
@deferred = @project.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
||||
@pending = @project.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
||||
@not_done_todos = @project.todos.active_or_hidden.includes(Todo::DEFAULT_INCLUDES)
|
||||
@deferred_todos = @project.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
||||
@pending_todos = @project.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
||||
|
||||
@done = {}
|
||||
@done = @project.todos.completed.
|
||||
|
|
@ -138,8 +138,8 @@ class ProjectsController < ApplicationController
|
|||
limit(current_user.prefs.show_number_completed).
|
||||
includes(Todo::DEFAULT_INCLUDES) unless current_user.prefs.show_number_completed == 0
|
||||
|
||||
@count = @not_done.size
|
||||
@down_count = @count + @deferred.size + @pending.size
|
||||
@count = @not_done_todos.size
|
||||
@down_count = @count + @deferred_todos.size + @pending_todos.size
|
||||
@next_project = current_user.projects.next_from(@project)
|
||||
@previous_project = current_user.projects.previous_from(@project)
|
||||
@default_tags = @project.default_tags
|
||||
|
|
@ -159,9 +159,9 @@ class ProjectsController < ApplicationController
|
|||
end
|
||||
format.xml do
|
||||
render :xml => @project.to_xml(:except => :user_id) { |xml|
|
||||
xml.not_done { @not_done.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
xml.deferred { @deferred.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
xml.pending { @pending.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
xml.not_done { @not_done_todos.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
xml.deferred { @deferred_todos.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
xml.pending { @pending_todos.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
xml.done { @done.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
||||
}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,49 +8,18 @@ class TodosController < ApplicationController
|
|||
|
||||
def index
|
||||
@source_view = params['_source_view'] || 'todo'
|
||||
@group_view_by = cookies['group_view_by'] || 'context'
|
||||
init_data_for_sidebar unless mobile?
|
||||
|
||||
@todos = current_user.todos.includes(Todo::DEFAULT_INCLUDES)
|
||||
@todos = @todos.limit(sanitize(params[:limit])) if params[:limit]
|
||||
|
||||
# TODO: refactor text feed for done todos to todos/done.text, not /todos.text?done=true
|
||||
if params[:done]
|
||||
@not_done_todos = current_user.todos.completed.completed_after(Time.zone.now - params[:done].to_i.days)
|
||||
else
|
||||
@not_done_todos = current_user.todos.active.not_hidden
|
||||
end
|
||||
|
||||
@not_done_todos = @not_done_todos.
|
||||
reorder("todos.due IS NULL, todos.due ASC, todos.created_at ASC").
|
||||
includes(Todo::DEFAULT_INCLUDES)
|
||||
|
||||
if params[:limit]
|
||||
@not_done_todos = @not_done_todos.limit(sanitize(params[:limit]))
|
||||
@todos = @todos.limit(sanitize(params[:limit]))
|
||||
end
|
||||
|
||||
if params[:due]
|
||||
due_within_when = Time.zone.now + params['due'].to_i.days
|
||||
@not_done_todos = @not_done_todos.where('todos.due <= ?', due_within_when)
|
||||
end
|
||||
|
||||
if params[:tag]
|
||||
tag = Tag.where(:name => params['tag']).first
|
||||
@not_done_todos = @not_done_todos.where('taggings.tag_id = ?', tag.id)
|
||||
end
|
||||
|
||||
if params[:context_id]
|
||||
context = current_user.contexts.find(params[:context_id])
|
||||
@not_done_todos = @not_done_todos.where('context_id' => context.id)
|
||||
end
|
||||
|
||||
if params[:project_id]
|
||||
project = current_user.projects.find(params[:project_id])
|
||||
@not_done_todos = @not_done_todos.where('project_id' => project)
|
||||
end
|
||||
@not_done_todos = get_not_done_todos
|
||||
|
||||
@projects = current_user.projects.includes(:default_context)
|
||||
@contexts = current_user.contexts
|
||||
@contexts_to_show = current_user.contexts.active
|
||||
@projects_to_show = current_user.projects.active
|
||||
|
||||
# If you've set no_completed to zero, the completed items box isn't shown
|
||||
# on the home page
|
||||
|
|
@ -674,11 +643,11 @@ class TodosController < ApplicationController
|
|||
hidden.
|
||||
reorder('todos.completed_at DESC, todos.created_at DESC').
|
||||
includes(Todo::DEFAULT_INCLUDES)
|
||||
@deferred = todos_with_tag_ids.
|
||||
@deferred_todos = todos_with_tag_ids.
|
||||
deferred.
|
||||
reorder('todos.show_from ASC, todos.created_at DESC').
|
||||
includes(Todo::DEFAULT_INCLUDES)
|
||||
@pending = todos_with_tag_ids.
|
||||
@pending_todos = todos_with_tag_ids.
|
||||
blocked.
|
||||
reorder('todos.show_from ASC, todos.created_at DESC').
|
||||
includes(Todo::DEFAULT_INCLUDES)
|
||||
|
|
@ -692,7 +661,8 @@ class TodosController < ApplicationController
|
|||
|
||||
@projects = current_user.projects
|
||||
@contexts = current_user.contexts
|
||||
@contexts_to_show = @contexts.reject {|c| c.hidden? }
|
||||
@contexts_to_show = @contexts.active
|
||||
@projects_to_show = @projects.active
|
||||
|
||||
# Set defaults for new_action
|
||||
@initial_tags = @tag_name
|
||||
|
|
@ -959,6 +929,8 @@ class TodosController < ApplicationController
|
|||
@single_tag = @tag_expr.size == 1 && @tag_expr[0].size == 1
|
||||
@tag_name = @tag_expr[0][0]
|
||||
@tag_title = @single_tag ? @tag_name : tag_title(@tag_expr)
|
||||
|
||||
@group_view_by = cookies['group_view_by'] || 'context'
|
||||
end
|
||||
|
||||
def get_ids_from_tag_expr(tag_expr)
|
||||
|
|
@ -1373,6 +1345,44 @@ class TodosController < ApplicationController
|
|||
completed_todos.completed_before(start_of_this_week).completed_after(start_of_this_month).all(includes)
|
||||
end
|
||||
|
||||
def get_not_done_todos
|
||||
# TODO: refactor text feed for done todos to todos/done.text, not /todos.text?done=true
|
||||
if params[:done]
|
||||
not_done_todos = current_user.todos.completed.completed_after(Time.zone.now - params[:done].to_i.days)
|
||||
else
|
||||
not_done_todos = current_user.todos.active.not_hidden
|
||||
end
|
||||
|
||||
not_done_todos = not_done_todos.
|
||||
reorder("todos.due IS NULL, todos.due ASC, todos.created_at ASC").
|
||||
includes(Todo::DEFAULT_INCLUDES)
|
||||
|
||||
not_done_todos = not_done_todos.limit(sanitize(params[:limit])) if params[:limit]
|
||||
|
||||
if params[:due]
|
||||
due_within_when = Time.zone.now + params['due'].to_i.days
|
||||
not_done_todos = not_done_todos.where('todos.due <= ?', due_within_when)
|
||||
end
|
||||
|
||||
if params[:tag]
|
||||
tag = Tag.where(:name => params['tag']).first
|
||||
not_done_todos = not_done_todos.where('taggings.tag_id = ?', tag.id)
|
||||
end
|
||||
|
||||
if params[:context_id]
|
||||
context = current_user.contexts.find(params[:context_id])
|
||||
not_done_todos = not_done_todos.where('context_id' => context.id)
|
||||
end
|
||||
|
||||
if params[:project_id]
|
||||
project = current_user.projects.find(params[:project_id])
|
||||
not_done_todos = not_done_todos.where('project_id' => project)
|
||||
end
|
||||
|
||||
return not_done_todos
|
||||
end
|
||||
|
||||
|
||||
class TodoCreateParamsHelper
|
||||
|
||||
def initialize(params, prefs)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,28 @@
|
|||
# application.
|
||||
module ApplicationHelper
|
||||
|
||||
def group_view_by_menu_entry
|
||||
# not set, no menu entry
|
||||
return "" if @group_view_by.nil?
|
||||
|
||||
# if view == context, the menu shows Order By Project
|
||||
menu_name = @group_view_by == 'context' ? 'project' : 'context'
|
||||
|
||||
content_tag(:li) do
|
||||
link_to(
|
||||
t("layouts.navigation.group_view_by_#{menu_name}"),
|
||||
'#',
|
||||
{:id => "group_view_by_link", :accesskey => "g", :title => t('layouts.navigation.group_view_by_title'), :x_current_group_by => @group_view_by} )
|
||||
end
|
||||
end
|
||||
|
||||
def container_toggle(id)
|
||||
link_to(
|
||||
image_tag("blank.png", :alt => t('common.collapse_expand')),
|
||||
"#",
|
||||
{:class => "container_toggle", :id => id} )
|
||||
end
|
||||
|
||||
def navigation_link(name, options = {}, html_options = nil, *parameters_for_method_reference)
|
||||
link_to name, options, html_options
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
module ContextsHelper
|
||||
|
||||
def show_context_name(context)
|
||||
if source_view_is :context
|
||||
content_tag(:span, :id => "context_name"){context.name}
|
||||
else
|
||||
link_to_context( context )
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_delete_context(context, descriptor = sanitize(context.name))
|
||||
link_to(descriptor,
|
||||
context_path(context, :format => 'js'),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,19 @@
|
|||
module ProjectsHelper
|
||||
|
||||
def show_project_name(project)
|
||||
if source_view_is :project
|
||||
content_tag(:span, :id => "project_name"){project.name}
|
||||
else
|
||||
link_to_project( project )
|
||||
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
|
||||
html = ""
|
||||
html << link_to_project(@previous_project, "« #{@previous_project.shortened_name}".html_safe) if @previous_project
|
||||
|
|
|
|||
|
|
@ -1,5 +1,19 @@
|
|||
module TodosHelper
|
||||
|
||||
def empty_message_holder(show)
|
||||
content_tag(:div, :id => "no_todos_in_view", :class => "container context", :style => "display:" + (show ? "block" : "none") ) do
|
||||
content_tag(:h2) { t('todos.no_actions_found_title') }
|
||||
content_tag(:div, :class => "message") do
|
||||
content_tag(:p) { t('todos.no_actions_found') }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show_grouped_todos
|
||||
collection = (@group_view_by == 'context') ? @contexts_to_show : @projects_to_show
|
||||
render(:partial => collection, :locals => { :collapsible => true })
|
||||
end
|
||||
|
||||
def remote_star_icon(todo=@todo)
|
||||
link_to( image_tag_for_star(todo),
|
||||
toggle_star_todo_path(todo),
|
||||
|
|
|
|||
|
|
@ -6,14 +6,8 @@ cache [context, @source_view, current_user.date.strftime("%Y%m%d"), @tag_name] d
|
|||
%>
|
||||
<div id="c<%= context.id %>" class="container context" style="display:<%= (collapsible && @not_done.empty?) ? "none" : "block" %>">
|
||||
<h2>
|
||||
<% if collapsible -%>
|
||||
<a href="#" class="container_toggle" id="toggle_c<%= context.id %>"><%= image_tag("blank.png", :alt => t('common.collapse_expand')) %></a>
|
||||
<% end -%>
|
||||
<% if source_view_is :context %>
|
||||
<span id="context_name"><%= context.name %></span>
|
||||
<% else %>
|
||||
<%= link_to_context( context ) %>
|
||||
<% end %>
|
||||
<%= container_toggle("toggle_c#{context.id}") %>
|
||||
<%= show_context_name(context) %>
|
||||
</h2>
|
||||
<div id="c_<%=context.id%>_target" class="context_target drop_target"></div>
|
||||
<div id="c<%= context.id %>items" class="items toggle_target">
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@
|
|||
<li><%= navigation_link( t('layouts.navigation.completed_tasks'), done_overview_path, {:accesskey=>"d", :title=>t('layouts.navigation.completed_tasks_title')} ) %></li>
|
||||
<li><%= navigation_link( t('layouts.navigation.feeds'), feeds_path, :title => t('layouts.navigation.feeds_title')) %></li>
|
||||
<li><%= navigation_link( t('layouts.navigation.stats'), stats_path, :title => t('layouts.navigation.stats_title')) %></li>
|
||||
<li><hr/></li>
|
||||
<%= group_view_by_menu_entry %>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#"><%= t('layouts.navigation.admin') %></a>
|
||||
|
|
|
|||
|
|
@ -1,21 +1,16 @@
|
|||
<%
|
||||
@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
|
||||
cache [project, current_user.date.strftime("%Y%m%d")] do %>
|
||||
<div class="container">
|
||||
<h2 id="project_name_container">
|
||||
<% if collapsible -%>
|
||||
<a href="#" class="container_toggle" id="toggle_p<%= project.id %>"><%= image_tag("blank.png", :alt => t('common.collapse_expand')) %></a>
|
||||
<% end -%>
|
||||
<div id="project_name" style="width: 100%;"><%= project.name -%></div>
|
||||
</h2>
|
||||
<div id="<%= dom_id(project, "container")%>" class="list">
|
||||
<%= render :partial => "projects/project_settings", :object => project, :locals => { :collapsible => collapsible } %>
|
||||
</div>
|
||||
</div>
|
||||
cache [project, @source_view, current_user.date.strftime("%Y%m%d")] do
|
||||
%>
|
||||
<%= render :partial => "project_settings_container", :locals => {:project => project} if source_view_is :project %>
|
||||
|
||||
<div class="container">
|
||||
<h2><%= t('projects.actions_in_project_title') %></h2>
|
||||
<div id="p<%= project.id %>" class="container project" style="display:<%= (collapsible && @not_done.empty?) ? "none" : "block" %>">
|
||||
<h2>
|
||||
<%= container_toggle("toggle_p#{project.id}") if collapsible %>
|
||||
<%= source_view_is(:project) ? t('projects.actions_in_project_title') : show_project_name(project) %>
|
||||
</h2>
|
||||
<div id="p<%= project.id %>items" class="items toggle_target">
|
||||
<div id="p<%= project.id %>empty-nd" style="display:<%= @not_done.empty? ? 'block' : 'none'%>;">
|
||||
<div class="message"><p><%= t('projects.no_actions_in_project') %></p></div>
|
||||
|
|
@ -23,4 +18,5 @@ cache [project, current_user.date.strftime("%Y%m%d")] do %>
|
|||
<%= render :partial => "todos/todo", :collection => @not_done, :locals => { :parent_container_type => "project" } %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
|
|
|||
6
app/views/projects/_project_settings_container.html.erb
Normal file
6
app/views/projects/_project_settings_container.html.erb
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<div class="container project">
|
||||
<h2 id="project_name_container">
|
||||
<%= show_project_name(project) %>
|
||||
</h2>
|
||||
<%= show_project_settings(project) %>
|
||||
</div>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
|
||||
<%= render :partial => @project, :locals => {:collapsible => false } %>
|
||||
<%= render :partial => "todos/deferred", :object => @deferred, :locals => { :collapsible => false, :append_descriptor => t('projects.todos_append'), :parent_container_type => 'project', :pending => @pending } %>
|
||||
<%= render :partial => "todos/deferred", :object => @deferred_todos, :locals => { :collapsible => false, :append_descriptor => t('projects.todos_append'), :parent_container_type => 'project', :pending => @pending_todos } %>
|
||||
<% unless @max_completed==0 -%>
|
||||
<%= render :partial => "todos/completed", :object => @done, :locals => { :collapsible => false, :suppress_project => true, :append_descriptor => t('projects.todos_append') } %>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
<div id="display_box">
|
||||
<div id="no_todos_in_view" class="container context" style="display:<%= @not_done_todos.empty? ? "block" : "none" %>">
|
||||
<h2><%= t('todos.no_actions_found_title')%></h2>
|
||||
<div class="message"><p><%= t('todos.no_actions_found') %></p></div>
|
||||
</div>
|
||||
<%= render(:partial => @contexts_to_show, :locals => { :collapsible => true }) -%>
|
||||
<%= empty_message_holder(@not_done_todos.empty?) %>
|
||||
|
||||
<%= show_grouped_todos %>
|
||||
|
||||
<% unless @done.nil? -%>
|
||||
<%= render(:partial => "todos/completed", :object => @done,
|
||||
:locals => { :collapsible => true, :append_descriptor => nil }) -%>
|
||||
<% end -%>
|
||||
</div>
|
||||
|
||||
<div id="input_box">
|
||||
<%= render :partial => "shared/add_new_item_form" %>
|
||||
<%= render :file => "sidebar/sidebar" %>
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
<div id="display_box">
|
||||
<div id="no_todos_in_view" class="container context" <%= "style=\"display:none\"".html_safe unless @not_done_todos.empty? %> >
|
||||
<h2><%= t('todos.no_actions_found_title')%></h2>
|
||||
<div class="message"><p><%= t('todos.no_actions_with', :tag_name=>@tag_name) %></p></div>
|
||||
</div>
|
||||
<%= empty_message_holder(@not_done_todos.empty?) %>
|
||||
|
||||
<%= render :partial => "contexts/context", :collection => @contexts_to_show,
|
||||
:locals => { :collapsible => true } %>
|
||||
<%= show_grouped_todos %>
|
||||
|
||||
<% unless @deferred.nil? -%>
|
||||
<% unless @deferred_todos.nil? -%>
|
||||
<%= render :partial => "todos/deferred", :locals => {
|
||||
:deferred => @deferred,
|
||||
:pending => @pending,
|
||||
:deferred => @deferred_todos,
|
||||
:pending => @pending_todos,
|
||||
:collapsible => true,
|
||||
:append_descriptor => t('todos.tagged_with', :tag_name => @tag_title),
|
||||
:parent_container_type => 'tag'
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ en:
|
|||
admin: Admin
|
||||
help: "?"
|
||||
mobile: Mobile Site
|
||||
group_view_by_context: "Order by context"
|
||||
group_view_by_project: "Order by project"
|
||||
group_view_by_title: "Change the ordering of the actions on this page"
|
||||
integrations:
|
||||
opensearch_description: Search in Tracks
|
||||
applescript_next_action_prompt: "Description of next action:"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue