Further updates to page. Small update to internal API.

Internal API update functions now accept partial updates, allowing one to
selectively update only some fields of a particular record.
This commit is contained in:
Jonathan Bernard 2011-02-14 17:16:37 -06:00
parent ddc12cec64
commit 1a3c0d5c4e
6 changed files with 75 additions and 64 deletions

View File

@ -1,5 +1,5 @@
-module(ts_common). -module(ts_common).
-export([new/1, update/1, list/3, order_datetimes/2]). -export([new/1, update/1, update_record/2, list/3, order_datetimes/2]).
-include_lib("stdlib/include/qlc.hrl"). -include_lib("stdlib/include/qlc.hrl").
@ -25,9 +25,22 @@ update(Record) ->
% record does not exist, cannot update % record does not exist, cannot update
[] -> no_record; [] -> no_record;
% record does exist, update % record does exist, update
[_ExistingRecord] -> mnesia:dirty_write(Record) [ExistingRecord] ->
mnesia:dirty_write(update_record(ExistingRecord, Record))
end. end.
update_record(Record, UpdateData) ->
update_record(tuple_to_list(Record), tuple_to_list(UpdateData), []).
update_record([], [], Updated) -> list_to_tuple(lists:reverse(Updated));
update_record([Field|RecordFields], [FieldReplacement|UpdateData], Acc) ->
UpdatedField = case FieldReplacement of
undefined -> Field;
NewValue -> NewValue
end,
update_record(RecordFields, UpdateData, [UpdatedField|Acc]).
%% list <Length> number of records, skipping the first <Start> %% list <Length> number of records, skipping the first <Start>
list(Table, Start, Length) list(Table, Start, Length)
when is_atom(Table) and is_integer(Start) and is_integer(Length) -> when is_atom(Table) and is_integer(Start) and is_integer(Length) ->

View File

@ -25,7 +25,8 @@ update(ER = #ts_entry{}) ->
% record does not exist % record does not exist
[] -> no_record; [] -> no_record;
% record exists, update it % record exists, update it
[_Record] -> mnesia:dirty_write(ER) [ExistingRecord] ->
mnesia:dirty_write(ts_common:update_record(ExistingRecord, ER))
end. end.
lookup(Username, TimelineId, EntryId) -> lookup(Username, TimelineId, EntryId) ->

View File

@ -47,7 +47,7 @@ ejson_to_record(_Empty=#ts_timeline{}, EJSON) ->
{struct, Fields} = EJSON, {struct, Fields} = EJSON,
#ts_timeline{ #ts_timeline{
ref = {undef, undef}, ref = {undefined, undefined},
created = decode_datetime(element(2, lists:keyfind(created, 1, Fields))), created = decode_datetime(element(2, lists:keyfind(created, 1, Fields))),
desc = element(2, lists:keyfind(description, 1, Fields))}; desc = element(2, lists:keyfind(description, 1, Fields))};
@ -55,7 +55,7 @@ ejson_to_record(_Empty=#ts_entry{}, EJSON) ->
{struct, Fields} = EJSON, {struct, Fields} = EJSON,
#ts_entry{ #ts_entry{
ref = {undef, undef, undef}, ref = {undefined, undefined, undefined},
timestamp = calendar:datetime_to_gregorian_seconds(decode_datetime( timestamp = calendar:datetime_to_gregorian_seconds(decode_datetime(
element(2, lists:keyfind(timestamp, 1, Fields)))), element(2, lists:keyfind(timestamp, 1, Fields)))),
mark = element(2, lists:keyfind(mark, 1, Fields)), mark = element(2, lists:keyfind(mark, 1, Fields)),

View File

@ -102,7 +102,16 @@ form {
form div.form-submit { form div.form-submit {
float: left; float: left;
width: 100%; width: 100%;
overflow: hidden; } overflow: hidden;
padding: 0.5em 2em 0.5em 2em;
position: relative; }
form div.form-submit div {
position: relative;
float: right;
left: -50%; }
form div.form-submit div input {
position: relative;
left: 50%; }
form div.form-submit input, form input.form-submit { form div.form-submit input, form input.form-submit {
border: 1px solid #979681; border: 1px solid #979681;
background: #f6f3ea; } background: #f6f3ea; }
@ -125,16 +134,6 @@ form {
color: #626150; } color: #626150; }
#user #change-pwd { #user #change-pwd {
display: none; } display: none; }
#user #user-info .form-submit {
padding: 0.5em 2em 0.5em 2em;
position: relative; }
#user #user-info .form-submit div {
position: relative;
float: right;
left: -50%; }
#user #user-info .form-submit div input {
position: relative;
left: 50%; }
#timeline #timeline-name, #timeline #timeline-desc { #timeline #timeline-name, #timeline #timeline-desc {
font-weight: bold; } font-weight: bold; }
@ -142,10 +141,6 @@ form {
color: #626150; } color: #626150; }
#timeline .control-links { #timeline .control-links {
padding-top: 0.2em; } padding-top: 0.2em; }
#timeline #timeline-info .form-submit {
width: auto;
float: right;
overflow: inline; }
#user-info, #timeline-info { #user-info, #timeline-info {
display: none; display: none;
@ -159,6 +154,7 @@ form {
#new-entry input { #new-entry input {
color: #626150; } color: #626150; }
#new-entry #add-notes { #new-entry #add-notes {
display: none; } display: none;
padding: 0.5em 0 0.5em 2em; }
#new-entry #new-entry-input { #new-entry #new-entry-input {
margin-right: 1em; } margin-right: 1em; }

