home page is restored, so is context view
BIN
app/assets/images/accept.png
Executable file
|
After Width: | Height: | Size: 781 B |
BIN
app/assets/images/add.png
Normal file
|
After Width: | Height: | Size: 596 B |
BIN
app/assets/images/arrows-ffffff.png
Normal file
|
After Width: | Height: | Size: 244 B |
BIN
app/assets/images/bigBlackWaiting.gif
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
app/assets/images/bigWaiting.gif
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
app/assets/images/blackWaiting.gif
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/assets/images/blank.png
Normal file
|
After Width: | Height: | Size: 156 B |
BIN
app/assets/images/bottom_off.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/bottom_on.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/cancel.png
Executable file
|
After Width: | Height: | Size: 587 B |
BIN
app/assets/images/close.gif
Normal file
|
After Width: | Height: | Size: 109 B |
BIN
app/assets/images/collapse.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/assets/images/construction.gif
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/assets/images/container-gradient.png
Normal file
|
After Width: | Height: | Size: 138 B |
BIN
app/assets/images/defer_1.png
Normal file
|
After Width: | Height: | Size: 3 KiB |
BIN
app/assets/images/defer_1_off.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/assets/images/defer_2.png
Normal file
|
After Width: | Height: | Size: 496 B |
BIN
app/assets/images/defer_2_off.png
Normal file
|
After Width: | Height: | Size: 425 B |
BIN
app/assets/images/defer_3.png
Normal file
|
After Width: | Height: | Size: 501 B |
BIN
app/assets/images/defer_3_off.png
Normal file
|
After Width: | Height: | Size: 441 B |
BIN
app/assets/images/defer_7.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
app/assets/images/defer_7_off.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
app/assets/images/delete_off.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/delete_on.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/done.png
Normal file
|
After Width: | Height: | Size: 905 B |
BIN
app/assets/images/down_off.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/down_on.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/downarrow.png
Normal file
|
After Width: | Height: | Size: 216 B |
BIN
app/assets/images/edit_off.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/assets/images/edit_on.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/assets/images/expand.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
app/assets/images/feed-icon.png
Executable file
|
After Width: | Height: | Size: 764 B |
BIN
app/assets/images/grip.png
Normal file
|
After Width: | Height: | Size: 192 B |
BIN
app/assets/images/icon_delete.png
Normal file
|
After Width: | Height: | Size: 618 B |
BIN
app/assets/images/menuarrow.gif
Normal file
|
After Width: | Height: | Size: 69 B |
BIN
app/assets/images/menustar.gif
Normal file
|
After Width: | Height: | Size: 337 B |
BIN
app/assets/images/menustar_small.gif
Normal file
|
After Width: | Height: | Size: 271 B |
BIN
app/assets/images/mobile_notes.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
app/assets/images/new-action-gradient.png
Normal file
|
After Width: | Height: | Size: 161 B |
BIN
app/assets/images/notes_off.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/assets/images/notes_on.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/assets/images/open-id-login-bg.gif
Normal file
|
After Width: | Height: | Size: 237 B |
BIN
app/assets/images/recurring16x16.png
Normal file
|
After Width: | Height: | Size: 410 B |
BIN
app/assets/images/recurring24x24.png
Normal file
|
After Width: | Height: | Size: 598 B |
BIN
app/assets/images/recurring_menu16x16.png
Normal file
|
After Width: | Height: | Size: 475 B |
BIN
app/assets/images/recurring_menu24x24.png
Normal file
|
After Width: | Height: | Size: 814 B |
BIN
app/assets/images/reviewed.png
Executable file
|
After Width: | Height: | Size: 642 B |
BIN
app/assets/images/shadow.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/assets/images/spinner.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/assets/images/staricons.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
app/assets/images/stats.gif
Executable file
|
After Width: | Height: | Size: 84 B |
BIN
app/assets/images/successor_off.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/assets/images/successor_on.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
app/assets/images/system-search.png
Normal file
|
After Width: | Height: | Size: 935 B |
BIN
app/assets/images/to_project_off.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
BIN
app/assets/images/top_off.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
app/assets/images/top_on.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/trans70.png
Normal file
|
After Width: | Height: | Size: 328 B |
BIN
app/assets/images/ui-anim_basic_16x16.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/assets/images/up_off.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/up_on.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
app/assets/images/waiting.gif
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
app/assets/images/x-office-calendar.png
Normal file
|
After Width: | Height: | Size: 515 B |
|
|
@ -12,4 +12,6 @@
|
|||
//
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require ../../../vendor/assets/javascripts/jquery-ui-1.8.17.custom.min
|
||||
//= require_tree ../../../vendor/assets/javascripts
|
||||
//= require_tree .
|
||||
|
|
|
|||
1351
app/assets/javascripts/tracks.js
Normal file
|
|
@ -9,5 +9,7 @@
|
|||
* compiled file, but it's generally better to create a new file per style scope.
|
||||
*
|
||||
*= require_self
|
||||
*= require_tree .
|
||||
* require_tree .
|
||||
*= require tracks
|
||||
*= require_tree ../../../vendor/assets/stylesheets
|
||||
*/
|
||||
|
|
|
|||
278
app/assets/stylesheets/mobile.css
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
body {
|
||||
font-family: Arial,Helvetica,sans-serif;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
font-size: small;
|
||||
color: #999999;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a, a:link, a:active, a:visited {
|
||||
color: #CC3334;
|
||||
padding: 0.25em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
background-color: #CC3334;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
text-decoration: underline;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #fff;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
padding-left:8px;
|
||||
margin-top:0;
|
||||
margin-bottom:0;
|
||||
font-size:medium;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: #aaaaaa;
|
||||
margin: .3em 0;
|
||||
padding: .3em 0 .1em .3em;
|
||||
border-top: 1px solid #777777;
|
||||
font-size:medium;
|
||||
}
|
||||
|
||||
h2 a, h2 a:link, h2 a:active, h2 a:visited {
|
||||
color: #666666;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h2 a:hover {
|
||||
background-color: transparent;
|
||||
color: #CC3334;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
h4.alert {
|
||||
border: 1px solid #666666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h4.warning {
|
||||
border: 1px solid #ED2E38;
|
||||
background-color: #F6979C;
|
||||
color: #000;
|
||||
}
|
||||
h4.error {
|
||||
color:#fff;
|
||||
background:#c00;
|
||||
}
|
||||
h4.notice {
|
||||
border: 1px solid #007E00;
|
||||
background-color: #c2ffc2;
|
||||
color: #007E00;
|
||||
}
|
||||
|
||||
span.tag {
|
||||
font-size: small;
|
||||
background-color: #CCE7FF;
|
||||
color: #000;
|
||||
padding: 1px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
span.r {
|
||||
font-size: small;
|
||||
color: #777777;
|
||||
}
|
||||
|
||||
span.prj, span.ctx{
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
#ctx, #pjr {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
#ctx a, #pjr a {
|
||||
padding: 0.1em 0;
|
||||
}
|
||||
|
||||
/* Draw attention to some text
|
||||
Same format as traffic lights */
|
||||
.red {
|
||||
color: #fff;
|
||||
background: #f00;
|
||||
padding: 1px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.amber {
|
||||
color: #fff;
|
||||
background: #ff6600;
|
||||
padding: 1px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.orange {
|
||||
color: #fff;
|
||||
background: #FFA500;
|
||||
padding: 1px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.green {
|
||||
color: #fff;
|
||||
background: #33cc00;
|
||||
padding: 1px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.grey {
|
||||
color: #fff;
|
||||
background: #999;
|
||||
padding: 1px;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.count {
|
||||
color: #fff;
|
||||
background: #f00;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
.errors {
|
||||
background: #FFC2C2;
|
||||
}
|
||||
|
||||
ul.c li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
ul.c {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
padding-left: 0.1em;
|
||||
}
|
||||
|
||||
ul.c li {
|
||||
padding: 0.25em 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul.c li span.r {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.r {
|
||||
display:none;
|
||||
}
|
||||
|
||||
#topbar {
|
||||
background-color: #000000;
|
||||
clear: both;
|
||||
color: #EEEEEE;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 501;
|
||||
}
|
||||
|
||||
.nav {
|
||||
color: #fff;
|
||||
background: #000;
|
||||
padding:0;
|
||||
overflow:auto;
|
||||
list-style:none;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.nav a, .nav a:link, .nav a:active, .nav a:visited {
|
||||
background: #666;
|
||||
color: #fff;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.nav a:focus, .nav a:hover, .nav a:active {
|
||||
background: transparent;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.nav li:hover, .nav a:focus, .nav a:hover, .nav a:active {
|
||||
color: #CCCCCC;
|
||||
}
|
||||
|
||||
.nav li.link {
|
||||
width:20%;
|
||||
float:left;
|
||||
outline:black solid 1px;
|
||||
}
|
||||
.nav .link a {
|
||||
font-size:small;
|
||||
text-align:center;
|
||||
display:block;
|
||||
}
|
||||
|
||||
#database_auth_form table td {
|
||||
width:7em;
|
||||
}
|
||||
|
||||
table.c {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.mobile-done {
|
||||
display:inline;
|
||||
}
|
||||
|
||||
input#todo_description, input#todo_tag_list, textarea#todo_notes, select#todo_project_id, select#todo_context_id {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.next-prev-project {
|
||||
overflow:auto;
|
||||
padding:0;
|
||||
margin:0;
|
||||
list-style:none;
|
||||
}
|
||||
|
||||
.prev,
|
||||
.next {
|
||||
float:left;
|
||||
width:50%;
|
||||
}
|
||||
|
||||
.next {
|
||||
float:right;
|
||||
}
|
||||
|
||||
.prev a,
|
||||
.next a {
|
||||
display:block;
|
||||
height:1em;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.prev a {
|
||||
background: url(images/previous.png) left center no-repeat;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.prev a:hover {
|
||||
background: #cc3334 url(images/previous.png) left center no-repeat;
|
||||
}
|
||||
|
||||
.next a {
|
||||
text-align:right;
|
||||
background: url(images/next.png) right center no-repeat;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.next a:hover {
|
||||
background: #cc3334 url(images/next.png) right center no-repeat;
|
||||
}
|
||||
83
app/assets/stylesheets/print.css
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
color: #000;
|
||||
font-size: 8.2pt;
|
||||
font-family: "Lucida Grande", "Bitstream Vera Sans", Helvetica, Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 2.2in;
|
||||
max-height: 4.3in;
|
||||
border:0;
|
||||
}
|
||||
|
||||
#navcontainer, #input_box, #footer, .big-box, .refresh, .badge, h1, .icon,
|
||||
#minilinks, .defer-container, .menu_sort, .position, .buttons, .sf-item-menu,
|
||||
.container_toggle, .grip, .show_notes, .recurring_icon, #project-next-prev,
|
||||
.project_settings, .add_note_link {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.tag {
|
||||
margin-left: 3pt;
|
||||
}
|
||||
|
||||
.contexts {
|
||||
margin: 0 0 2em 0;
|
||||
border-top: 1px solid #000;
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
.contexts:first-child {
|
||||
page-break-before: avoid;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.4em;
|
||||
font-weight: bold;
|
||||
margin-bottom: .3em;
|
||||
margin-top: 5pt;
|
||||
padding: .2em 0;
|
||||
border-bottom: 1pt dotted #000;
|
||||
}
|
||||
|
||||
a, p, blockquote, ul, li, ol, dt, dd, dl, table {
|
||||
margin: 0 0 .3em 0;
|
||||
}
|
||||
|
||||
.notes {
|
||||
margin: .12em 1.2em;
|
||||
padding: .3em;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-left: 18pt;
|
||||
line-height: 150%
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: .1em 0 .1em 2em;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.item-container {
|
||||
clear:both;
|
||||
padding-top: .3em;
|
||||
padding-bottom: .3em;
|
||||
}
|
||||
|
||||
.item-checkbox {
|
||||
width: 10pt;
|
||||
height: 10pt;
|
||||
display:block;
|
||||
float:left;
|
||||
}
|
||||
162
app/assets/stylesheets/scaffold.css
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
body { background-color: #fff; color: #333; }
|
||||
|
||||
body, ol, ul, td {
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
p {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
a, a:link, a:active, a:visited {
|
||||
color: #cc3334;
|
||||
text-decoration: none;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #fff;
|
||||
background-color: #cc3334;
|
||||
}
|
||||
|
||||
h1, h2, h3 { color: #333; font-family: verdana, arial, helvetica, sans-serif; text-align: center; }
|
||||
h1 { font-size: 28px }
|
||||
h2 { font-size: 19px }
|
||||
h3 { font-size: 16px }
|
||||
|
||||
li { margin-bottom: 7px; }
|
||||
|
||||
pre {
|
||||
background-color: #eee;
|
||||
padding: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
td {background-color: #ff9;}
|
||||
|
||||
#scaffold-main {
|
||||
width: 80%;
|
||||
margin: 10px auto;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
div.form {
|
||||
width: 350px;
|
||||
margin: 100px auto 10px auto;
|
||||
padding: 10px;
|
||||
border: 1px solid #999;
|
||||
background: #ff9;
|
||||
}
|
||||
|
||||
div.memo {
|
||||
width: 40%;
|
||||
margin: 100px auto;
|
||||
padding: 10px;
|
||||
border: 1px solid #999;
|
||||
background: #ff9;
|
||||
}
|
||||
|
||||
/* Flash box styling */
|
||||
|
||||
h4.alert {
|
||||
font-size: 0.8em;
|
||||
font-weight:bold;
|
||||
margin:0;
|
||||
padding:5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h4.warning {
|
||||
border: 1px solid #ED2E38;
|
||||
background-color: #F6979C;
|
||||
color: #000000;
|
||||
}
|
||||
h4.error {
|
||||
color:#fff;
|
||||
background:#c00;
|
||||
}
|
||||
h4.notice {
|
||||
border: 1px solid #007E00;
|
||||
background-color: #c2ffc2;
|
||||
color: #007E00;
|
||||
}
|
||||
|
||||
/*#notice {
|
||||
padding: 2px;
|
||||
border: 1px solid #007E00;
|
||||
background-color: #c2ffc2;
|
||||
color: #007E00;
|
||||
margin-bottom: 15px;
|
||||
text-align: center;
|
||||
}
|
||||
*/
|
||||
|
||||
#footer {
|
||||
clear: both;
|
||||
background-color: #eee;
|
||||
font-size: 0.8em;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
margin: 20px auto;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
|
||||
/* Error message styles */
|
||||
.fieldWithErrors {
|
||||
padding: 2px;
|
||||
background-color: red;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#errorExplanation {
|
||||
border: 2px solid #ff0000;
|
||||
padding: 7px;
|
||||
padding-bottom: 12px;
|
||||
margin: 10px auto 10px auto;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#errorExplanation h2 {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding: 5px 5px 5px 15px;
|
||||
font-size: 12px;
|
||||
margin: -7px;
|
||||
background-color: #c00;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#errorExplanation p {
|
||||
color: #333;
|
||||
margin-bottom: 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#errorExplanation ul li {
|
||||
font-size: 1em;
|
||||
list-style-type: disc;
|
||||
list-style-position: outside;
|
||||
}
|
||||
|
||||
input.login_text {
|
||||
width:200px;
|
||||
}
|
||||
input.open_id {
|
||||
background: url(../images/open-id-login-bg.gif) no-repeat;
|
||||
background-color: #fff;
|
||||
background-position: 0 50%;
|
||||
color: #000;
|
||||
padding-left: 18px;
|
||||
width:182px;
|
||||
}
|
||||
p.alternate_auth {
|
||||
text-align:center;
|
||||
}
|
||||
p.alternate_auth a {
|
||||
text-decoration:underline;
|
||||
}
|
||||
1432
app/assets/stylesheets/tracks.css
Normal file
|
|
@ -95,10 +95,10 @@ class ApplicationController < ActionController::Base
|
|||
if count == 0 && deferred_count > 0
|
||||
word = deferred_count == 1 ? string.singularize : string.pluralize
|
||||
word = "deferred " + word
|
||||
deferred_count.to_s + " " + word
|
||||
return (deferred_count.to_s + " " + word).html_safe
|
||||
else
|
||||
word = count == 1 ? string.singularize : string.pluralize
|
||||
count.to_s + " " + word
|
||||
return (count.to_s + " " + word).html_safe
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
class CannotAccessContext < RuntimeError; end
|
||||
|
||||
class BackendController < ApplicationController
|
||||
acts_as_web_service
|
||||
wsdl_service_name 'Backend'
|
||||
web_service_api TodoApi
|
||||
web_service_scaffold :invoke
|
||||
skip_before_filter :login_required
|
||||
|
||||
|
||||
def new_todo(username, token, context_id, description, notes)
|
||||
check_token(username, token)
|
||||
check_context_belongs_to_user(context_id)
|
||||
item = create_todo(description, context_id, nil, notes)
|
||||
item.id
|
||||
end
|
||||
|
||||
def new_todo_for_project(username, token, context_id, project_id, description, notes)
|
||||
check_token(username, token)
|
||||
check_context_belongs_to_user(context_id)
|
||||
item = create_todo(description, context_id, project_id, notes)
|
||||
item.id
|
||||
end
|
||||
|
||||
def new_rich_todo(username, token, default_context_id, description, notes)
|
||||
check_token(username,token)
|
||||
item = Todo.from_rich_message(@user, default_context_id, description, notes)
|
||||
item.save
|
||||
raise item.errors.full_messages.to_s if item.new_record?
|
||||
item.id
|
||||
end
|
||||
|
||||
def list_contexts(username, token)
|
||||
check_token(username, token)
|
||||
|
||||
@user.contexts
|
||||
end
|
||||
|
||||
def list_projects(username, token)
|
||||
check_token(username, token)
|
||||
|
||||
@user.projects
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Check whether the token in the URL matches the token in the User's table
|
||||
def check_token(username, token)
|
||||
@user = User.find_by_login( username )
|
||||
unless (token == @user.token)
|
||||
raise(InvalidToken, "Sorry, you don't have permission to perform this action.")
|
||||
end
|
||||
end
|
||||
|
||||
def check_context_belongs_to_user(context_id)
|
||||
unless @user.contexts.exists? context_id
|
||||
raise(CannotAccessContext, "Cannot access a context that does not belong to this user.")
|
||||
end
|
||||
end
|
||||
|
||||
def create_todo(description, context_id, project_id = nil, notes="")
|
||||
item = @user.todos.build
|
||||
item.description = description
|
||||
item.notes = notes
|
||||
item.context_id = context_id
|
||||
item.project_id = project_id unless project_id.nil?
|
||||
item.save
|
||||
raise item.errors.full_messages.to_s if item.new_record?
|
||||
item
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidToken < RuntimeError; end
|
||||
|
|
@ -263,7 +263,7 @@ class ContextsController < ApplicationController
|
|||
end
|
||||
|
||||
def set_context_from_params
|
||||
@context = current_user.contexts.find_by_params(params)
|
||||
@context = current_user.contexts.find(params[:id])
|
||||
rescue
|
||||
@context = nil
|
||||
end
|
||||
|
|
@ -276,11 +276,8 @@ class ContextsController < ApplicationController
|
|||
def init_todos
|
||||
set_context_from_params
|
||||
unless @context.nil?
|
||||
@context.todos.send :with_scope, :find => { :include => Todo::DEFAULT_INCLUDES } do
|
||||
@done = @context.done_todos
|
||||
end
|
||||
|
||||
@max_completed = current_user.prefs.show_number_completed
|
||||
@done = @context.todos.completed.all(:limit => @max_completed)
|
||||
|
||||
# @not_done_todos = @context.not_done_todos TODO: Temporarily doing this
|
||||
# search manually until I can work out a way to do the same thing using
|
||||
|
|
|
|||
|
|
@ -192,18 +192,17 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def sidebar_html_for_titled_list (list, title)
|
||||
return content_tag(:h3, title+" (#{list.length})") +
|
||||
content_tag(:ul, sidebar_html_for_list(list))
|
||||
return content_tag(:h3, title+" (#{list.length})") + content_tag(:ul, sidebar_html_for_list(list))
|
||||
end
|
||||
|
||||
def sidebar_html_for_list(list)
|
||||
if list.empty?
|
||||
return content_tag(:li, t('sidebar.list_empty'))
|
||||
return content_tag(:li, t('sidebar.list_empty')).html_safe
|
||||
else
|
||||
return list.inject("") do |html, item|
|
||||
link = (item.class == "Project") ? link_to_project( item ) : link_to_context(item)
|
||||
html << content_tag(:li, link + " (" + count_undone_todos_phrase(item)+")")
|
||||
end
|
||||
end.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ module TodosHelper
|
|||
|
||||
def collapsed_notes_image(todo)
|
||||
link = link_to(image_tag( 'blank.png', :width=>'16', :height=>'16', :border=>'0' ), "#", {:class => 'show_notes', :title => 'Show notes'})
|
||||
notes = content_tag(:div, {:class => "todo_notes", :id => dom_id(todo, 'notes'), :style => "display:none"}) { todo.rendered_notes }
|
||||
notes = content_tag(:div, {:class => "todo_notes", :id => dom_id(todo, 'notes'), :style => "display:none"}) { todo.rendered_notes.html_safe }
|
||||
return link+notes
|
||||
end
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ module TodosHelper
|
|||
end
|
||||
|
||||
def tag_list(todo=@todo, mobile=false)
|
||||
content_tag(:span, :class => 'tags') { todo.tags.all_except_starred.collect{|tag| tag_span(tag, mobile)}.join('') }
|
||||
content_tag(:span, :class => 'tags') { todo.tags.all_except_starred.collect{|tag| tag_span(tag, mobile)}.join('').html_safe }
|
||||
end
|
||||
|
||||
def tag_list_mobile(todo=@todo)
|
||||
|
|
@ -166,7 +166,7 @@ module TodosHelper
|
|||
str << item_link_to_project( todo )
|
||||
end
|
||||
end
|
||||
return str
|
||||
return str.html_safe
|
||||
end
|
||||
|
||||
# Uses the 'staleness_starts' value from settings.yml (in days) to colour the
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<% @not_done = @not_done_todos.select {|t| t.context_id == context.id } %>
|
||||
<div id="c<%= context.id %>" class="container context" <%= "style=\"display:none\"" if collapsible && @not_done.empty? %>>
|
||||
<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("collapse.png") %></a>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<div id="display_box">
|
||||
<%= render :partial => "contexts/context", :object => @context, :locals => { :collapsible => false } %>
|
||||
<%= render :partial => @context, :locals => { :collapsible => false } %>
|
||||
<%= render :partial => "todos/deferred", :object => @deferred, :locals => { :collapsible => false, :append_descriptor => t('contexts.todos_append'), :parent_container_type => 'context', :pending => @pending } %>
|
||||
<% unless @max_completed==0 -%>
|
||||
<%= render :partial => "todos/completed", :object => @done, :locals => { :suppress_context => true, :collapsible => false, :append_descriptor => t('contexts.last_completed_in_context', :number=>prefs.show_number_completed) } %>
|
||||
<% end -%>
|
||||
</div><!-- [end:display_box] -->
|
||||
</div>
|
||||
|
||||
<div id="input_box">
|
||||
<%= render :partial => "shared/add_new_item_form" %>
|
||||
<%= render :file => "sidebar/sidebar.html.erb" %>
|
||||
</div><!-- End of input box -->
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,24 +2,16 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<%#= stylesheet_link_tag 'standard','superfish','niftyCorners', 'jquery-ui-1.8.17.custom', :cache => 'tracks-cached' %>
|
||||
<%= stylesheet_link_tag "application", :media => "all" %>
|
||||
<%= stylesheet_link_tag "print", :media => "print" %>
|
||||
<%#= javascript_include_tag 'jquery-1.7.1.min', 'jquery-ui-1.8.17.custom.min',
|
||||
'jquery.truncator','jquery.jeditable.mini', 'jquery.cookie', 'jquery.blockUI',
|
||||
'jquery.form',
|
||||
:cache => 'jquery-cached' %>
|
||||
<%#= javascript_tag_for_i18n_datepicker %>
|
||||
<%#= javascript_include_tag 'hoverIntent','superfish','application',
|
||||
'accesskey-hints','niftycube','swfobject',
|
||||
:cache => 'tracks-cached' %>
|
||||
<% #= javascript_include_tag('jquery.simulate.drag-sortable') if ENV['RAILS_ENV']=='cucumber' -%>
|
||||
<%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %>
|
||||
<%= javascript_tag "var TAG_NAME = '#{@tag_name}';" if @tag_name %>
|
||||
<%= javascript_include_tag "application" %>
|
||||
<%= csrf_meta_tag %>
|
||||
<script type="text/javascript">
|
||||
var SOURCE_VIEW = '<%=@source_view%>';
|
||||
var defaultContexts = <%= default_contexts_for_autocomplete rescue '{}' %>;
|
||||
var defaultTags = <%= default_tags_for_autocomplete rescue '{}' %>;
|
||||
var AUTH_TOKEN = '<%= protect_against_forgery? ? form_authenticity_token.inspect : "" %>'
|
||||
var TAG_NAME = '<%= @tag_name ? @tag_name : "" %>'
|
||||
var defaultContexts = <%= default_contexts_for_autocomplete.html_safe rescue '{}' %>;
|
||||
var defaultTags = <%= default_tags_for_autocomplete.html_safe rescue '{}' %>;
|
||||
var dateFormat = '<%= date_format_for_date_picker %>';
|
||||
var weekStart = '<%= current_user.prefs.week_starts %>';
|
||||
function relative_to_root(path) { return '<%= root_url %>'+path; };
|
||||
|
|
@ -41,7 +33,7 @@
|
|||
<body class="<%= controller.controller_name %>">
|
||||
|
||||
<div id="topbar">
|
||||
<%= NOTIFY_BAR %>
|
||||
<%= NOTIFY_BAR.html_safe %>
|
||||
|
||||
<div id="date">
|
||||
<h1>
|
||||
|
|
@ -68,7 +60,7 @@
|
|||
<ul>
|
||||
<li><%= navigation_link( t('common.contexts'), contexts_path, {:accesskey=>"c", :title=>t('layouts.navigation.contexts_title')} ) %></li>
|
||||
<li><%= navigation_link( t('common.notes'), notes_path, {:accesskey => "o", :title => t('layouts.navigation.notes_title')} ) %></li>
|
||||
<li><%= navigation_link( t('common.review'), review_path, {:accesskey => "r", :title => t('layouts.navigation.review_title')} ) %></li>
|
||||
<li><%= navigation_link( t('common.review'), review_path, {:accesskey => "r", :title => t('layouts.navigation.review_title')} ) %></li>
|
||||
<li><%= navigation_link( t('layouts.navigation.recurring_todos'), {:controller => "recurring_todos", :action => "index"}, :title => t('layouts.navigation.recurring_todos_title')) %></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
<%
|
||||
todo = edit_form
|
||||
form_for(todo, :html=> { :name=>'todo', :id => dom_id(@todo, 'form'), :class => 'inline-form edit_todo_form' }) do |t|%>
|
||||
<div id="edit_error_status"><%= error_messages_for("todo", :object_name => 'action') %></div>
|
||||
<% todo = edit_form -%>
|
||||
<%= form_for(todo, :html=> { :name=>'todo', :id => dom_id(@todo, 'form'), :class => 'inline-form edit_todo_form' }) do |t|%>
|
||||
<div id="edit_error_status">
|
||||
<% if todo.errors.any? -%>
|
||||
<ul>
|
||||
<% todo.errors.full_messages.each do |msg| %>
|
||||
<li><%= msg %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end -%>
|
||||
</div>
|
||||
|
||||
<%= t.hidden_field( "id" ) -%>
|
||||
<%= source_view_tag( @source_view ) -%>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
<%- todo = new_multi_todo_form -%>
|
||||
|
||||
<div id="todo_multi_add" style="display:none">
|
||||
<% form_for(todo, :html=> { :id=>'todo-form-multi-new-action', :name=>'todo', :class => 'inline-form' }) do |t| %>
|
||||
<%= form_for(todo, :html=> { :id=>'todo-form-multi-new-action', :name=>'todo', :class => 'inline-form' }) do |t| %>
|
||||
<input id="default_project_name_id" name="default_project_name" type="hidden" value="<%=h @initial_project_name-%>" />
|
||||
<input id="default_context_name_id" name="default_context_name" type="hidden" value="<%=h @initial_context_name-%>" />
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<%- todo = new_todo_form -%>
|
||||
|
||||
<div id="todo_new_action">
|
||||
<% form_for(todo, :html=> { :id=>'todo-form-new-action', :name=>'todo', :class => 'inline-form new_todo_form' }) do |t|%>
|
||||
<%= form_for(todo, :html=> { :id=>'todo-form-new-action', :name=>'todo', :class => 'inline-form new_todo_form' }) do |t|%>
|
||||
<input id="default_project_name_id" name="default_project_name" type="hidden" value="<%= h(@initial_project_name)-%>" />
|
||||
<input id="default_context_name_id" name="default_context_name" type="hidden" value="<%= h(@initial_context_name)-%>" />
|
||||
<input type="hidden" id="new_todo_starred" name="new_todo_starred" value="false" />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div id="display_box">
|
||||
<div id="no_todos_in_view" class="container context" <%= "style=\"display:none\"" unless @not_done_todos.empty? %> >
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -110,7 +110,14 @@ function html_for_new_context() {
|
|||
}
|
||||
|
||||
function html_for_error_messages() {
|
||||
return "<%= escape_javascript(error_messages_for('todo')) %>";
|
||||
<%
|
||||
error_messages = ""
|
||||
if @todo.errors.any?
|
||||
list_of_messages = @todo.errors.full_messages.inject("") { |all, msg| all += context_tag(:li, msg) }
|
||||
error_messages = content_tag(:ul, list_of_messages)
|
||||
end
|
||||
-%>
|
||||
return "<%= escape_javascript(error_messages) %>";
|
||||
}
|
||||
|
||||
function update_predecessors(next_steps) {
|
||||
|
|
|
|||