summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/todo/todo.html79
-rw-r--r--modules/todo/todo.js39
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 {