View File

@ -127,8 +127,22 @@ form {
float: left; float: left;
width: 100%; width: 100%;
overflow: hidden; overflow: hidden;
padding: 0.5em 2em 0.5em 2em;
position: relative;
div {
position: relative;
float: right;
left: -50%;
input {
position: relative;
left: 50%;
}
}
} }
div.form-submit input, input.form-submit { div.form-submit input, input.form-submit {
border: 1px solid $bbor; border: 1px solid $bbor;
background: lighten($bbg, 10%); background: lighten($bbg, 10%);
@ -156,19 +170,6 @@ form {
#change-pwd { display: none; } #change-pwd { display: none; }
#user-info .form-submit { #user-info .form-submit {
padding: 0.5em 2em 0.5em 2em;
position: relative;
div {
position: relative;
float: right;
left: -50%;
input {
position: relative;
left: 50%;
}
}
} }
} }
@ -180,12 +181,6 @@ form {
.control-links { padding-top: 0.2em; } .control-links { padding-top: 0.2em; }
#timeline-info .form-submit {
width: auto;
float: right;
overflow: inline;
}
} }
#user-info, #timeline-info { #user-info, #timeline-info {
@ -204,6 +199,10 @@ form {
input { color: $greyTxt; } input { color: $greyTxt; }
#add-notes { display: none; } #add-notes {
display: none;
padding: 0.5em 0 0.5em 2em;
}
#new-entry-input { margin-right: 1em; } #new-entry-input { margin-right: 1em; }
} }

View File

