Started working on the client-side code.
This commit is contained in:
1 parent
0642c18a6e
commit
afca12ecc9
9 files changed
+8269
-18
No files matched your search
Binary file not shown.
Binary file not shown.
+18
-18
@@ -62,20 +62,20 @@ dispatch_user(YArg, Session, [H]) ->
|
|||||||
{'GET', Username} -> get_user(YArg, Username);
|
{'GET', Username} -> get_user(YArg, Username);
|
||||||
|
|
||||||
{_BadMethod, Username} ->
|
{_BadMethod, Username} ->
|
||||||
make_json_405(YArg, [{see_docs, "/ts_api_doc/users"}]);
|
make_json_405(YArg, [{see_docs, "/ts_api_doc/users.html"}]);
|
||||||
|
|
||||||
_Other -> make_json_401(YArg, [{see_docs, "/ts_api_doc/users"}])
|
_Other -> make_json_401(YArg, [{see_docs, "/ts_api_doc/users.html"}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
dispatch_timeline(YArg, _Session, []) ->
|
dispatch_timeline(YArg, _Session, []) ->
|
||||||
make_json_404(YArg, [{see_docs, "/ts_api_doc/timelines"}]);
|
make_json_404(YArg, [{see_docs, "/ts_api_doc/timelines.html"}]);
|
||||||
|
|
||||||
dispatch_timeline(YArg, Session, [UrlUsername|_T] = PathElements) ->
|
dispatch_timeline(YArg, Session, [UrlUsername|_T] = PathElements) ->
|
||||||
Username = path_element_to_atom(UrlUsername),
|
Username = path_element_to_atom(UrlUsername),
|
||||||
|
|
||||||
case Session#ts_api_session.username of
|
case Session#ts_api_session.username of
|
||||||
Username -> dispatch_timeline(YArg, PathElements);
|
Username -> dispatch_timeline(YArg, PathElements);
|
||||||
_Other -> make_json_404(YArg, [{see_docs, "/ts_api_doc/users"}])
|
_Other -> make_json_404(YArg, [{see_docs, "/ts_api_doc/users.html"}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
% just username, list timelines
|
% just username, list timelines
|
||||||
@@ -85,7 +85,7 @@ dispatch_timeline(YArg, [UrlUsername]) ->
|
|||||||
|
|
||||||
case HTTPMethod of
|
case HTTPMethod of
|
||||||
'GET' -> list_timelines(YArg, Username);
|
'GET' -> list_timelines(YArg, Username);
|
||||||
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/timelines"}])
|
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/timelines.html"}])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
dispatch_timeline(YArg, [UrlUsername, UrlTimelineId]) ->
|
dispatch_timeline(YArg, [UrlUsername, UrlTimelineId]) ->
|
||||||
@@ -98,21 +98,21 @@ dispatch_timeline(YArg, [UrlUsername, UrlTimelineId]) ->
|
|||||||
'POST' -> post_timeline(YArg, Username, TimelineId);
|
'POST' -> post_timeline(YArg, Username, TimelineId);
|
||||||
'PUT' -> put_timeline(YArg, Username, TimelineId);
|
'PUT' -> put_timeline(YArg, Username, TimelineId);
|
||||||
'DELETE' -> delete_timeline(YArg, Username, TimelineId);
|
'DELETE' -> delete_timeline(YArg, Username, TimelineId);
|
||||||
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/timelines"}])
|
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/timelines.html"}])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
dispatch_timeline(YArg, _Other) ->
|
dispatch_timeline(YArg, _Other) ->
|
||||||
make_json_404(YArg, [{see_docs, "/ts_api_doc/timelines"}]).
|
make_json_404(YArg, [{see_docs, "/ts_api_doc/timelines.html"}]).
|
||||||
|
|
||||||
dispatch_entry(YArg, _Session, []) ->
|
dispatch_entry(YArg, _Session, []) ->
|
||||||
make_json_404(YArg, [{see_docs, "/ts_aip_doc/entries"}]);
|
make_json_404(YArg, [{see_docs, "/ts_aip_doc/entries.html"}]);
|
||||||
|
|
||||||
dispatch_entry(YArg, Session, [UrlUsername|_T] = PathElements) ->
|
dispatch_entry(YArg, Session, [UrlUsername|_T] = PathElements) ->
|
||||||
Username = path_element_to_atom(UrlUsername),
|
Username = path_element_to_atom(UrlUsername),
|
||||||
|
|
||||||
case Session#ts_api_session.username of
|
case Session#ts_api_session.username of
|
||||||
Username -> dispatch_entry(YArg, PathElements);
|
Username -> dispatch_entry(YArg, PathElements);
|
||||||
_Other -> make_json_404(YArg, [{see_docs, "/ts_api_doc/entries"}])
|
_Other -> make_json_404(YArg, [{see_docs, "/ts_api_doc/entries.html"}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
dispatch_entry(YArg, [UrlUsername, UrlTimelineId]) ->
|
dispatch_entry(YArg, [UrlUsername, UrlTimelineId]) ->
|
||||||
@@ -123,7 +123,7 @@ dispatch_entry(YArg, [UrlUsername, UrlTimelineId]) ->
|
|||||||
case HTTPMethod of
|
case HTTPMethod of
|
||||||
'GET' -> list_entries(YArg, Username, TimelineId);
|
'GET' -> list_entries(YArg, Username, TimelineId);
|
||||||
'PUT' -> put_entry(YArg, Username, TimelineId);
|
'PUT' -> put_entry(YArg, Username, TimelineId);
|
||||||
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/entries"}])
|
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/entries.html"}])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
dispatch_entry(YArg, [UrlUsername, UrlTimelineId, UrlEntryId]) ->
|
dispatch_entry(YArg, [UrlUsername, UrlTimelineId, UrlEntryId]) ->
|
||||||
@@ -136,11 +136,11 @@ dispatch_entry(YArg, [UrlUsername, UrlTimelineId, UrlEntryId]) ->
|
|||||||
'GET' -> get_entry(YArg, Username, TimelineId, EntryId);
|
'GET' -> get_entry(YArg, Username, TimelineId, EntryId);
|
||||||
'POST' -> post_entry(YArg, Username, TimelineId, EntryId);
|
'POST' -> post_entry(YArg, Username, TimelineId, EntryId);
|
||||||
'DELETE' -> delete_entry(YArg, Username, TimelineId, EntryId);
|
'DELETE' -> delete_entry(YArg, Username, TimelineId, EntryId);
|
||||||
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/entries"}])
|
_Other -> make_json_405(YArg, [{see_docs, "/ts_api_doc/entries.html"}])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
dispatch_entry(YArg, _Other) ->
|
dispatch_entry(YArg, _Other) ->
|
||||||
make_json_404(YArg, [{see_docs, "/ts_api_doc/entries"}]).
|
make_json_404(YArg, [{see_docs, "/ts_api_doc/entries.html"}]).
|
||||||
|
|
||||||
% ============================== %
|
% ============================== %
|
||||||
% ======== IMPLEMENTATION ====== %
|
% ======== IMPLEMENTATION ====== %
|
||||||
@@ -175,7 +175,7 @@ do_login(YArg) ->
|
|||||||
"bad username/password combination"}])
|
"bad username/password combination"}])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
_Other -> make_json_400(YArg, [{see_docs, "/ts_api_doc/login"}])
|
_Other -> make_json_400(YArg, [{see_docs, "/ts_api_doc/login.html"}])
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_logout(YArg) ->
|
do_logout(YArg) ->
|
||||||
@@ -252,7 +252,7 @@ put_timeline(YArg, Username, TimelineId) ->
|
|||||||
JSONResponse = json:encode({struct, [
|
JSONResponse = json:encode({struct, [
|
||||||
{status, "ignored"},
|
{status, "ignored"},
|
||||||
{timeline, EJSONRec},
|
{timeline, EJSONRec},
|
||||||
{see_docs, "/ts_api_doc/timelines#PUT"}
|
{see_docs, "/ts_api_doc/timelines.html#PUT"}
|
||||||
]}),
|
]}),
|
||||||
|
|
||||||
{content, "application/json", JSONResponse};
|
{content, "application/json", JSONResponse};
|
||||||
@@ -282,7 +282,7 @@ post_timeline(YArg, Username, TimelineId) ->
|
|||||||
|
|
||||||
no_record -> make_json_404(YArg,
|
no_record -> make_json_404(YArg,
|
||||||
[{status, "no such timeline"},
|
[{status, "no such timeline"},
|
||||||
{see_docs, "/ts_api_doc/timelines#POST"}]);
|
{see_docs, "/ts_api_doc/timelines.html#POST"}]);
|
||||||
|
|
||||||
_Error -> make_json_500(YArg)
|
_Error -> make_json_500(YArg)
|
||||||
end.
|
end.
|
||||||
@@ -299,7 +299,7 @@ list_entries(YArg, Username, TimelineId) ->
|
|||||||
|
|
||||||
{no_record, _ByDateField} -> make_json_404(
|
{no_record, _ByDateField} -> make_json_404(
|
||||||
[{status, "no such timeline"},
|
[{status, "no such timeline"},
|
||||||
{see_docs, "/ts_api_doc/entries#LIST"}]);
|
{see_docs, "/ts_api_doc/entries.html#LIST"}]);
|
||||||
|
|
||||||
% listing by date range
|
% listing by date range
|
||||||
{Timeline, {byDate, "true"}} ->
|
{Timeline, {byDate, "true"}} ->
|
||||||
@@ -402,7 +402,7 @@ put_entry(YArg, Username, TimelineId) ->
|
|||||||
JSONResponse = json:encode({struct, [
|
JSONResponse = json:encode({struct, [
|
||||||
{status, "ignored"},
|
{status, "ignored"},
|
||||||
{entry, EJSONRec},
|
{entry, EJSONRec},
|
||||||
{see_docs, "/ts_api_doc/entries#PUT"}
|
{see_docs, "/ts_api_doc/entries.html#PUT"}
|
||||||
]}),
|
]}),
|
||||||
|
|
||||||
{content, "application/json", JSONResponse};
|
{content, "application/json", JSONResponse};
|
||||||
@@ -425,7 +425,7 @@ post_entry(YArg, Username, TimelineId, EntryId) ->
|
|||||||
ok -> make_json_200(YArg, NewRecord);
|
ok -> make_json_200(YArg, NewRecord);
|
||||||
|
|
||||||
no_record -> make_json_404(YArg,
|
no_record -> make_json_404(YArg,
|
||||||
[{status, "no such entry"}, {see_docs, "/ts_api_doc/entries#POST"}]);
|
[{status, "no such entry"}, {see_docs, "/ts_api_doc/entries.html#POST"}]);
|
||||||
|
|
||||||
_Error -> make_json_500(YArg)
|
_Error -> make_json_500(YArg)
|
||||||
end.
|
end.
|
||||||
|
|||||||
Whitespace-only changes.
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>TimeStamper - Simple time tracking</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
<div>
|
||||||
|
<h1>TimeStamper</h1>
|
||||||
|
<h4>Simple time tracking.</h4>
|
||||||
|
</div>
|
||||||
|
<div id="form-panel">
|
||||||
|
<form action="/ts/" method="post">
|
||||||
|
<label for="uname">username: </label>
|
||||||
|
<input name="uname" type="text"/>
|
||||||
|
<label for="pwd">password: </label>
|
||||||
|
<input name="pwd" type="password"/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Vendored
+8176
File diff suppressed because it is too large.
Load diff
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/*!
|
||||||
|
* jQuery JavaScript Library v1.5
|
||||||
|
* http://jquery.com/
|
||||||
|
*
|
||||||
|
* Copyright 2011, John Resig
|
||||||
|
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||||
|
* http://jquery.org/license
|
||||||
|
*
|
||||||
|
* Includes Sizzle.js
|
||||||
|
* http://sizzlejs.com/
|
||||||
|
* Copyright 2011, The Dojo Foundation
|
||||||
|
* Released under the MIT, BSD, and GPL Licenses.
|
||||||
|
*
|
||||||
|
* Date: Mon Jan 31 08:31:29 2011 -0500
|
||||||
|
*/
|
||||||
|
(function(a,b){function b$(a){return d.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function bX(a){if(!bR[a]){var b=d("<"+a+">").appendTo("body"),c=b.css("display");b.remove();if(c==="none"||c==="")c="block";bR[a]=c}return bR[a]}function bW(a,b){var c={};d.each(bV.concat.apply([],bV.slice(0,b)),function(){c[this]=a});return c}function bJ(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var e=a.dataTypes,f=a.converters,g,h=e.length,i,j=e[0],k,l,m,n,o;for(g=1;g<h;g++){k=j,j=e[g];if(j==="*")j=k;else if(k!=="*"&&k!==j){l=k+" "+j,m=f[l]||f["* "+j];if(!m){o=b;for(n in f){i=n.split(" ");if(i[0]===k||i[0]==="*"){o=f[i[1]+" "+j];if(o){n=f[n],n===!0?m=o:o===!0&&(m=n);break}}}}!m&&!o&&d.error("No conversion from "+l.replace(" "," to ")),m!==!0&&(c=m?m(c):o(n(c)))}}return c}function bI(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bH(a,b,c,e){d.isArray(b)&&b.length?d.each(b,function(b,f){c||bp.test(a)?e(a,f):bH(a+"["+(typeof f==="object"||d.isArray(f)?b:"")+"]",f,c,e)}):c||b==null||typeof b!=="object"?e(a,b):d.isArray(b)||d.isEmptyObject(b)?e(a,""):d.each(b,function(b,d){bH(a+"["+b+"]",d,c,e)})}function bG(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bD,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l==="string"&&(g[l]?l=b:(c.dataTypes.unshift(l),l=bG(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bG(a,c,d,e,"*",g));return l}function bF(a){return function(b,c){typeof b!=="string"&&(c=b,b="*");if(d.isFunction(c)){var e=b.toLowerCase().split(bz),f=0,g=e.length,h,i,j;for(;f<g;f++)h=e[f],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bn(a,b,c){var e=b==="width"?bh:bi,f=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return f;d.each(e,function(){c||(f-=parseFloat(d.css(a,"padding"+this))||0),c==="margin"?f+=parseFloat(d.css(a,"margin"+this))||0:f-=parseFloat(d.css(a,"border"+this+"Width"))||0});return f}function _(a,b){b.src?d.ajax({url:b.src,async:!1,dataType:"script"}):d.globalEval(b.text||b.textContent||b.innerHTML||""),b.parentNode&&b.parentNode.removeChild(b)}function $(a,b){if(b.nodeType===1){var c=b.nodeName.toLowerCase();b.clearAttributes(),b.mergeAttributes(a);if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(d.expando)}}function Z(a,b){if(b.nodeType===1&&d.hasData(a)){var c=d.expando,e=d.data(a),f=d.data(b,e);if(e=e[c]){var g=e.events;f=f[c]=d.extend({},e);if(g){delete f.handle,f.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)d.event.add(b,h,g[h][i],g[h][i].data)}}}}function Y(a,b){return d.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function O(a,b,c){if(d.isFunction(b))return d.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return d.grep(a,function(a,d){return a===b===c});if(typeof b==="string"){var e=d.grep(a,function(a){return a.nodeType===1});if(J.test(b))return d.filter(b,e,!c);b=d.filter(b,e)}return d.grep(a,function(a,e){return d.inArray(a,b)>=0===c})}function N(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function F(a,b){return(a&&a!=="*"?a+".":"")+b.replace(q,"`").replace(r,"&")}function E(a){var b,c,e,f,g,h,i,j,k,l,m,n,p,q=[],r=[],s=d._data(this,u);typeof s==="function"&&(s=s.events);if(a.liveFired!==this&&s&&s.live&&!a.target.disabled&&(!a.button||a.type!=="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var t=s.live.slice(0);for(i=0;i<t.length;i++)g=t[i],g.origType.replace(o,"")===a.type?r.push(g.selector):t.splice(i--,1);f=d(a.target).closest(r,a.currentTarget);for(j=0,k=f.length;j<k;j++){m=f[j];for(i=0;i<t.length;i++){g=t[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))){h=m.elem,e=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,e=d(a.relatedTarget).closest(g.selector)[0];(!e||e!==h)&&q.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=q.length;j<k;j++){f=q[j];if(c&&f.level>c)break;a.currentTarget=f.elem,a.data=f.handleObj.data,a.handleObj=f.handleObj,p=f.handleObj.origHandler.apply(f.elem,arguments);if(p===!1||a.isPropagationStopped()){c=f.level,p===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function C(a,b,c){c[0].type=a;return d.event.handle.apply(b,c)}function w(){return!0}function v(){return!1}function f(a,c,f){if(f===b&&a.nodeType===1){f=a.getAttribute("data-"+Line truncated
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="user" class="bar">
|
||||||
|
<span id="fullname">Jonathan Bernard</span>
|
||||||
|
<span id="username">jdbernard</span>
|
||||||
|
</div>
|
||||||
|
<div id="user-info" class="bar">
|
||||||
|
<form action="/ts/update-user.yaws" onsubmit="updateUser(); false">
|
||||||
|
<!-- TODO -->
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="timeline" class="bar">
|
||||||
|
<span id="timeline_name">work</span>
|
||||||
|
</div>
|
||||||
|
<div id="timeline-info" class="bar">
|
||||||
|
<form action="/ts/update-timeline.yaws" onsubmit="updateTimeline(); false">
|
||||||
|
<!-- TODO -->
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="new-entry" class="bar">
|
||||||
|
</div>
|
||||||
|
<div id="new-entry-notes" class="bar">
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in new issue
Block a user