diff options
-rw-r--r-- | modules/todo/todo.html | 79 | ||||
-rw-r--r-- | modules/todo/todo.js | 39 |
2 files changed, 102 insertions, 16 deletions
diff --git a/modules/todo/todo.html b/modules/todo/todo.html index 19b9370..22cce9b 100644 --- a/modules/todo/todo.html +++ b/modules/todo/todo.html @@ -61,6 +61,17 @@ function beginOfDay(date){ return d; } +function shiftDate(date,repweeks){ + var Y=date.getFullYear(), + M=date.getMonth(), + D=date.getDate(), + h=date.getHours(), + m=date.getMinutes(), + s=date.getSeconds(), + ms=date.getMilliseconds(); + return new Date(Y,M,D+7*repweeks,h,m,s,ms); +} + function fancytime(timeS){ return pad(timeS.hour,2,"0")+":"+pad(timeS.min,2,"0")+(timeS.sec==0?"":":"+pad(timeS.sec,2,"0")); } @@ -95,7 +106,7 @@ function tablerowfor(task){ var div=document.createElement("div"); div.classList.add("task"); - var e=document.createElement("span"); + var e=document.createElement("span"),e2; e.classList.add("tasksubject"); e.appendChild(document.createTextNode(task.subject)); div.appendChild(e); @@ -108,22 +119,43 @@ function tablerowfor(task){ e.appendChild(document.createTextNode((task.repweeks!=0?"(rep) ":"")+fancydate(task.date))); e.setAttribute("title",task.date.toString()); e.appendChild(document.createElement("br")); - var e2=document.createElement("span"); - e2.classList.add("subdate"); - e2.appendChild(document.createTextNode(task.date.toString())); + e2=document.createElement("span"); + e2.classList.add("subdate"); + e2.appendChild(document.createTextNode(task.date.toString())); e.appendChild(e2); float.appendChild(e); - e=document.createElement("span"); - e.classList.add("taskdelete"); - e.appendChild(document.createTextNode("X")); - e.addEventListener("click",function(ev){ - if(!confirm("Really delete task \""+task.subject+"\"?"))return - fetch("DELETE","/todo/task",task.id,function(status,body){ - if(status==200)getlist(); - else alert("Delete failed: "+body); + e=document.createElement("div"); + e.classList.add("taskbuttons"); + e2=document.createElement("span"); + e2.classList.add("taskdelete"); + e2.appendChild(document.createTextNode("X")); + e2.addEventListener("click",function(ev){ + if(!confirm("Really delete task \""+task.subject+"\"?"))return; + fetch("DELETE","/todo/task",task.id,function(status,body){ + if(status==200)getlist(); + else alert("Delete failed: "+body); + }); }); - }); + e.appendChild(e2); + + if(task.repweeks!=0){ + e.appendChild(document.createElement("br")); + + e2=document.createElement("span"); + e2.classList.add("taskshiftahead"); + e2.appendChild(document.createTextNode("→")); + e2.addEventListener("click",function(ev){ + if(!confirm("Really shift task \""+task.subject+"\" ahead by "+ + task.repweeks+" week"+(task.repweeks!=1?"s":"")+"?"))return; + fetch("POST","/todo/task/shiftahead",task.id,function(status,body){ + if(status==200)getlist(); + else alert("Shiftahead failed: "+body); + }); + }); + e.appendChild(e2); + } + float.appendChild(e); div.appendChild(float); @@ -141,7 +173,7 @@ function refreshlist(list){ task=list[i]; if(task.repweeks!=0){ while(task.date<now){ - task.date=new Date(task.date.getTime()+task.repweeks*7*24*3600*1000); + task.date=shiftDate(task.date,task.repweeks); } } rows.push([task.date,tablerowfor(task)]); @@ -256,13 +288,28 @@ body{ color:#ccc; font-size:8px; } -.taskdelete{ +.taskbuttons{ + margin-top:-5px; + display:inline-block; margin-left:60px; font-size:10px; + vertical-align:top; + width:10px; + text-align:center; +} +.taskdelete{ + margin-bottom:5px; + font-size:10px; font-family:sans-serif; color:red; cursor:pointer; - vertical-align:top; +} +.taskshiftahead{ + line-height:25px; + font-size:12px; + font-family:sans-serif; + color:blue; + cursor:pointer; } #addtaskform{ border:1px #ddd solid; diff --git a/modules/todo/todo.js b/modules/todo/todo.js index 66433d9..8fabc63 100644 --- a/modules/todo/todo.js +++ b/modules/todo/todo.js @@ -52,6 +52,18 @@ var naccounts=0; })(); +function shiftDate(date,repweeks){ + var Y=date.getFullYear(), + M=date.getMonth(), + D=date.getDate(), + h=date.getHours(), + m=date.getMinutes(), + s=date.getSeconds(), + ms=date.getMilliseconds(); + return new Date(Y,M,D+7*repweeks,h,m,s,ms); +} + + function sendUnauth(res){ res.set("WWW-Authenticate","Basic realm=Authorization required"); return res.sendStatus(401); @@ -161,6 +173,33 @@ module.exports=function(app,io,_moddir){ if(fail)res.status(404).send("Unknown id"); else res.status(200).end(); }); + app.post("/todo/task/shiftahead",function(req,res){ + var id=+req.body; + var i; + var fail=false; + var usertasks=tasks[req.authuser]; + var now; + if(id<0||~~id!=id||isNaN(id)||!usertasks){ + fail=true; + } else { + for(i=0;i<usertasks.length;i++)if(usertasks[i].id==id)break; + if(i==usertasks.length)fail=true; + else if(usertasks[i].repweeks==0){ + res.status(400).send("Can't shiftahead a non-repeating task"); + return; + } else { + now=new Date(); + while(usertasks[i].date<now){ // First move up to now + usertasks[i].date=shiftDate(usertasks[i].date,usertasks[i].repweeks); + } + // Then for the actual shiftahead: + usertasks[i].date=shiftDate(usertasks[i].date,usertasks[i].repweeks); + persist.setItemSync("tasks",tasks); + } + } + if(fail)res.status(404).send("Unknown id"); + else res.status(200).end(); + }); app.post("/todo/task",function(req,res){ var obj; try { |