mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-24 08:04:08 +01:00
Merge branch 'master' of git@github.com:gorn/tracks
This commit is contained in:
commit
8aa573a73e
106 changed files with 2221 additions and 585 deletions
|
|
@ -25,7 +25,9 @@
|
|||
<% end -%>
|
||||
<% if source_view_is :context %>
|
||||
<span class="in_place_editor_field" id="context_name_in_place_editor"><%= context.name %></span>
|
||||
<%= in_place_editor 'context_name_in_place_editor', { :url => { :controller => 'contexts', :action => 'update', :id => context.id, :field => 'name', :wants_render => false, :escape => false} , :options=>"{method:'put'}" } %>
|
||||
<%= in_place_editor 'context_name_in_place_editor', {
|
||||
:url => { :controller => 'contexts', :action => 'update', :id => context.id, :field => 'name', :update_context_name => true, :escape => false},
|
||||
:options=>"{method:'put'}", :script => true } %>
|
||||
<% else %>
|
||||
<%= link_to_context( context ) %>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -53,4 +53,9 @@
|
|||
</div>
|
||||
<%
|
||||
sortable_element 'list-contexts', get_listing_sortable_options
|
||||
-%>
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
Nifty("div#context_new_container","normal");
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
10
app/views/contexts/update_context_name.js.rjs
Normal file
10
app/views/contexts/update_context_name.js.rjs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
page['context_name_in_place_editor'].replace_html @context.name
|
||||
|
||||
page['default_context_name_id'].value = @context.name
|
||||
page['todo_context_name'].value = @context.name
|
||||
|
||||
# renew context auto complete array
|
||||
page << "contextAutoCompleter.options.array = #{context_names_for_autocomplete}; contextAutoCompleter.changed = true"
|
||||
|
||||
status_message = "Name of context was changed"
|
||||
page.notify :notice, status_message, 5.0
|
||||
|
|
@ -1,44 +1,49 @@
|
|||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h3>Exporting data</h3>
|
||||
<p>You can choose between the following formats:</p>
|
||||
<ul>
|
||||
<li><strong>YAML: </strong>Best for exporting data. <br/><i>Please note that importing YAML files is currently supported only in experimentally. Do not rely on it for backing up critical data.</i></li>
|
||||
<li><strong>CSV: </strong>Best for importing into spreadsheet or data analysis software</li>
|
||||
<li><strong>XML: </strong>Best for importing or repurposing the data</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<table class="export_table">
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th>Download link</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>YAML file containing all your actions, contexts, projects, tags and notes</td>
|
||||
<td><%= link_to "YAML file", :controller => 'data', :action => 'yaml_export' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CSV file containing all of your actions, with named contexts and projects</td>
|
||||
<td><%= link_to "CSV file (actions, contexts and projects)", :controller => 'data', :action => 'csv_actions' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CSV file containing all your notes</td>
|
||||
<td><%= link_to "CSV file (notes only)", :controller => 'data', :action => 'csv_notes' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XML file containing all your actions, contexts, projects, tags and notes</td>
|
||||
<td><%= link_to "XML file (actions only)", :controller => 'data', :action => 'xml_export' %></td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h3>Importing data</h3>
|
||||
<p>Curently there is a experimental support for importing YAML files. Beware: all your current data will be destroyed before importing the YAML file, so if you have access to the database, we strongly reccoment backing up the database right now in case that anything goes wrong.</p>
|
||||
<p><%= link_to "Start import", :controller => 'data', :action => 'yaml_form' %>.</p>
|
||||
<div id="display_box">
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<h3>Importing data</h3>
|
||||
<p>Curently there is a experimental support for importing YAML files.
|
||||
Beware: all your current data will be destroyed before importing the YAML
|
||||
file, so if you have access to the database, we strongly recomment backing up
|
||||
the database right now in case that anything goes wrong.
|
||||
</p>
|
||||
<p><%= link_to "Start import", :controller => 'data', :action => 'yaml_form' %>.</p>
|
||||
<br/><br/><h3>Exporting data</h3>
|
||||
<p>You can choose between the following formats:</p>
|
||||
<ul>
|
||||
<li><strong>YAML: </strong>Best for exporting data. <br/><i>Please note that importing YAML files is currently supported only in experimentally. Do not rely on it for backing up critical data.</i></li>
|
||||
<li><strong>CSV: </strong>Best for importing into spreadsheet or data analysis software</li>
|
||||
<li><strong>XML: </strong>Best for importing or repurposing the data</li>
|
||||
</ul>
|
||||
</div>
|
||||
<br/><br/>
|
||||
<table class="export_table">
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th>Download link</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>YAML file containing all your actions, contexts, projects, tags and notes</td>
|
||||
<td><%= link_to "YAML file", :controller => 'data', :action => 'yaml_export' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CSV file containing all of your actions, with named contexts and projects</td>
|
||||
<td><%= link_to "CSV file (actions, contexts and projects)", :controller => 'data', :action => 'csv_actions' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CSV file containing all your notes</td>
|
||||
<td><%= link_to "CSV file (notes only)", :controller => 'data', :action => 'csv_notes' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>XML file containing all your actions, contexts, projects, tags and notes</td>
|
||||
<td><%= link_to "XML file (actions only)", :controller => 'data', :action => 'xml_export' %></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div><!-- End of feeds -->
|
||||
</div>
|
||||
|
||||
</div><!-- End of feeds -->
|
||||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
Nifty("div#feedlegend","normal");
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,23 @@
|
|||
<div id="display_box">
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<p><b>Beware</b>: all your current data will be destroyed before importing the YAML file, so if you have access to the database, we strongly reccoment backing up the database right now in case that anything goes wrong.</p>
|
||||
<p>Paste the contents of the YAML file you exported into the text box below:</p>
|
||||
</div>
|
||||
<p>
|
||||
<% form_for :import, @import, :url => {:controller => 'data', :action => 'yaml_import'} do |f| %>
|
||||
<%= f.text_area :yaml %><br />
|
||||
<input type="submit" value="Import data">
|
||||
<% end %>
|
||||
</p>
|
||||
</div><!-- End of feeds -->
|
||||
<div id="feeds">
|
||||
<div id="feedlegend">
|
||||
<p><b>Beware</b>: all your current data will be destroyed before importing
|
||||
the YAML file, so if you have access to the database, we strongly recommend
|
||||
backing up the database right now in case that anything goes wrong.
|
||||
</p>
|
||||
<p>Paste the contents of the YAML file you exported into the text box below:</p>
|
||||
</div>
|
||||
<p>
|
||||
<% form_for :import, @import, :url => {:controller => 'data', :action => 'yaml_import'} do |f| %>
|
||||
<%= f.text_area :yaml %><br />
|
||||
<input type="submit" value="Import data">
|
||||
<% end %>
|
||||
</p>
|
||||
</div><!-- End of feeds -->
|
||||
</div><!-- End of display_box -->
|
||||
|
||||
<div id="input_box">
|
||||
</div><!-- End of input box -->
|
||||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
Nifty("div#feedlegend","normal");
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -64,10 +64,13 @@
|
|||
Active projects with their actions
|
||||
</li>
|
||||
<li><h4>Feeds for incomplete actions in a specific context:</h4>
|
||||
<% if @active_contexts.empty? && @hidden_contexts.empty? -%>
|
||||
<ul><li>There need to be at least one context before you can request a feed</li></ul>
|
||||
<% else -%>
|
||||
<ul>
|
||||
<li>Step 1 - Choose the context you want a feed of:
|
||||
<select name="feed-contexts" id="feed-contexts">
|
||||
<%= options_from_collection_for_select(@active_contexts, "id", "name", @active_contexts.first.id) -%>
|
||||
<%= options_from_collection_for_select(@active_contexts, "id", "name", @active_contexts.first.id) unless @active_projects.empty?-%>
|
||||
<%= options_from_collection_for_select(@hidden_contexts, "id", "name") -%>
|
||||
</select>
|
||||
<%= observe_field "feed-contexts", :update => "feeds-for-context",
|
||||
|
|
@ -80,17 +83,21 @@
|
|||
<li>Step 2 - Select the feed for this context
|
||||
<div id="feedicons-context">
|
||||
<div id="feeds-for-context">
|
||||
<%= render :partial => 'feed_for_context', :locals => { :context => @active_contexts.first } %>
|
||||
<%= render :partial => 'feed_for_context', :locals => { :context => @active_contexts.empty? ? @hidden_contexts.first : @active_contexts.first } %>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<% end -%>
|
||||
</li>
|
||||
<li><h4>Feeds for incomplete actions in a specific project:</h4>
|
||||
<% if @active_projects.empty? && @hidden_projects.empty? -%>
|
||||
<ul><li>There need to be at least one project before you can request a feed</li></ul>
|
||||
<% else -%>
|
||||
<ul>
|
||||
<li>Step 1 - Choose the project you want a feed of:
|
||||
<select name="feed-projects" id="feed-projects">
|
||||
<%= options_from_collection_for_select(@active_projects, "id", "name", @active_projects.first.id) -%>
|
||||
<%= options_from_collection_for_select(@active_projects, "id", "name", @active_projects.first.id) unless @active_projects.empty?-%>
|
||||
<%= options_from_collection_for_select(@hidden_projects, "id", "name") -%>
|
||||
<%= options_from_collection_for_select(@completed_projects, "id", "name") -%>
|
||||
</select>
|
||||
|
|
@ -104,11 +111,12 @@
|
|||
<li>Step 2 - Select the feed for this project
|
||||
<div id="feedicons-project">
|
||||
<div id="feeds-for-project">
|
||||
<%= render :partial => 'feed_for_project', :locals => { :project => @active_projects.first } %>
|
||||
<%= render :partial => 'feed_for_project', :locals => { :project => @active_projects.empty? ? @hidden_projects.first : @active_projects.first } %>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<% end -%>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ the newly created action.
|
|||
*)
|
||||
|
||||
(* Edit appropriately for your setup *)
|
||||
property myUsername to "<%= current_user.login %>"
|
||||
property myToken to "<%= current_user.token %>"
|
||||
property myContextID to <%= context.id %> (* <%= context.name %> *)
|
||||
property myUsername : "<%= current_user.login %>"
|
||||
property myToken : "<%= current_user.token %>"
|
||||
property myContextID : <%= context.id %> (* <%= context.name %> *)
|
||||
|
||||
-- this string is used when the message subject is empty
|
||||
property emptySubject : "No Subject Specified"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,18 @@
|
|||
<p>Do you have one of your own to add? <a href="http://www.rousette.org.uk/projects/forums/viewforum/10/" title="Tracks | Tips and Tricks">Tell us about it in our Tips and Tricks forum
|
||||
</a> and we may include it on this page in a future versions of Tracks.</p>
|
||||
|
||||
<a name="message_gateway"> </a>
|
||||
<h2>Integrated email/SMS receiver</h2>
|
||||
<p>
|
||||
If Tracks is running on the same server as your mail server, you can use the integrated mail handler built into tracks. Steps to set it up:
|
||||
<ul>
|
||||
<li>Go to <%= link_to "Preferences", preferences_url %> and set your "From email" and "default email context" for todos sent in via email (which could come from an SMS message)</li>
|
||||
<li>In sendmail/qmail/postfix/whatever, set up an email address alias to pipe messages to <pre style="font-size:1.5em">/PATH/TO/RUBY/ruby /PATH/TO/TRACKS/script/runner -e production 'MessageGateway.receive(STDIN.read)'</pre></li>
|
||||
<li>Send an email to your newly configured address!</li>
|
||||
</ul>
|
||||
You can also use the Rich Todo API to send in tasks like "do laundry @ Home" or "Call Bill > project X". The subject of the message will fill description, context, and project, while the body will populate the tasks's note.
|
||||
</p>
|
||||
|
||||
<a name="applescript1-section"> </a>
|
||||
<h2>Add an Action with Applescript</h2>
|
||||
<p>This is a simple script that pops up a dialog box asking for a description, and then sends that to Tracks with a hard-coded context.</p>
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@
|
|||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd -H "Content-Type: text/xml" \
|
||||
-d "project[name]=Build a treehouse for the kids" \
|
||||
-d "<project><name>Build a treehouse for the kids</name></project>" \
|
||||
<%= home_url %>projects.xml -i
|
||||
>> HTTP/1.1 201 Created
|
||||
Location: <%= home_url %>projects/65.xml
|
||||
|
|
@ -86,7 +86,7 @@ Location: <%= home_url %>projects/65.xml
|
|||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd -H "Content-Type: text/xml" \
|
||||
-d "todo[description]=Model treehouse in SketchUp&todo[context_id]=2&todo[project_id]=65" \
|
||||
-d "<todo><description>Model treehouse in SketchUp</description><context_id>2</context_id><project_id>65<project_id>" \
|
||||
<%= home_url %>todos.xml -i
|
||||
>> HTTP/1.1 201 Created
|
||||
Location: <%= home_url %>todos/452.xml
|
||||
|
|
@ -99,7 +99,7 @@ Location: <%= home_url %>todos/452.xml
|
|||
<pre>
|
||||
<code>
|
||||
$ curl -u username:p4ssw0rd -H "Content-Type: text/xml" -X PUT \
|
||||
-d "todo[notes]=use maple texture" \
|
||||
-d "<todo><notes>use maple texture</notes></todos>" \
|
||||
<%= home_url %>todos/452.xml -i
|
||||
>> HTTP/1.1 200 OK
|
||||
...
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@
|
|||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
Nifty("div#todo_new_action_container","normal");
|
||||
Nifty("div#project_new_project_container","normal");
|
||||
Nifty("div#context_new_container","normal");
|
||||
Nifty("div#recurring_new_container","normal");
|
||||
if ($('flash').visible()) { new Effect.Fade("flash",{duration:5.0}); }
|
||||
}
|
||||
</script>
|
||||
|
|
@ -49,7 +46,7 @@ window.onload=function(){
|
|||
<li><%= navigation_link("Home", home_path, {:accesskey => "t", :title => "Home"} ) %></li>
|
||||
<li><%= navigation_link( "Contexts", contexts_path, {:accesskey=>"c", :title=>"Contexts"} ) %></li>
|
||||
<li><%= navigation_link( "Projects", projects_path, {:accesskey=>"p", :title=>"Projects"} ) %></li>
|
||||
<li><%= navigation_link( "Tickler", tickler_path, :title => "Tickler" ) %></li>
|
||||
<li><%= navigation_link( "Tickler", tickler_path, {:accesskey =>"k", :title => "Tickler"} ) %></li>
|
||||
<li><%= navigation_link( "Done", done_path, {:accesskey=>"d", :title=>"Completed"} ) %></li>
|
||||
<li><%= navigation_link( "Notes", notes_path, {:accesskey => "o", :title => "Show all notes"} ) %></li>
|
||||
<li><%= navigation_link( "Preferences", preferences_path, {:accesskey => "u", :title => "Show my preferences"} ) %></li>
|
||||
|
|
@ -57,6 +54,7 @@ window.onload=function(){
|
|||
<% if current_user.is_admin? -%>
|
||||
<li><%= navigation_link("Admin", users_path, {:accesskey => "a", :title => "Add or delete users"} ) %></li>
|
||||
<% end -%>
|
||||
<li><%= navigation_link(image_tag("x-office-calendar.png", :size => "16X16", :border => 0), calendar_path, :title => "Calendar of due actions" ) %></li>
|
||||
<li><%= navigation_link(image_tag("recurring_menu16x16.png", :size => "16X16", :border => 0), {:controller => "recurring_todos", :action => "index"}, :title => "Manage recurring actions" ) %></li>
|
||||
<li><%= navigation_link(image_tag("feed-icon.png", :size => "16X16", :border => 0), {:controller => "feedlist", :action => "index"}, :title => "See a list of available feeds" ) %></li>
|
||||
<li><%= navigation_link(image_tag("menustar.gif", :size => "16X16", :border => 0), tag_path("starred"), :title => "See your starred actions" ) %></li>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<div id="<%= dom_id(note, 'container') %>">
|
||||
<h2><%= link_to("Note #{note.id}", note_path(note), :title => "Show note #{note.id}" ) %></h2>
|
||||
<div id="<%= dom_id(note) %>">
|
||||
<%= sanitize(textilize(note.body.gsub(/((https?:\/\/[^ \n\t]*))/, '"\1":\2'))) %>
|
||||
<%= sanitize(markdown(auto_link(note.body))) %>
|
||||
|
||||
<div class="note_footer">
|
||||
<%= link_to_remote(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
<li><strong>refresh:</strong> automatic refresh interval for each of the pages (in minutes)</li>
|
||||
<li><strong>verbose action descriptor:</strong> when true, show project/context name in action listing; when false show [P]/[C] with tool tips</li>
|
||||
<li><strong>mobile todos per page:</strong> the maximum number of actions to show on a single page in the mobile view</li>
|
||||
<li><strong>From email:</string> the email address you use for sending todos as email or SMS messages to your Tracks account</li>
|
||||
<li><string>Default email context:</string> the context to which tasks sent in via email or SMS should be added</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
@ -67,6 +69,8 @@
|
|||
<%= row_with_text_field('refresh') %>
|
||||
<%= row_with_select_field("verbose_action_descriptors") %>
|
||||
<%= row_with_text_field("mobile_todos_per_page") %>
|
||||
<%= row_with_text_field("sms_email") %>
|
||||
<%= table_row("sms_context", false) { select('prefs', 'sms_context_id', current_user.contexts.map{|c| [c.name, c.id]}) } %>
|
||||
|
||||
<tr><td><%= submit_tag "Update" %></td>
|
||||
<td><%= link_to "Cancel", :action => 'index' %></td>
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
<li>Refresh interval (in minutes): <span class="highlight"><%= prefs.refresh %></span></li>
|
||||
<li>Verbose action descriptors: <span class="highlight"><%= prefs.verbose_action_descriptors %></span></li>
|
||||
<li>Actions per page (Mobile View): <span class="highlight"><%= prefs.mobile_todos_per_page %></span></li>
|
||||
<li>From email: <span class="highlight"><%= prefs.sms_email %></span></li>
|
||||
<li>Default email context: <span class="highlight"><%= prefs.sms_context.nil? ? "None" : prefs.sms_context.name %></span></li>
|
||||
</ul>
|
||||
<div class="actions">
|
||||
<%= link_to "Edit preferences »", { :controller => 'preferences', :action => 'edit'}, :class => 'edit_link' %>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<% @not_done = project.not_done_todos -%>
|
||||
<% #@not_done = project.not_done_todos -%>
|
||||
|
||||
<div id="p<%= project.id %>" class="container project">
|
||||
<h2>
|
||||
|
|
@ -6,7 +6,9 @@
|
|||
<a href="#" class="container_toggle" id="toggle_p<%= project.id %>"><%= image_tag("collapse.png") %></a>
|
||||
<% end %>
|
||||
<span class="in_place_editor_field" id="project_name_in_place_editor"><%= project.name %></span>
|
||||
<%= in_place_editor 'project_name_in_place_editor', { :url => { :controller => 'projects', :action => 'update', :id => project.id, :field => 'name', :wants_render => false, :escape => false} , :options=>"{method:'put'}" } %>
|
||||
<%= in_place_editor 'project_name_in_place_editor', {
|
||||
:url => { :controller => 'projects', :action => 'update', :id => project.id, :field => 'name', :update_project_name => true, :escape => false} ,
|
||||
:options=>"{method:'put'}", :script => true} %>
|
||||
</h2>
|
||||
<% unless project.description.blank? -%>
|
||||
<div class="project_description"><%= sanitize(project.description) %></div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<div class="project-state-group" id="list-<%= state %>-projects-container" <%= " style=\"display:none\"" if project_state_group.empty? %>>
|
||||
<h2><span id="<%= state %>-projects-count" class="badge"><%= project_state_group.length %></span><%= state.titlecase %> Projects</h2>
|
||||
<div class="menu_sort"><span class="sort_separator">Sort </span>
|
||||
<div class="alpha_sort">
|
||||
<%= link_to("Sort Alphabetically", alphabetize_projects_path(:state => state),
|
||||
<%= link_to("Alphabetically", alphabetize_projects_path(:state => state),
|
||||
:class => "alphabetize_link", :title => "Sort these projects alphabetically") %>
|
||||
<% apply_behavior '.alphabetize_link:click', :prevent_default => true do |page, element|
|
||||
page.confirming 'Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order.' do
|
||||
|
|
@ -10,10 +11,21 @@
|
|||
page << remote_to_href(:complete => "alphaSort.stopWaiting()")
|
||||
end
|
||||
end
|
||||
%></div><span class="sort_separator"> | </span><div class="tasks_sort">
|
||||
<%= link_to("By number of tasks", actionize_projects_path(:state => state),
|
||||
:class => "actionize_link", :title => "Sort these projects by number of tasks") %>
|
||||
<% apply_behavior '.actionize_link:click', :prevent_default => true do |page, element|
|
||||
page.confirming 'Are you sure that you want to sort these projects by the number of tasks? This will replace the existing sort order.' do
|
||||
page << "tasksSort = this.up('.tasks_sort');
|
||||
tasksSort.startWaiting();"
|
||||
page << remote_to_href(:complete => "tasksSort.stopWaiting()")
|
||||
end
|
||||
end
|
||||
%></div>
|
||||
</div>
|
||||
|
||||
<div id="list-<%= state %>-projects" class="project-list">
|
||||
<%= render :partial => 'project_listing', :collection => project_state_group %>
|
||||
</div>
|
||||
<%= sortable_element "list-#{state}-projects", get_listing_sortable_options("list-#{state}-projects") %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
6
app/views/projects/actionize.js.rjs
Normal file
6
app/views/projects/actionize.js.rjs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
list_id = "list-#{@state}-projects"
|
||||
page.replace_html list_id,
|
||||
:partial => 'project_listing',
|
||||
:collection => @projects
|
||||
page.sortable list_id, get_listing_sortable_options(list_id)
|
||||
|
||||
|
|
@ -61,4 +61,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
Nifty("div#project_new_project_container","normal");
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
10
app/views/projects/update_project_name.js.rjs
Normal file
10
app/views/projects/update_project_name.js.rjs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
page['project_name_in_place_editor'].replace_html @project.name
|
||||
|
||||
page['default_project_name_id'].value = @project.name
|
||||
page['todo_project_name'].value = @project.name
|
||||
|
||||
# renew project auto complete array
|
||||
page << "projectAutoCompleter.options.array = #{project_names_for_autocomplete}; projectAutoCompleter.changed = true"
|
||||
|
||||
status_message = "Name of project was changed"
|
||||
page.notify :notice, status_message, 5.0
|
||||
|
|
@ -6,7 +6,16 @@
|
|||
<div class="description">
|
||||
<span class="todo.descr"><%= sanitize(recurring_todo.description) %></span> <%= recurring_todo_tag_list %>
|
||||
<span class='recurrence_pattern'>
|
||||
[<%=recurrence_target(recurring_todo)%> <%= recurring_todo.recurrence_pattern %> <%= recurrence_time_span(recurring_todo) %>]
|
||||
<%
|
||||
rt = recurrence_target(recurring_todo)
|
||||
rp = recurring_todo.recurrence_pattern
|
||||
# only add space if recurrence_pattern has content
|
||||
rp = " " + rp if !rp.nil?
|
||||
rts = recurrence_time_span(recurring_todo)
|
||||
# only add space if recurrence_time_span has content
|
||||
rts = " " + rts if !(rts == "")
|
||||
%>
|
||||
[<%=rt%><%=rp%><%=rts%>]
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -101,22 +101,22 @@
|
|||
<div id="recurring_monthly" style="display:none">
|
||||
<label>Settings for monthly recurring actions</label><br/>
|
||||
<%= radio_button_tag('recurring_todo[monthly_selector]', 'monthly_every_x_day', true)%> Day <%=
|
||||
text_field_tag('recurring_todo[monthly_every_x_day]', Time.now.mday, {"size" => 3, "tabindex" => 9}) %> on every <%=
|
||||
text_field_tag('recurring_todo[monthly_every_x_day]', Time.zone.now.mday, {"size" => 3, "tabindex" => 9}) %> on every <%=
|
||||
text_field_tag('recurring_todo[monthly_every_x_month]', 1, {"size" => 3, "tabindex" => 10}) %> month<br/>
|
||||
<%= radio_button_tag('recurring_todo[monthly_selector]', 'monthly_every_xth_day')%> The <%=
|
||||
select_tag('recurring_todo[monthly_every_xth_day]', options_for_select(@xth_day), {}) %> <%=
|
||||
select_tag('recurring_todo[monthly_day_of_week]' , options_for_select(@days_of_week, Time.now.wday), {}) %> of every <%=
|
||||
select_tag('recurring_todo[monthly_day_of_week]' , options_for_select(@days_of_week, Time.zone.now.wday), {}) %> of every <%=
|
||||
text_field_tag('recurring_todo[monthly_every_x_month2]', 1, {"size" => 3, "tabindex" => 11}) %> month<br/>
|
||||
</div>
|
||||
<div id="recurring_yearly" style="display:none">
|
||||
<label>Settings for yearly recurring actions</label><br/>
|
||||
<%= radio_button_tag('recurring_todo[yearly_selector]', 'yearly_every_x_day', true)%> Every <%=
|
||||
select_tag('recurring_todo[yearly_month_of_year]', options_for_select(@months_of_year, Time.now.month), {}) %> <%=
|
||||
text_field_tag('recurring_todo[yearly_every_x_day]', Time.now.day, "size" => 3, "tabindex" => 9) %><br/>
|
||||
select_tag('recurring_todo[yearly_month_of_year]', options_for_select(@months_of_year, Time.zone.now.month), {}) %> <%=
|
||||
text_field_tag('recurring_todo[yearly_every_x_day]', Time.zone.now.day, "size" => 3, "tabindex" => 9) %><br/>
|
||||
<%= radio_button_tag('recurring_todo[yearly_selector]', 'yearly_every_xth_day')%> The <%=
|
||||
select_tag('recurring_todo[yearly_every_xth_day]', options_for_select(@xth_day), {}) %> <%=
|
||||
select_tag('recurring_todo[yearly_day_of_week]', options_for_select(@days_of_week, Time.now.wday), {}) %> of <%=
|
||||
select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, Time.now.month), {}) %><br/>
|
||||
select_tag('recurring_todo[yearly_day_of_week]', options_for_select(@days_of_week, Time.zone.now.wday), {}) %> of <%=
|
||||
select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, Time.zone.now.month), {}) %><br/>
|
||||
</div>
|
||||
<div id="recurring_target">
|
||||
<label>Set recurrence on</label><br/>
|
||||
|
|
|
|||
|
|
@ -40,3 +40,9 @@
|
|||
apply_behaviour "#recurring_edit_period:click",
|
||||
"TracksForm.hide_all_edit_recurring(); $('recurring_edit_'+TracksForm.get_edit_period()).show();"
|
||||
-%>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.onload=function(){
|
||||
Nifty("div#recurring_new_container","normal");
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<div id="todo_new_action_container">
|
||||
|
||||
<div id="toggle_action_new" class="hide_form">
|
||||
<a title="Hide new action form" accesskey="n">« Hide form</a>
|
||||
<a title="Hide new action form" accesskey="n" href="#">« Hide form</a>
|
||||
<% apply_behavior '#toggle_action_new a:click', :prevent_default => true do |page|
|
||||
page << "TracksForm.toggle('toggle_action_new', 'todo_new_action', 'todo-form-new-action',
|
||||
'« Hide form', 'Hide next action form',
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
<label for="todo_notes">Notes</label>
|
||||
<%= text_area( "todo", "notes", "cols" => 29, "rows" => 6, "tabindex" => 2) %>
|
||||
|
||||
<input id="default_project_name_id" name="default_project_name" type="hidden" value="<%=@initial_project_name-%>" />
|
||||
<label for="todo_project_name">Project</label>
|
||||
<input id="todo_project_name" name="project_name" autocomplete="off" tabindex="3" size="30" type="text" value="<%= @initial_project_name %>" />
|
||||
<div class="page_name_auto_complete" id="project_list" style="display:none"></div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<div id="error_status"><%= error_messages_for("todo", :object_name => 'action') %></div>
|
||||
|
||||
<%= hidden_field( "todo", "id" ) %>
|
||||
<%= source_view_tag( @source_view ) %>
|
||||
<%= hidden_field( "todo", "id" ) -%>
|
||||
<%= source_view_tag( @source_view ) -%>
|
||||
<%= "<INPUT TYPE=\"hidden\" name=\"_tag_name\" value=\""+ @tag_name+"\">" unless @tag_name.nil? -%>
|
||||
|
||||
<label for="<%= dom_id(@todo, 'description') %>">Description</label>
|
||||
<%= text_field( "todo", "description", "size" => 30, "tabindex" => 8) %>
|
||||
|
|
@ -48,16 +49,16 @@ Event.observe($('<%= dom_id(@todo, 'context_name') %>'), "click", <%= dom_id(@to
|
|||
<div class="due_input">
|
||||
<label for="<%= dom_id(@todo, 'due_label') %>">Due</label>
|
||||
<%= date_field_tag("todo[due]", dom_id(@todo, 'due'), format_date(@todo.due), "tabindex" => 13) %>
|
||||
<a href="#" id="<%= dom_id(@todo, 'due_x') %>" class="date_clear">
|
||||
<%= image_tag("cancel.png", :alt => "") %>
|
||||
<a href="#" id="<%= dom_id(@todo, 'due_x') %>" class="date_clear" title="Clear due date">
|
||||
<%= image_tag("delete_off.png", :alt => "Clear due date") %>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="show_from_input">
|
||||
<label for="<%= dom_id(@todo, 'show_from') %>">Show from</label>
|
||||
<%= date_field_tag("todo[show_from]", dom_id(@todo, 'show_from'), format_date(@todo.show_from), "tabindex" => 14) %>
|
||||
<a href="#" id="<%= dom_id(@todo, 'show_from_x') %>" class="date_clear">
|
||||
<%= image_tag("cancel.png", :alt => "") %>
|
||||
<a href="#" id="<%= dom_id(@todo, 'show_from_x') %>" class="date_clear" title="Clear show from date">
|
||||
<%= image_tag("delete_off.png", :alt => "Clear show from date") %>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ end %>
|
|||
<h2><label for="tag_list">Tags (separate with commas)</label></h2>
|
||||
<%= text_field_tag "tag_list", @tag_list_text, :size => 30, :tabindex => 6 %>
|
||||
<h2><label for="todo_due">Due</label></h2>
|
||||
<%= date_select("todo", "due", :order => [:day, :month, :year],
|
||||
:start_year => this_year, :include_blank => true) %>
|
||||
<%= date_select("todo", "due", {:order => [:day, :month, :year],
|
||||
:start_year => this_year, :include_blank => true}, :tabindex => 7) %>
|
||||
<h2><label for="todo_show_from">Show from</label></h2>
|
||||
<%= date_select("todo", "show_from", :order => [:day, :month, :year],
|
||||
:start_year => this_year, :include_blank => true) %>
|
||||
<%= date_select("todo", "show_from", {:order => [:day, :month, :year],
|
||||
:start_year => this_year, :include_blank => true}, :tabindex => 8) %>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<%= remote_star_icon %>
|
||||
<%= remote_toggle_checkbox unless source_view_is :deferred %>
|
||||
<div class="description<%= staleness_class( todo ) %>">
|
||||
<% unless @todo.completed? %><span class="defer-container"><%= defer_link(1) %> <%= defer_link(7) %></span><% end %>
|
||||
<%= date_span -%>
|
||||
<span class="todo.descr"><%= h sanitize(todo.description) %></span>
|
||||
<%= link_to(image_tag("recurring16x16.png"), {:controller => "recurring_todos", :action => "index"}, :class => "recurring_icon") if @todo.from_recurring_todo? %>
|
||||
|
|
|
|||
|
|
@ -3,5 +3,5 @@
|
|||
element.next('.todo_notes').toggle
|
||||
end -%>
|
||||
<div class="todo_notes" id="<%= dom_id(item, 'notes') %>" style="display:none">
|
||||
<%= markdown( item.notes.gsub(/((https?:\/\/[^ \n\t]*))/, '"\1":\2') ) %>
|
||||
<%= sanitize(markdown( auto_link(item.notes)) ) %>
|
||||
</div>
|
||||
68
app/views/todos/calendar.html.erb
Normal file
68
app/views/todos/calendar.html.erb
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<div id="display_box">
|
||||
|
||||
<div class="container">
|
||||
<h2>Due today</h2>
|
||||
<div id="empty_due_today" <%= "style=\"display:none\"" unless @due_today.empty? %>>
|
||||
No actions due today
|
||||
</div>
|
||||
<div id="due_today">
|
||||
<%= render :partial => "todos/todo", :collection => @due_today %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Due in rest of this week</h2>
|
||||
<div id="empty_due_this_week" <%= "style=\"display:none\"" unless @due_this_week.empty? %>>
|
||||
No actions due in rest of this week
|
||||
</div>
|
||||
<div id="due_this_week">
|
||||
<%= render :partial => "todos/todo", :collection => @due_this_week %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Due next week</h2>
|
||||
<div id="empty_due_next_week" <%= "style=\"display:none\"" unless @due_next_week.empty? %>>
|
||||
No actions due in next week
|
||||
</div>
|
||||
<div id="due_next_week">
|
||||
<%= render :partial => "todos/todo", :collection => @due_next_week %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Due in rest of <%= Time.zone.now.strftime("%B") %> </h2>
|
||||
<div id="empty_due_this_month" <%= "style=\"display:none\"" unless @due_this_month.empty? %>>
|
||||
No actions due in rest of this month
|
||||
</div>
|
||||
<div id="due_this_month">
|
||||
<%= render :partial => "todos/todo", :collection => @due_this_month %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<h2>Due in <%= (Time.zone.now+1.month).strftime("%B") %> and later</h2>
|
||||
<div id="empty_due_after_this_month" <%= "style=\"display:none\"" unless @due_after_this_month.empty? %>>
|
||||
No actions due after this month
|
||||
</div>
|
||||
<div id="due_after_this_month">
|
||||
<%= render :partial => "todos/todo", :collection => @due_after_this_month %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- End of display_box -->
|
||||
<div class="input_box" id="input_box">
|
||||
<!--
|
||||
<input class="hide_tickler" id="hide_tickler" type="checkbox" tabindex="5" name="hide_tickler" checked="true"/>
|
||||
<label for="hide_tickler"> Show actions in tickler</label>
|
||||
<br/><br/>
|
||||
-->
|
||||
<p><%= link_to('<span class="feed">iCal</span>', {:format => 'ics', :token => current_user.token}, :title => "iCal feed" ) %>
|
||||
- Get this calendar in iCal format</p>
|
||||
</div>
|
||||
|
||||
<%
|
||||
apply_behavior 'input.hide_tickler:click', :prevent_default => true do |page|
|
||||
page << "alert('hiding action in tickler from calendar is not yet implemented');"
|
||||
end
|
||||
%>
|
||||
31
app/views/todos/calendar.ics.erb
Normal file
31
app/views/todos/calendar.ics.erb
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
BEGIN:VCALENDAR
|
||||
PRODID:-//TRACKS//<%= TRACKS_VERSION %>//EN
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:PUBLISH
|
||||
X-WR-CALNAME:Tracks
|
||||
<% for todo in @due_all
|
||||
due_date = todo.due
|
||||
overdue_text = ""
|
||||
if due_date.at_midnight < Time.zone.now.at_midnight
|
||||
due_date = Time.zone.now
|
||||
overdue_text = "Overdue: "
|
||||
end
|
||||
%>BEGIN:VEVENT
|
||||
DTSTART;VALUE=DATE:<%= due_date.strftime("%Y%m%d") %>
|
||||
DTEND;VALUE=DATE:<%= (due_date+1.day).strftime("%Y%m%d") %>
|
||||
DTSTAMP:<%= due_date.strftime("%Y%m%dT%H%M%SZ") %>
|
||||
UID:<%= todo_url(todo) %>
|
||||
CLASS:PUBLIC
|
||||
CATEGORIES:Tracks
|
||||
CREATED:<%= todo.created_at.strftime("%Y%m%dT%H%M%SZ") %>
|
||||
DESCRIPTION:<%= format_ical_notes(todo.notes) %>
|
||||
LAST-MODIFIED:<%= todo.updated_at.strftime("%Y%m%dT%H%M%SZ") %>
|
||||
LOCATION:
|
||||
SEQUENCE:0
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:<%= overdue_text + todo.description %>
|
||||
TRANSP:TRANSPARENT
|
||||
END:VEVENT
|
||||
<% end
|
||||
%>END:VCALENDAR
|
||||
|
|
@ -8,6 +8,7 @@ if @saved
|
|||
page['badge_count'].replace_html @down_count
|
||||
page.send :record, "Form.reset('todo-form-new-action');Form.focusFirstElement('todo-form-new-action')"
|
||||
page['todo_context_name'].value = @initial_context_name
|
||||
page['todo_project_name'].value = @initial_project_name
|
||||
page << "updateContextNamesForAutoComplete(#{context_names_for_autocomplete})" if @new_context_created
|
||||
page << "projectAutoCompleter.options.array = #{project_names_for_autocomplete}" if @new_project_created
|
||||
if should_show_new_item()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
if @saved
|
||||
page[@todo].remove
|
||||
page.show "empty_"+@original_item_due_id if @old_due_empty
|
||||
page['badge_count'].replace_html @down_count
|
||||
|
||||
# remove context if empty
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<% form_tag formatted_todos_path(:m), :method => :post do %>
|
||||
<%= render :partial => 'edit_mobile' %>
|
||||
<p><input type="submit" value="Create" tabindex="6" /></p>
|
||||
<p><input type="submit" value="Create" tabindex="12" accesskey="#" /></p>
|
||||
<% end -%>
|
||||
<%= link_to "Back", @return_path %>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<% form_tag formatted_todo_path(@todo, :m), :method => :put do %>
|
||||
<%= render :partial => 'edit_mobile', :locals => { :parent_container_type => "show_mobile" } %>
|
||||
<p><input type="submit" value="Update" tabindex="6" /></p>
|
||||
<p><input type="submit" value="Update" tabindex="6" accesskey="#" /></p>
|
||||
<% end -%>
|
||||
<%= link_to "Cancel", @return_path %>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
if @saved
|
||||
page[@todo].remove
|
||||
page.show "empty_"+@original_item_due_id if @old_due_empty
|
||||
if @todo.completed?
|
||||
|
||||
# completed todos move from their context to the completed container
|
||||
|
|
@ -23,10 +24,12 @@ if @saved
|
|||
page.insert_html :bottom, item_container_id(@new_recurring_todo), :partial => 'todos/todo', :locals => { :todo => @new_recurring_todo, :parent_container_type => parent_container_type }
|
||||
page.visual_effect :highlight, dom_id(@new_recurring_todo, 'line'), {'startcolor' => "'#99ff99'"}
|
||||
else
|
||||
page.notify :notice, "There is no next action after the recurring action you just finished. The recurrence is completed", 6.0 if @new_recurring_todo.nil?
|
||||
if @todo.recurring_todo.todos.active.count == 0
|
||||
page.notify :notice, "There is no next action after the recurring action you just finished. The recurrence is completed", 6.0 if @new_recurring_todo.nil?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
# todo is activated from completed container
|
||||
page.call "todoItems.ensureVisibleWithEffectAppear", item_container_id(@todo)
|
||||
|
|
|
|||
|
|
@ -6,19 +6,28 @@ if @saved
|
|||
status_message = 'Added new context / ' + status_message if @new_context_created
|
||||
page.notify :notice, status_message, 5.0
|
||||
|
||||
# #update auto completer arrays for context and project
|
||||
# update auto completer arrays for context and project
|
||||
page << "contextAutoCompleter.options.array = #{context_names_for_autocomplete}; contextAutoCompleter.changed = true" if @new_context_created
|
||||
page << "projectAutoCompleter.options.array = #{project_names_for_autocomplete}; projectAutoCompleter.changed = true" if @new_project_created
|
||||
|
||||
if source_view_is_one_of(:todo, :context, :tag)
|
||||
if @context_changed || @todo.deferred?
|
||||
page[@todo].remove
|
||||
|
||||
if (@remaining_in_context == 0)
|
||||
# remove context container from page if empty
|
||||
source_view do |from|
|
||||
from.todo { page.visual_effect :fade, "c#{@original_item_context_id}", :duration => 0.4 }
|
||||
from.tag { page.visual_effect :fade, "c#{@original_item_context_id}", :duration => 0.4 }
|
||||
from.context { page.show "c#{@original_item_context_id}empty-nd" }
|
||||
if @context_changed
|
||||
source_view do |from|
|
||||
from.todo { page.visual_effect :fade, "c#{@original_item_context_id}", :duration => 0.4 }
|
||||
from.tag { page.visual_effect :fade, "c#{@original_item_context_id}", :duration => 0.4 }
|
||||
from.context { page.show "c#{@original_item_context_id}empty-nd" }
|
||||
end
|
||||
else
|
||||
source_view do |from|
|
||||
from.todo { page.visual_effect :fade, item_container_id(@todo), :duration => 0.4 }
|
||||
from.tag { page.visual_effect :fade, item_container_id(@todo), :duration => 0.4 }
|
||||
from.context { page.show "c#{@original_item_context_id}empty-nd" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -92,6 +101,23 @@ if @saved
|
|||
elsif source_view_is :stats
|
||||
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :parent_container_type => parent_container_type }
|
||||
page.visual_effect :highlight, dom_id(@todo), :duration => 3
|
||||
elsif source_view_is :calendar
|
||||
if @due_date_changed
|
||||
page[@todo].remove
|
||||
page.show "empty_"+@original_item_due_id if @old_due_empty
|
||||
page.hide "empty_"+@new_due_id
|
||||
page.insert_html :bottom, @new_due_id, :partial => 'todos/todo'
|
||||
page.visual_effect :highlight, dom_id(@todo), :duration => 3
|
||||
else
|
||||
if @todo.due.nil?
|
||||
# due date removed
|
||||
page[@todo].remove
|
||||
page.show "empty_"+@original_item_due_id if @old_due_empty
|
||||
else
|
||||
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :parent_container_type => parent_container_type }
|
||||
page.visual_effect :highlight, dom_id(@todo), :duration => 3
|
||||
end
|
||||
end
|
||||
else
|
||||
logger.error "unexpected source_view '#{params[:_source_view]}'"
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue