timestamper/www/index.yaws

176 lines
7.2 KiB
Plaintext
Raw Normal View History

<!DOCTYPE html>
<html>
<head>
<title>TimeStamper - Simple Time Tracking</title>
<link href='//fonts.googleapis.com/css?family=Anonymous+Pro|Arvo|Bentham|Cantarell|Josefin+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" media="screen" href="css/ts-screen.css" type="text/css"/>
<!-- Needed for IE, but I'm not sure if I'm going to support IE with this tool. -->
<!--<script type="text/javascript" src="/js/json2.js"></script>-->
<!-- PROD -->
<!--
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
-->
<!-- DEV -->
<script type="text/javascript" src="js/jquery-1.5.js"></script>
<script type="text/javascript" src="js/showdown.js"></script>
<script type="text/javascript" src="js/underscore.js"></script>
<script type="text/javascript" src="js/ICanHaz.js"></script>
<script type="text/javascript" src="js/backbone.js"></script>
<script type="text/javascript" src="js/ts.js"></script>
<script type="text/javascript">
<erl>
out(YArg) ->
Session = ts_api_session:get_session(YArg),
case Session of not_logged_in -> {html, "//not logged in"}; session_expired -> {html, "//session expired"};
_S ->
Username = element(2, Session),
% get the user
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
UserResp = ts_api:get_user(YArg, Username),
{content, _, UserJSON} = lists:keyfind(content, 1, UserResp),
UserRecord = ts_user:lookup(Username),
% get the timelines
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
TimelineResp = ts_api:list_timelines(YArg, Username),
{content, _, TimelineListJSON} = lists:keyfind(content, 1, TimelineResp),
% get the last used timeline if there is one.
SelectedTimeline = case ts_ext_data:get_property(Username, last_timeline) of
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
not_set -> ts_timeline:list(Username, 0, 1);
T -> T
end,
% get entries for this timeline
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
EntriesResp =
ts_api:list_entries(YArg, Username, SelectedTimeline),
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
{content, _, EntryListJSON} = lists:keyfind(content, 1, EntriesResp),
{html, f(
"function bootstrap() {~n"
" var data = {};~n"
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
" data.user = ~s;~n"
" data.timelines = ~s;~n"
" data.initialTimelineId = ~p;~n"
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
" data.entries = ~s;~n"
" return data;~n"
"};",
Bugfixes: session management, new entry creation. * Changed the cookie Path value to allow the cookie to be reused for the domain, not just ths `/ts_api` path. This allows the user to refresh the page and reuse their existing session as long as it is not stale. * Fixed a bug in the `ts_json:ejson_to_record_strict/2` function. It was expecting a record out of `ts_json:ejson_to_record/2` but that function returns a tuple with the record and extended data. Because of the way `ejson_to_record_strict` uses case statements to check for specific values it was still passing the parsed record and data through, but all the checks were being bypassed. * Fixed bugs in the `index.yaws` bootstrap code for the case where the user already has a valid session. * Added `urlRoot` functions to the Backbone model definitions. * Changed the behavior of the new entry creation method. We were trying to fetch just updated attributes from the server for the model we created, but we were pulling all the entries due to the URL backbone was using. This led to the new client-side model having all the previous entry models as attributes. Ideally we would fix the fetch so that only the one model is requested from the server, but we run into a catch-22 because the lookup id is not know by the client as it is generated on the server-side. For now I have changed this behavior so that we still pull all entries, but we pull them into the collection. The collection is then smart enough to update the entries that have changed (namely the new one). The server returns the newly created entry attributes in response to the POST request that the client makes initially, so when I have more time to work on this I plan to do away with the fetch after create, and just pull in the data from the server's response. * Changed formatting.
2013-10-22 15:32:22 +00:00
[lists:flatten(UserJSON), lists:flatten(TimelineListJSON),
SelectedTimeline, lists:flatten(EntryListJSON)])}
end.
</erl>
</script>
<script type="text/html" id="userTemplate">
<div class="fullname">{{name}}</div>
<input class="fullname-input" type="text" value="{{name}}"/></div>
2011-06-01 06:29:48 -05:00
<div class="user-menu">
<div class="username"> - {{id}}</div>
2011-06-01 06:29:48 -05:00
<ul class="user-menu-items">
<li><a href="#">logout</a></li>
<li><a href="#">user info</a></li>
</ul>
</div>
</script>
<script type="text/html" id="timelineTemplate">
<span class="timeline-desc">{{description}}</span>
<input class="timeline-desc-input" type="text" value='{{description}}'/>
<div class="drop-menu">
<div class="timeline-id">(&nbsp;{{id}}&nbsp;)</div>
<input class="timeline-id-input" type="text" value='{{id}}'/>
<ul class="drop-menu-items">
<li class="new-timeline-link"><a href="#">
<img src="img/round_plus_icon_16.png"/>new</a></li>
</ul>
</div>
</script>
<script type="text/html" id="timelineLinkTemplate">
<li class="timeline-link"><a href="#">{{id}}</a></li>
</script>
<script type="text/html" id="entryTemplate">
<div class="mark">
<img class="expand-entry" src="img/br_down_icon_16.png"/>
<img class="collapse-entry" src="img/br_up_icon_16.png"/>
<span>{{mark}}</span>
</div>
<input class="mark-input" type="text" value="{{mark}}"/>
Duration display, time formatting, UI tweaks. Client Behaviour (ts.js) ======================== - Created EntryView.getViewModel: translates model data to view data, specifically synthesizes the start time and duration from the timestamp. - Added nextModel option to EntryView, needed for calculating the entry duration. - Created EntryView.formatStart: given the timestamp, return the start time, in HH:MM format. Code is written for both 24hr and 12hr format, still need to write a selector mechanism. For now, uses 12hr format. - Created EntryView.formatDuration: Get the duration of the entry based on this entry's timestamp and and the next entry's timestamp in a display-able form. If nextModel is `null` or `undefined` it is assumed that `model` is the most recent model and duration is calculated against the current time. - Changed EntryView.render to use getViewModel. - Added 'blur' listeners to the mark and timestamp input fields to close them without persisting the changes. - Created EntryView.update: Refresh the display based on the model using the existing DOM elements. - EntryView.save() now uses EntryView.update() instead of EntryView.render() and no longer includes an implicit close() - EntryView.close() has been split into seperate save() and close() functions, to persist the changes and hide the input dialogs, respectively. - EntryListView.addOne now passes the nextModel to EntryViews is creates. - EntryListView.createNewEntryOnEnter() now clear the new intry input after creating a new entry. - EntryListView.render() now uses a for-structure to traverse the entry collection and passes the nextModel (if there is one) to EntryListView.addOne. Client UI (ts-screen.scss) ========================== - Font size, family, and color adjusted on timeline and user input fields. - Day seperator secondary header colors adjusted. - Mark column width shortened, timestamp and duration columns widened. - Styles added for notes UI Client UI (index.yaws) ====================== - Markup changes needed for getViewModel chanes. - Expanded day seperator.
2011-05-07 22:03:02 -05:00
<div class="timestamp">{{start}}</div>
<input class="timestamp-input" type="text" value="{{timestamp}}"/>
Duration display, time formatting, UI tweaks. Client Behaviour (ts.js) ======================== - Created EntryView.getViewModel: translates model data to view data, specifically synthesizes the start time and duration from the timestamp. - Added nextModel option to EntryView, needed for calculating the entry duration. - Created EntryView.formatStart: given the timestamp, return the start time, in HH:MM format. Code is written for both 24hr and 12hr format, still need to write a selector mechanism. For now, uses 12hr format. - Created EntryView.formatDuration: Get the duration of the entry based on this entry's timestamp and and the next entry's timestamp in a display-able form. If nextModel is `null` or `undefined` it is assumed that `model` is the most recent model and duration is calculated against the current time. - Changed EntryView.render to use getViewModel. - Added 'blur' listeners to the mark and timestamp input fields to close them without persisting the changes. - Created EntryView.update: Refresh the display based on the model using the existing DOM elements. - EntryView.save() now uses EntryView.update() instead of EntryView.render() and no longer includes an implicit close() - EntryView.close() has been split into seperate save() and close() functions, to persist the changes and hide the input dialogs, respectively. - EntryListView.addOne now passes the nextModel to EntryViews is creates. - EntryListView.createNewEntryOnEnter() now clear the new intry input after creating a new entry. - EntryListView.render() now uses a for-structure to traverse the entry collection and passes the nextModel (if there is one) to EntryListView.addOne. Client UI (ts-screen.scss) ========================== - Font size, family, and color adjusted on timeline and user input fields. - Day seperator secondary header colors adjusted. - Mark column width shortened, timestamp and duration columns widened. - Styles added for notes UI Client UI (index.yaws) ====================== - Markup changes needed for getViewModel chanes. - Expanded day seperator.
2011-05-07 22:03:02 -05:00
<div class="duration">{{duration}}</div>
<div class="notes">
<div class="notes-text">{{notes}}</div>
<textarea class="notes-input" rows="10">{{notes}}</textarea>
</div>
</script>
<script type="text/html" id="daySeparatorTemplate">
<div class="day-seperator">
<h4 class="mark">{{separatorLabel}}</h4>
<h5 class="timestamp">start</h5>
<h5 class="duration">duration</h5>
</div>
</script>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<!-- == LOGIN FORM == -->
2011-06-01 06:29:48 -05:00
<div id="login" class="hidden dialog">
<div class="container">
<h2>Login</h2>
<div><label>Username: </label><input type="text" id="username-input"></input></div>
<div><label>Password: </label><input type="password" id="password-input"></input></div>
2011-06-01 06:29:48 -05:00
<div class="button-panel">
<span class='validate-tips'></span>
<div id="login-button" class="dialog-button"><a href="#">login</a></div>
</div>
</div>
</div>
<!-- == NEW TIMELINE FORM == -->
<div id="new-timeline" class="hidden dialog">
<div class="container">
<h2>Create a new timeline:</h2>
<div><label>Timeline ID: </label><input type="text" id="new-timeline-id"></input></div>
<div><label>Description: </label><input type="text" id="new-timeline-desc"></input></div>
<div class="button-panel">
<span class='validate-tips'></span>
2011-06-01 06:29:48 -05:00
<div id="new-timeline-create" class="dialog-button"><a href="#">create</a></div>
<div id="new-timeline-cancel" class="dialog-button"><a href="#">cancel</a></div>
</div>
</div>
</div>
<div id="top">
<!-- == TIMELINE == -->
<div id="timeline"><!-- replaced on login by app -->
<div class="timeline-desc">Login</div>
</div>
<!-- == USER == -->
<div id="user"><!-- replaced on login by app -->
</div>
</div>
<div id="entry-list">
<div id="new-entry">
<input id="new-entry-input" class="mark-input"
placeholder="Start a new task..." type="text" />
</div>
<div id="entries"></div>
</div>
<div class="footer">
Copyright 2011 <a href="http://www.jdb-labs.com"><span class="logo">JDB Labs</span> LLC.</a>
</div>
</body>
</html>