@ -2,9 +2,11 @@
<html> <html>
<head> <head>
<title>TimeStamper - Simple Time Tracking</title>
<link rel="stylesheet" media="screen" href="../css/ts-screen.css" type="text/css"/> <link rel="stylesheet" media="screen" href="../css/ts-screen.css" type="text/css"/>
<script type="text/javascript" src="../js/jquery-1.5.min.js"></script> <script type="text/javascript" src="../js/jquery-1.5.min.js"></script>
<script type="text/javascript" src="../js/ts.js"></script> <script type="text/javascript" src="../js/ts.js"></script>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head> </head>
<body> <body>
@ -21,32 +23,33 @@
<div id="user-info"> <div id="user-info">
<form action="/ts/update-user.yaws" onsubmit="updateUser(event)"> <form action="/ts/update-user.yaws" onsubmit="updateUser(event)">
<div class="form-col"> <div class="form-col">
<label for="fullname"><span>name:</span> <label for="fullname-input"><span>name:</span>
<input id="fullname-input" name="fullname" <input id="fullname-input" name="fullname"
class="text-input" type="text"/> class="text-input" type="text"/>
</label> </label>
<label for="email"><span>email:</span> <label for="email-input"><span>email:</span>
<input id="email-input" name="email" <input id="email-input" name="email"
class="text-input" type="text"/> class="text-input" type="text"/>
</label> </label>
</div> </div>
<div class="form-col"> <div class="form-col">
<div id="change-pwd"> <div id="change-pwd">
<label for="old-pwd"><span>password:</span> <label for="old-pwd-input"><span>password:</span>
<input id="old-pwd-input" name="old-pwd" <input id="old-pwd-input" name="old-pwd"
class="text-input" type="password"/> class="text-input" type="password"/>
</label> </label>
<label for="new-pwd"><span>new pwd:</span> <label for="new-pwd-input"><span>new pwd:</span>
<input id="new-pwd-input" name="new-pwd" <input id="new-pwd-input" name="new-pwd"
class="text-input" type="password"/> class="text-input" type="password"/>
</label> </label>
<label for="new-pwd-conf"><span>confirm:</span> <label for="new-pwd-conf-input"><span>confirm:</span>
<input id="new-pwd-conf-input" name="new-pwd-conf" <input id="new-pwd-conf-input" name="new-pwd-conf"
class="text-input" type="password"/> class="text-input" type="password"/>
</label> </label>
</div> </div>
<label for="enable-pwd-change"> <label for="enable-pwd-change-input">
<input name="enable-pwd-change" type="checkbox" <input name="enable-pwd-change" type="checkbox"
id="enable-pwd-change-input"
onclick="showChangePwd(event)"/> onclick="showChangePwd(event)"/>
change password change password
</label> </label>
@ -74,13 +77,13 @@
<div id="timeline-info"> <div id="timeline-info">
<form action="/ts/update-timeline.yaws" <form action="/ts/update-timeline.yaws"
onsubmit="updateTimeline(event); false"> onsubmit="updateTimeline(event); false">
<label for="timeline-desc"><span>description:</span> <label for="timeline-desc-input"><span>description:</span>
<input id="timeline-desc-input" class="text-input" <input id="timeline-desc-input" class="text-input"
name="timeline-desc" type="text"/> name="timeline-desc" type="text"/>
</label> </label>
<div class="form-submit"> <div class="form-submit">
<input name="submit-timeline" type="submit" <div><input name="submit-timeline" type="submit"
value="save changes"/> value="save changes"/></div>
</div> </div>
</form> </form>
</div> </div>
@ -88,20 +91,19 @@
<div id="new-entry" class="bar last-bar"> <div id="new-entry" class="bar last-bar">
<form action="/ts/new-entry.yaws" onsubmit="newEntry(event)"> <form action="/ts/new-entry.yaws" onsubmit="newEntry(event)">
<span for="new-entry">begin a new activity: begin a new activity:
<input name="new-entry" id="new-entry-input" <input name="new-entry" id="new-entry-input"
class="text-input" type="text"/> class="text-input" type="text"/>
<input name=submit-entry" id="submit-entry" <input name="submit-entry" id="submit-entry"
class="form-submit" type="submit" value="create entry"/> class="form-submit" type="submit" value="create entry"/>
<div class="control-links"> <div class="control-links">
<a id="show-notes" href="#" <a id="show-notes" href="#"
onclick="showNewNotes(event)"/>add notes</a> onclick="showNewNotes(event)">add notes</a>
</div> </div>
</span> <div id="add-notes" class="form-col">
<div id="add-notes"> <label for="new-notes-input">notes:</label>
<label for="new-notes">notes:</label> <textarea name="new-notes" id="new-notes-input"
<input name="new-notes" id="new-notes-input" class="text-input" rows="8" cols="40" ></textarea>
class="text-input" type="textarea"/>
</div> </div>
</form> </form>
</div> </div>