2011-02-10 07:47:35 -06:00
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
2011-03-16 07:39:09 -05:00
|
|
|
<title>TimeStamper - Simple Time Tracking</title>
|
2011-05-16 04:09:37 -05:00
|
|
|
<link href='http://fonts.googleapis.com/css?family=Anonymous+Pro|Arvo|Bentham|Cantarell|Josefin+Sans' rel='stylesheet' type='text/css'>
|
2011-04-27 14:11:54 -05:00
|
|
|
<link rel="stylesheet" media="screen" href="/css/ts-screen.css" type="text/css"/>
|
2011-04-15 13:26:55 -05:00
|
|
|
<!-- Needed for IE, but I'm not sure if I'm going to support IE with this tool. -->
|
2011-03-16 07:39:09 -05:00
|
|
|
<!--<script type="text/javascript" src="/js/json2.js"></script>-->
|
|
|
|
<!-- PROD -->
|
|
|
|
<!--
|
|
|
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
|
|
|
|
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js"></script>
|
|
|
|
-->
|
|
|
|
<!-- DEV -->
|
2011-04-27 14:11:54 -05:00
|
|
|
<script type="text/javascript" src="/js/jquery-1.5.js"></script>
|
2011-03-16 07:39:09 -05:00
|
|
|
|
2011-05-16 04:09:37 -05:00
|
|
|
<script type="text/javascript" src="/js/showdown.js"></script>
|
2011-04-27 14:11:54 -05:00
|
|
|
<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>
|
2011-05-03 12:50:03 -05:00
|
|
|
<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),
|
2011-03-16 07:39:09 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
% get the user
|
|
|
|
{content, _, UserJSON} = ts_api:get_user(YArg, Username),
|
|
|
|
UserRecord = ts_user:lookup(Username),
|
2011-02-10 07:47:35 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
% get the timelines
|
|
|
|
{content, _, TimelineListJSON} = ts_api:list_timelines(YArg, Username),
|
2011-03-16 07:39:09 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
% get the selected timeline
|
|
|
|
SelectedTimeline = case lists:keyfind(
|
|
|
|
selected_timeline, 1, element(8, UserRecord)) of
|
|
|
|
false -> ts_timeline:list(Username, 0, 1);
|
|
|
|
T -> T
|
|
|
|
end,
|
|
|
|
|
|
|
|
% get entries for this timeline
|
|
|
|
{content, _, EntryListJSON} =
|
|
|
|
ts_api:list_entries(YArg, Username, SelectedTimeline),
|
2011-03-16 07:39:09 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
{html, f(
|
|
|
|
"function bootstrap() {~n"
|
|
|
|
" var data = {};~n"
|
|
|
|
" data.user = ~p;~n"
|
|
|
|
" data.timelines = ~p;~n"
|
|
|
|
" data.initialTimelineId = ~p;~n"
|
|
|
|
" data.entries = ~p;~n"
|
|
|
|
" return data;~n"
|
|
|
|
"};",
|
|
|
|
[UserJSON, TimelineListJSON, SelectedTimeline, EntryListJSON])}
|
|
|
|
end.
|
|
|
|
</erl>
|
|
|
|
</script>
|
|
|
|
<script type="text/html" id="userTemplate">
|
|
|
|
<div class="fullname">{{name}}</div>
|
2011-05-09 10:52:21 -05:00
|
|
|
<input class="fullname-input" type="text" value="{{name}}"/></div>
|
2011-06-01 06:29:48 -05:00
|
|
|
<div class="user-menu">
|
2011-05-03 12:50:03 -05:00
|
|
|
<div class="username"> - {{id}}</div>
|
2011-06-01 06:29:48 -05:00
|
|
|
<ul class="user-menu-items">
|
2011-04-27 14:11:54 -05:00
|
|
|
<li><a href="#">logout</a></li>
|
|
|
|
<li><a href="#">user info</a></li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
2011-05-03 12:50:03 -05:00
|
|
|
</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">( {{id}} )</div>
|
|
|
|
<input class="timeline-id-input" type="text" value='{{id}}'/>
|
|
|
|
<ul class="drop-menu-items">
|
|
|
|
</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">
|
2011-05-09 10:52:21 -05:00
|
|
|
<div class="mark">
|
2011-05-16 04:09:37 -05:00
|
|
|
<img class="expand-entry" src="/img/br_down_icon_16.png"/>
|
|
|
|
<img class="collapse-entry" src="/img/br_up_icon_16.png"/>
|
2011-05-09 10:52:21 -05:00
|
|
|
<span>{{mark}}</span>
|
|
|
|
</div>
|
2011-05-03 12:50:03 -05:00
|
|
|
<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>
|
2011-05-03 12:50:03 -05:00
|
|
|
<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>
|
2011-05-16 04:09:37 -05:00
|
|
|
<div class="notes">
|
|
|
|
<div class="notes-text">{{notes}}</div>
|
|
|
|
<textarea class="notes-input" rows="10">{{notes}}</textarea>
|
|
|
|
</div>
|
2011-05-03 12:50:03 -05:00
|
|
|
</script>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body>
|
|
|
|
|
2011-05-06 17:45:56 -05:00
|
|
|
<!-- == LOGIN FORM == -->
|
2011-06-01 06:29:48 -05:00
|
|
|
<div id="login" class="hidden dialog">
|
2011-05-06 17:45:56 -05:00
|
|
|
<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">
|
2011-05-06 17:45:56 -05:00
|
|
|
<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>
|
2011-05-06 17:45:56 -05:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
<div id="top">
|
|
|
|
|
|
|
|
<!-- == TIMELINE == -->
|
2011-05-06 17:45:56 -05:00
|
|
|
<div id="timeline"><!-- replaced on login by app -->
|
|
|
|
<div class="timeline-desc">Login</div>
|
|
|
|
</div>
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
<!-- == USER == -->
|
2011-05-06 17:45:56 -05:00
|
|
|
<div id="user"><!-- replaced on login by app -->
|
|
|
|
</div>
|
2011-03-16 07:39:09 -05:00
|
|
|
|
|
|
|
</div>
|
|
|
|
|
2011-04-27 16:59:33 -05:00
|
|
|
<div id="entry-list">
|
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="day-seperator">
|
|
|
|
<h4 class="mark">Today</h4>
|
|
|
|
<h5 class="timestamp">start</h5>
|
|
|
|
<h5 class="duration">duration</h5>
|
|
|
|
</div>
|
2011-04-27 16:59:33 -05:00
|
|
|
<div id="new-entry">
|
|
|
|
<input id="new-entry-input" class="mark-input"
|
|
|
|
placeholder="Start a new task..." type="text" />
|
|
|
|
</div>
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
<div id="entries"></div>
|
2011-03-16 07:39:09 -05:00
|
|
|
</div>
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
<div class="footer">
|
|
|
|
Copyright 2011 <a href="http://www.jdb-labs.com"><span class="logo">JDB Labs</span> LLC.</a>
|
2011-03-16 07:39:09 -05:00
|
|
|
</div>
|
2011-04-27 14:11:54 -05:00
|
|
|
|
2011-02-10 07:47:35 -06:00
|
|
|
</body>
|
|
|
|
|
|
|
|
</html>
|