2013-10-22 15:32:22 +00:00
|
|
|
/**
|
|
|
|
* # `ts.js`: TimeStamper Web UI Client-side
|
|
|
|
* @author Jonathan Bernard <jdb@jdb-labs.com>
|
|
|
|
**/
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
// TimeStamper namespace
|
|
|
|
var TS = {};
|
2011-03-16 07:39:09 -05:00
|
|
|
|
2011-03-01 18:00:51 -06:00
|
|
|
/* Setup after the document is ready for manipulation. */
|
2011-03-01 08:23:51 -06:00
|
|
|
$(document).ready(function(){
|
2011-02-24 07:29:30 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
// ======== DEFINE MODELS ========//
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* Entry model.
|
|
|
|
* Attributes
|
2013-10-22 15:32:22 +00:00
|
|
|
* - user_id
|
|
|
|
* - timeline_id
|
2011-04-15 13:26:55 -05:00
|
|
|
* - id
|
|
|
|
* - mark
|
2013-10-22 15:32:22 +00:00
|
|
|
* - uuid
|
2011-04-15 13:26:55 -05:00
|
|
|
* - notes
|
2011-06-17 10:58:01 -05:00
|
|
|
* - timestamp
|
2011-04-15 13:26:55 -05:00
|
|
|
*/
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.EntryModel = Backbone.Model.extend({
|
2011-03-08 18:02:33 -06:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
initialize: function(attrs, options) {
|
|
|
|
_.bindAll(this, 'get', 'set', 'urlRoot'); },
|
|
|
|
|
2011-06-17 10:58:01 -05:00
|
|
|
get: function(attribute) {
|
|
|
|
if (attribute == "timestamp") {
|
|
|
|
if (!this.timestampDate) {
|
|
|
|
this.timestampDate = new Date(
|
2013-10-22 15:32:22 +00:00
|
|
|
Backbone.Model.prototype.get.call(this, attribute)); }
|
|
|
|
return this.timestampDate; }
|
|
|
|
else {
|
|
|
|
return Backbone.Model.prototype.get.call(this, attribute); } },
|
2011-06-17 10:58:01 -05:00
|
|
|
|
|
|
|
set: function(attributes, options) {
|
|
|
|
var attrsToSet = {}
|
|
|
|
_.each(attributes, function(val, key) {
|
|
|
|
if (key == "timestamp") {
|
|
|
|
if (val instanceof Date) {
|
|
|
|
this.timestampDate = val;
|
2013-10-22 15:32:22 +00:00
|
|
|
attrsToSet.timestamp = dateToJSON(val); }
|
|
|
|
else {
|
2011-06-17 10:58:01 -05:00
|
|
|
this.timestampDate = new Date(val);
|
2013-10-22 15:32:22 +00:00
|
|
|
attrsToSet.timestamp = dateToJSON(this.timestampDate); } }
|
|
|
|
else { attrsToSet[key] = val; } });
|
|
|
|
|
|
|
|
return Backbone.Model.prototype.set.call(
|
|
|
|
this, attrsToSet, options); },
|
2011-06-17 10:58:01 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
urlRoot: function() { return '/ts_api/entries/' + this.get('user_id') +
|
|
|
|
'/' + this.get('timeline_id') + '/'; } });
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* Timeline model.
|
|
|
|
* Attributes:
|
2013-10-22 15:32:22 +00:00
|
|
|
* - user_id
|
2011-04-15 13:26:55 -05:00
|
|
|
* - id
|
2011-05-03 12:50:03 -05:00
|
|
|
* - description
|
2011-04-15 13:26:55 -05:00
|
|
|
* - created
|
|
|
|
*/
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.TimelineModel = Backbone.Model.extend({
|
2013-10-22 15:32:22 +00:00
|
|
|
urlRoot: function() {
|
|
|
|
return '/ts_api/timelines/' + this.get('user_id') + '/'; },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
initialze: function(attrs, options) { _.bindAll(this, 'urlRoot'); } });
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* User model.
|
|
|
|
* Attributes:
|
2013-10-22 15:32:22 +00:00
|
|
|
* - id
|
|
|
|
* - name
|
2011-04-15 13:26:55 -05:00
|
|
|
* - email
|
|
|
|
* - join_date
|
|
|
|
*/
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.UserModel = Backbone.Model.extend({
|
2011-04-27 14:11:54 -05:00
|
|
|
url: function() { return '/ts_api/users/' + this.get('id'); },
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
initialize: function(attrs, options) { _.bindAll(this, 'url'); } });
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
TS.EntryList = Backbone.Collection.extend({
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.EntryModel,
|
2011-04-15 13:26:55 -05:00
|
|
|
|
|
|
|
comparator: function(entry) { return entry.get('timestamp'); },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
initialize: function(model, options) {
|
2011-06-16 17:50:47 -05:00
|
|
|
if (options.timelineModel == undefined) {
|
2013-10-22 15:32:22 +00:00
|
|
|
throw "Cannot create an EntryList without a " +
|
|
|
|
"TimelineModel reference." }
|
|
|
|
else { this.timelineModel = options.timelineModel; }
|
|
|
|
|
|
|
|
_.bindAll(this, "url", "create"); },
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
url: function() {
|
2011-06-16 17:50:47 -05:00
|
|
|
return "/ts_api/entries/" + this.timelineModel.get('user_id') + "/"
|
2013-10-22 15:32:22 +00:00
|
|
|
+ this.timelineModel.get('id'); } });
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
TS.TimelineList = Backbone.Collection.extend({
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.TimelineModel,
|
|
|
|
|
|
|
|
initialize: function(models, options) {
|
|
|
|
if (options.user == undefined) {
|
|
|
|
throw "Cannot create a TimelineList without a UserModel reference.";
|
|
|
|
} else { this.user = options.user; }
|
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
_.bindAll(this, 'url'); },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
comparator: function(timeline) { return timeline.get('id'); },
|
2011-04-27 16:59:33 -05:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
url: function() {
|
2013-10-22 15:32:22 +00:00
|
|
|
return "/ts_api/timelines/" + this.user.get('id'); } });
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
// ======== DEFINE VIEWS ========//
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
/* Entry view
|
|
|
|
*/
|
|
|
|
TS.EntryView = Backbone.View.extend({
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.EntryModel,
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
className: 'entry',
|
|
|
|
|
2011-05-16 04:09:37 -05:00
|
|
|
notesCache: false,
|
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
events: {
|
2011-05-16 04:09:37 -05:00
|
|
|
"click img.expand-entry" : "showNotes",
|
|
|
|
"click img.collapse-entry" : "hideNotes",
|
2011-04-15 13:26:55 -05:00
|
|
|
"dblclick div.mark" : "editMark",
|
|
|
|
"dblclick div.timestamp" : "editTimestamp",
|
2011-05-16 04:09:37 -05:00
|
|
|
"dblclick div.notes" : "editNotes",
|
2013-10-11 20:06:31 +00:00
|
|
|
"keypress .mark-input" : "saveOnEnter",
|
|
|
|
"keypress .timestamp-input" : "saveOnEnter",
|
|
|
|
"keypress .notes-input" : "saveOnCtrlEnter",
|
|
|
|
"blur .mark-input" : "save",
|
|
|
|
"blur .timestamp-input" : "save",
|
2013-10-22 15:32:22 +00:00
|
|
|
"blur .notes-input" : "save" },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
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 21:31:30 -05:00
|
|
|
initialize: function(options) {
|
2013-10-11 20:06:31 +00:00
|
|
|
_.bindAll(this, 'render', 'editTImestamp', 'editMark', 'update',
|
|
|
|
'saveOnEnter', 'saveOnCtrlEnter', 'getViewModel',
|
|
|
|
'renderNotes', 'showNotes', 'hideNotes', 'save');
|
2011-05-16 04:09:37 -05:00
|
|
|
|
|
|
|
this.markdownConverter = options.markdownConverter;
|
|
|
|
|
|
|
|
this.model.bind('change', this.update);
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.view = this;
|
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 21:31:30 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
this.nextModel = options.nextModel; },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
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
|
|
|
/**
|
|
|
|
* Refresh the display based on the model replacing the existing
|
|
|
|
* HTML content. Add new `blur` listeners to the input fields.
|
|
|
|
*/
|
2011-04-15 13:26:55 -05:00
|
|
|
render: function() {
|
2011-05-16 04:09:37 -05:00
|
|
|
// render the HTML
|
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 21:31:30 -05:00
|
|
|
$(this.el).html(ich.entryTemplate(this.getViewModel()));
|
2011-05-16 04:09:37 -05:00
|
|
|
|
|
|
|
// invalidate the notes display cache
|
|
|
|
this.notesCache = false;
|
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-03-01 08:23:51 -06:00
|
|
|
|
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
|
|
|
/**
|
|
|
|
* Refresh the display based on the model using the existing DOM
|
|
|
|
* elements.
|
|
|
|
*/
|
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 21:31:30 -05:00
|
|
|
update: function() {
|
|
|
|
var data = this.getViewModel();
|
2011-05-09 10:52:21 -05:00
|
|
|
this.$('.mark span').text(data.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 21:31:30 -05:00
|
|
|
this.$('.mark-input').val(data.mark);
|
|
|
|
this.$('.timestamp').text(data.start);
|
|
|
|
this.$('.timestamp-input').val(data.timestamp);
|
|
|
|
this.$('.duration').text(data.duration);
|
2011-05-16 04:09:37 -05:00
|
|
|
this.$('.notes-text').html(this.renderNotes(data.notes));
|
|
|
|
this.$('.notes-input').val(data.notes);
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
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 21:31:30 -05:00
|
|
|
|
2011-05-16 04:09:37 -05:00
|
|
|
renderNotes: function(source) {
|
|
|
|
if (!this.notesCache) {
|
2013-10-11 20:06:31 +00:00
|
|
|
this.notesCache = this.markdownConverter.makeHtml(source); }
|
2011-05-16 04:09:37 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
return this.notesCache },
|
2011-05-16 04:09:37 -05:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editMark: function() {
|
|
|
|
$(this.el).addClass('edit-mark');
|
|
|
|
this.$('.mark-input').focus();
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editTimestamp: function() {
|
|
|
|
$(this.el).addClass('edit-timestamp');
|
|
|
|
this.$('timestamp-input').focus();
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-03-01 18:00:51 -06:00
|
|
|
|
2011-05-16 04:09:37 -05:00
|
|
|
editNotes: function() {
|
|
|
|
// invalidate notes HTML cache
|
|
|
|
this.notesCache = false;
|
|
|
|
|
|
|
|
// show notes textarea, hide display
|
|
|
|
$(this.el).addClass('edit-notes');
|
|
|
|
|
|
|
|
// focus input
|
|
|
|
this.$('.notes-input').focus();
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-05-16 04:09:37 -05:00
|
|
|
|
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
|
|
|
/**
|
|
|
|
* Translate the model data into a form suitable to be displayed.
|
|
|
|
* @return a map including display-able `start` and `duration` values.
|
|
|
|
*/
|
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 21:31:30 -05:00
|
|
|
getViewModel: function() {
|
|
|
|
var data = this.model.toJSON();
|
|
|
|
|
|
|
|
// create start and duration values
|
|
|
|
var tsDate = new Date(data.timestamp);
|
|
|
|
data.start = this.formatStart(tsDate);
|
|
|
|
data.duration = this.formatDuration(this.model, this.nextModel);
|
2011-05-16 04:09:37 -05:00
|
|
|
data.notes = data.notes ? data.notes : '*No notes for this entry.*';
|
2013-10-22 15:32:22 +00:00
|
|
|
return data; },
|
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 21:31:30 -05:00
|
|
|
|
2013-10-11 20:06:31 +00:00
|
|
|
/** Save and close editable fields. */
|
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 21:31:30 -05:00
|
|
|
save: function() {
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.save({
|
|
|
|
mark: this.$('.mark-input').val(),
|
2011-06-17 10:58:01 -05:00
|
|
|
timestamp: new Date(this.$('.timestamp-input').val()),
|
2011-05-16 04:09:37 -05:00
|
|
|
notes: this.$('.notes-input').val()});
|
2013-10-11 20:06:31 +00:00
|
|
|
|
|
|
|
this.$('.notes-text').html(this.renderNotes(this.model.get('notes')));
|
2013-10-22 15:32:22 +00:00
|
|
|
$(this.el).removeClass('edit-mark edit-timestamp edit-notes'); },
|
2011-03-03 17:05:30 -06:00
|
|
|
|
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
|
|
|
/** Event handler for keypresses on entry input fields. */
|
2013-10-22 15:32:22 +00:00
|
|
|
saveOnEnter: function(e) { if(e.keyCode == 13) { this.save(); } },
|
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 21:31:30 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
saveOnCtrlEnter: function(e) { if (e.keyCode == 10) { this.save(); } },
|
2011-05-16 04:09:37 -05:00
|
|
|
|
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
|
|
|
/**
|
|
|
|
* Get the display-able start time from the entry timestamp.
|
|
|
|
* @param startDate a Date object, the entry timestamp.
|
|
|
|
* @return display-able start time in HH:MM format.
|
|
|
|
*/
|
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 21:31:30 -05:00
|
|
|
formatStart: function(startDate) {
|
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
|
|
|
/* Code is written for both 24hr and 12hr formats. I still need to
|
|
|
|
* create a mechanism for selecting between them. For now, use the
|
|
|
|
* 12hr format. */
|
|
|
|
|
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 21:31:30 -05:00
|
|
|
// 24 hour
|
|
|
|
// return startDate.getHours() + ":" + startDate.getMinutes();
|
|
|
|
|
|
|
|
// 12 hour
|
|
|
|
var hour = startDate.getHours() % 12;
|
|
|
|
return (hour == 0 ? 12 : hour) + ":" + startDate.getMinutes() +
|
2013-10-22 15:32:22 +00:00
|
|
|
" " + (startDate.getHours() > 11 ? "pm" : "am"); },
|
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 21:31:30 -05:00
|
|
|
|
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
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* @param model EntryModel representing this entry.
|
|
|
|
* @param nextModel EntryModel representing the next entry.
|
|
|
|
* @return the duration between model and nextModel, formatted for
|
|
|
|
* display: `Xd Yhr Zm`. */
|
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 21:31:30 -05:00
|
|
|
formatDuration: function(model, nextModel) {
|
2011-06-17 10:58:01 -05:00
|
|
|
var d1 = model.get('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 21:31:30 -05:00
|
|
|
var d2, diff;
|
|
|
|
var day, hr, min;
|
|
|
|
|
|
|
|
// if no next model, assume it's an onoing task
|
2011-06-17 10:58:01 -05:00
|
|
|
if (nextModel) { d2 = nextModel.get('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 21:31:30 -05:00
|
|
|
else { d2 = new Date(); }
|
|
|
|
|
|
|
|
diff= d2.getTime() - d1.getTime();
|
|
|
|
day = Math.floor(diff / 86400000); // milliseconds in a day
|
|
|
|
diff %= 86400000;
|
|
|
|
|
|
|
|
hr = Math.floor(diff / 3600000); // millis in an hour
|
|
|
|
diff %= 3600000;
|
|
|
|
|
|
|
|
min = Math.floor(diff / 60000); // millis in a minute
|
|
|
|
|
|
|
|
return (day > 0 ? day + "d " : "") +
|
|
|
|
(hr > 0 ? hr + "hr " : "") +
|
2013-10-22 15:32:22 +00:00
|
|
|
min + "m "; },
|
2011-05-09 10:52:21 -05:00
|
|
|
|
2011-05-16 04:09:37 -05:00
|
|
|
showNotes: function() {
|
|
|
|
if (!this.notesCache) {
|
|
|
|
this.$('.notes-text').html(
|
2013-10-11 20:06:31 +00:00
|
|
|
this.renderNotes(this.model.get('notes'))); }
|
2011-05-16 04:09:37 -05:00
|
|
|
|
|
|
|
this.$('.notes').slideDown();
|
2013-10-22 15:32:22 +00:00
|
|
|
$(this.el).addClass('show-notes'); },
|
2011-05-16 04:09:37 -05:00
|
|
|
|
|
|
|
hideNotes: function() {
|
|
|
|
this.$('.notes').slideUp();
|
2013-10-22 15:32:22 +00:00
|
|
|
$(this.el).removeClass('show-notes'); } });
|
2011-03-01 08:23:51 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
TS.EntryListView = Backbone.View.extend({
|
|
|
|
|
2013-10-24 20:42:53 +00:00
|
|
|
el: $("#entry-list")[0],
|
2011-04-27 16:59:33 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
events: { "keypress #new-entry-input" : "createNewEntryOnEnter" },
|
2011-04-20 09:40:54 -05:00
|
|
|
|
|
|
|
initialize: function() {
|
2011-05-16 04:09:37 -05:00
|
|
|
_.bindAll(this, 'addOne', 'createNewEntry', 'render', 'renderOne');
|
2011-04-20 09:40:54 -05:00
|
|
|
this.collection.bind('add', this.addOne);
|
|
|
|
this.collection.bind('refresh', this.render);
|
|
|
|
this.collection.view = this;
|
2011-04-27 16:59:33 -05:00
|
|
|
this.entryContainer = this.$("#entries")
|
2013-10-22 15:32:22 +00:00
|
|
|
this.markdownConverter = new Showdown.converter(); },
|
2011-05-16 04:09:37 -05:00
|
|
|
|
|
|
|
addOne: function(entry) {
|
|
|
|
var lastEntry = this.collection.at(this.collection.length - 2);
|
|
|
|
lastEntry.view.nextModel = entry;
|
|
|
|
lastEntry.view.update();
|
2013-10-24 20:42:53 +00:00
|
|
|
this.renderOne(entry, null);
|
|
|
|
$(".entry.current").removeClass("current");
|
|
|
|
$(entry.view.el).addClass("current"); },
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-16 04:09:37 -05:00
|
|
|
renderOne: function(entry, nextEntry) {
|
2011-06-16 17:50:47 -05:00
|
|
|
// exclude if any exclusion RegExps match
|
|
|
|
var excluded = _.any(this.entryExclusions,
|
|
|
|
function(exclusion) { return exclusion.test(entry.get("mark"))});
|
|
|
|
|
|
|
|
// create the view if it does not exist
|
2011-05-16 04:09:37 -05:00
|
|
|
if (!entry.view) { new TS.EntryView(
|
|
|
|
{model: entry, markdownConverter: this.markdownConverter}); }
|
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 21:31:30 -05:00
|
|
|
entry.view.nextModel = nextEntry
|
2011-06-16 17:50:47 -05:00
|
|
|
|
|
|
|
// render the element
|
|
|
|
var el = entry.view.render().el;
|
|
|
|
|
2011-06-17 16:02:26 -05:00
|
|
|
// add it to the container after the topmost separator ("Today")
|
|
|
|
this.topSeparator.after(el);
|
2011-06-16 17:50:47 -05:00
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// If this entry and the next entry are not on the same day, put a
|
|
|
|
// day separator between them.
|
|
|
|
var nextDay = nextEntry ? nextEntry.get("timestamp") : new Date();
|
|
|
|
if (entry.get("timestamp").getDate() != nextDay.getDate()) {
|
|
|
|
this.topSeparator.after(ich.daySeparatorTemplate(
|
|
|
|
{separatorLabel: this.formatDaySeparator(
|
|
|
|
TS.app.currentDay, entry.get("timestamp")) })); }
|
|
|
|
|
2011-06-16 17:50:47 -05:00
|
|
|
// hide it if excluded
|
|
|
|
if (excluded) {
|
|
|
|
$(el).fadeOut('slow');
|
2013-10-22 15:32:22 +00:00
|
|
|
$(el).addClass('excluded'); } },
|
2011-04-27 16:59:33 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
createNewEntryOnEnter: function(e) {
|
|
|
|
|
|
|
|
if (e.keyCode == 13) {
|
|
|
|
|
|
|
|
// grab the mark data
|
|
|
|
var entryMark = this.$("#new-entry-input").val();
|
|
|
|
|
|
|
|
// create the mark. Immediately fetch to get server-side timestamp
|
2013-10-22 16:46:34 +00:00
|
|
|
this.collection.create(
|
|
|
|
{mark: entryMark,
|
|
|
|
notes: '',
|
|
|
|
timestamp: new Date()},
|
|
|
|
{wait: true,
|
|
|
|
success: function(model, resp, options) {
|
|
|
|
model.set(resp); }});
|
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 21:31:30 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
// clear the input for the next entry
|
|
|
|
this.$("#new-entry-input").val(""); } },
|
2011-04-20 09:40:54 -05:00
|
|
|
|
|
|
|
render: function() {
|
2011-06-16 17:50:47 -05:00
|
|
|
|
|
|
|
// get our user exclusions
|
|
|
|
var userExclusions = TS.app.user.model.get("entry_exclusions") || [];
|
|
|
|
|
|
|
|
// get the current timeline exclusions
|
|
|
|
var timelineExclusions =
|
|
|
|
this.collection.timelineModel.get("entry_exclusions") || [];
|
|
|
|
|
|
|
|
// turn them into RegExps and store them
|
|
|
|
this.entryExclusions = _.map(
|
|
|
|
userExclusions.concat(timelineExclusions),
|
|
|
|
function(exclusion) { return new RegExp(exclusion)} );
|
|
|
|
|
2011-06-17 10:58:01 -05:00
|
|
|
// clear existing elements in the view container
|
2011-04-27 16:59:33 -05:00
|
|
|
this.entryContainer.empty();
|
2011-06-17 10:58:01 -05:00
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// add the top-most day separator; should always be "Today"
|
2011-06-17 16:02:26 -05:00
|
|
|
this.topSeparator = ich.daySeparatorTemplate({
|
2013-10-24 14:55:08 +00:00
|
|
|
separatorLabel: this.formatDaySeparator(
|
|
|
|
TS.app.currentDay, new Date()) });
|
2011-06-17 16:02:26 -05:00
|
|
|
this.entryContainer.prepend(this.topSeparator);
|
2011-06-17 10:58:01 -05:00
|
|
|
|
|
|
|
// iterate through the collection and render the elements.
|
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 21:31:30 -05:00
|
|
|
for (var i = 0, len = this.collection.length; i < len; i++) {
|
|
|
|
var entry = this.collection.at(i);
|
|
|
|
var nextEntry = (i + 1 < len ? this.collection.at(i + 1) : null);
|
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
this.renderOne(entry, nextEntry); } },
|
2011-06-17 16:02:26 -05:00
|
|
|
|
|
|
|
formatDaySeparator: function(today, labelDay) {
|
|
|
|
|
|
|
|
var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
|
|
|
|
'Friday', 'Saturday'];
|
|
|
|
var months = ['January', 'February', 'March', 'April', 'May',
|
|
|
|
'June', 'July', 'August', 'September', 'October',
|
|
|
|
'November', 'December'];
|
|
|
|
|
|
|
|
var yearDiff = today.getFullYear() - labelDay.getFullYear();
|
|
|
|
var monthDiff = today.getMonth() - labelDay.getMonth();
|
|
|
|
var dayDiff = today.getDate() - labelDay.getDate();
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// more than a calendar year old: Weekday, Month Date, Year
|
2011-06-17 16:02:26 -05:00
|
|
|
if (yearDiff > 0) {
|
|
|
|
|
|
|
|
return days[labelDay.getDay()] + ", " +
|
|
|
|
months[labelDay.getMonth()] + " " + labelDay.getDate() +
|
|
|
|
", " + labelDay.getFullYear(); }
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// same calendar year, more than a week ago: Weekday, Month Date
|
2011-06-17 16:02:26 -05:00
|
|
|
else if (monthDiff > 0 || dayDiff > 7) {
|
|
|
|
|
|
|
|
return days[labelDay.getDay()] + ", " +
|
|
|
|
months[labelDay.getMonth()] + " " + labelDay.getDate(); }
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// less than a week ago, more than yesterday, Last Weekday
|
2011-06-17 16:02:26 -05:00
|
|
|
else if (dayDiff > 1) {
|
|
|
|
return "Last " + days[labelDay.getDay()]; }
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// Yesterday
|
2011-06-17 16:02:26 -05:00
|
|
|
else if (dayDiff == 1) { return "Yesterday"; }
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// Today
|
2013-10-22 15:32:22 +00:00
|
|
|
else if (dayDiff == 0) { return "Today"; } } });
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
TS.TimelineListView = Backbone.View.extend({
|
2013-10-24 20:42:53 +00:00
|
|
|
el: $("#timeline")[0],
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
collection: TS.TimelineList,
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
events: {
|
|
|
|
"dblclick .timeline-id" : "editId",
|
|
|
|
"dblclick .timeline-desc" : "editDesc",
|
2013-10-11 20:06:31 +00:00
|
|
|
"keypress .timeline-id-input" : "saveOnEnter",
|
|
|
|
"keypress .timeline-desc-input" : "saveOnEnter",
|
2013-10-22 15:32:22 +00:00
|
|
|
"click .new-timeline-link" : "showNewTimelineDialog" },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
initialize: function(options) {
|
|
|
|
_.bindAll(this, 'render', 'renderOne', 'editId',
|
2013-10-11 20:06:31 +00:00
|
|
|
'editDesc', 'saveOnEnter', 'save');
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
if (options.initialTimelineId == undefined) {
|
2013-10-22 15:32:22 +00:00
|
|
|
throw "Can not create a TimelineListView without an " +
|
|
|
|
"initial timeline." }
|
|
|
|
else {
|
|
|
|
this.selectedModel =
|
|
|
|
this.collection.get(options.initialTimelineId); }
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
this.collection.bind('add', this.renderOne);
|
2013-10-22 15:32:22 +00:00
|
|
|
this.collection.bind('refresh', this.render); },
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
renderOne: function(timeline) {
|
|
|
|
this.$('.drop-menu-items').append(
|
2013-10-22 15:32:22 +00:00
|
|
|
ich.timelineLinkTemplate(timeline.toJSON())); },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
render: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
// render the basic template
|
2011-06-16 17:50:47 -05:00
|
|
|
$(this.el).html(ich.timelineTemplate(this.selectedModel.toJSON()));
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
// render the selection list
|
2013-10-22 15:32:22 +00:00
|
|
|
_.each(this.collection.without([this.selectedModel]), this.renderOne); },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editId: function() {
|
|
|
|
$(this.el).addClass('edit-id');
|
|
|
|
this.$('.timeline-id-input').focus();
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editDesc: function() {
|
|
|
|
$(this.el).addClass('edit-desc');
|
|
|
|
this.$('.timeline-desc-input').focus();
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-04-15 13:26:55 -05:00
|
|
|
|
2013-10-11 20:06:31 +00:00
|
|
|
save: function() {
|
2011-06-16 17:50:47 -05:00
|
|
|
this.selectedModel.save({
|
2011-05-03 12:50:03 -05:00
|
|
|
id: this.$('.timeline-id-input').val(),
|
|
|
|
description: this.$('.timeline-desc-input').val()});
|
|
|
|
$(this.el).removeClass('edit-id edit-desc');
|
2013-10-22 15:32:22 +00:00
|
|
|
this.render(); },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
showNewTimelineDialog: function() { TS.app.newTimelineDialog.show(); },
|
2011-06-07 08:34:20 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
saveOnEnter: function(e) { if (e.keyCode == 13) { this.save(); } } });
|
2011-04-27 16:59:33 -05:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
TS.UserView = Backbone.View.extend({
|
|
|
|
|
2013-10-24 20:42:53 +00:00
|
|
|
el: $("#user")[0],
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-20 09:40:54 -05:00
|
|
|
model: TS.UserModel,
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
events: {
|
|
|
|
'dblclick .fullname': 'editFullname',
|
2013-10-22 15:32:22 +00:00
|
|
|
'keypress .fullname-input': 'saveOnEnter' },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
initialize: function() {
|
2013-10-11 20:06:31 +00:00
|
|
|
_.bindAll(this, 'render', 'save', 'editFullname', 'saveOnEnter');
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.bind('change', this.render);
|
2013-10-22 15:32:22 +00:00
|
|
|
this.model.view = this; },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
render: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
$(this.el).html(ich.userTemplate(this.model.toJSON()));
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-15 13:26:55 -05:00
|
|
|
editFullname: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
$(this.el).addClass('edit-fullname');
|
2011-04-15 13:26:55 -05:00
|
|
|
this.$('.fullname-input').focus();
|
2013-10-22 15:32:22 +00:00
|
|
|
return this; },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2013-10-11 20:06:31 +00:00
|
|
|
save: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
this.model.set({name: this.$('fullname-input').val()});
|
2011-04-15 13:26:55 -05:00
|
|
|
this.model.save();
|
2013-10-22 15:32:22 +00:00
|
|
|
$(this.el).removeClass('edit-fullname'); },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
saveOnEnter: function(e) { if (e.keyCode == 13) this.save(); } });
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-04-27 14:11:54 -05:00
|
|
|
TS.AppView = Backbone.View.extend({
|
|
|
|
|
2013-10-24 20:42:53 +00:00
|
|
|
el: $("body")[0],
|
2011-04-27 14:11:54 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
events: { 'click #timeline .drop-menu-items a': 'selectTimeline' },
|
2011-04-27 14:11:54 -05:00
|
|
|
|
|
|
|
initialize: function() {
|
2011-05-03 12:50:03 -05:00
|
|
|
|
2011-06-10 11:49:45 -05:00
|
|
|
_.bindAll(this, 'initializeViews', 'loadInitialData',
|
2013-10-24 14:55:08 +00:00
|
|
|
'periodicRefresh', 'selectTimeline');
|
2011-05-03 12:50:03 -05:00
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
TS.app = this;
|
|
|
|
TS.app.currentDay = new Date();
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
// create the login dialog
|
|
|
|
this.loginDialog = new TS.LoginView
|
|
|
|
|
2011-06-01 06:29:48 -05:00
|
|
|
// initialize data, either from boostrapped data, or via user login
|
2011-05-03 12:50:03 -05:00
|
|
|
if (window.bootstrap) { this.initializeData(window.bootstrap()) }
|
|
|
|
else {
|
|
|
|
// this is async (waiting for user input)
|
|
|
|
this.loginDialog.authenticate(function() {
|
2013-10-24 14:55:08 +00:00
|
|
|
TS.app.initializeData(TS.app.loadInitialData())}); }
|
|
|
|
|
|
|
|
// Schedule our update function.
|
|
|
|
setInterval(this.periodicRefresh, 60000); },
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
initializeData: function(data) {
|
|
|
|
|
|
|
|
// create user data
|
|
|
|
this.user = {};
|
|
|
|
this.user.model = new TS.UserModel(data.user);
|
|
|
|
this.user.view = new TS.UserView({model: this.user.model});
|
|
|
|
|
|
|
|
// create timeline models from the bootstrapped data
|
|
|
|
var tlModels = _.map(data.timelines, function(timeline) {
|
2013-10-22 15:32:22 +00:00
|
|
|
return new TS.TimelineModel(timeline); });
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
// create the timeline list collection
|
|
|
|
this.timelines = {};
|
|
|
|
this.timelines.collection = new TS.TimelineList(
|
|
|
|
tlModels, {user: this.user.model});
|
|
|
|
this.timelines.view = new TS.TimelineListView(
|
|
|
|
{collection: this.timelines.collection,
|
|
|
|
initialTimelineId: data.initialTimelineId});
|
|
|
|
|
2011-06-07 08:34:20 -05:00
|
|
|
// create the new timeline dialog
|
|
|
|
this.newTimelineDialog = new TS.NewTimelineView(
|
|
|
|
{timelineCollection: this.timelines.collection});
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
// create entry models from the bootstrapped data
|
|
|
|
var entryModels = _.map(data.entries, function(entry) {
|
2013-10-22 15:32:22 +00:00
|
|
|
return new TS.EntryModel(entry); });
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
// create the entry collection
|
|
|
|
this.entries = {};
|
|
|
|
this.entries.collection = new TS.EntryList(entryModels,
|
2011-06-16 17:50:47 -05:00
|
|
|
{timelineModel: this.timelines.view.selectedModel});
|
2011-05-03 12:50:03 -05:00
|
|
|
this.entries.view = new TS.EntryListView(
|
|
|
|
{collection: this.entries.collection});
|
|
|
|
|
|
|
|
// render views
|
|
|
|
this.user.view.render();
|
|
|
|
this.timelines.view.render();
|
2013-10-22 15:32:22 +00:00
|
|
|
this.entries.view.render(); },
|
2011-04-27 14:11:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
loadInitialData: function() {
|
|
|
|
// assume we are authenticated
|
|
|
|
|
2011-05-06 17:45:56 -05:00
|
|
|
var username = $("#username-input").val(); // hackish
|
2011-05-03 12:50:03 -05:00
|
|
|
var data = jQuery.parseJSON($.ajax({
|
|
|
|
url: '/ts_api/app/user_summary/' + username,
|
|
|
|
async: false}).responseText);
|
|
|
|
|
2011-06-15 16:50:38 -05:00
|
|
|
// look for the last used timeline, default to first timeline
|
|
|
|
data.initialTimelineId =
|
|
|
|
data.user.last_timeline || data.timelines[0].id
|
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
data.entries = jQuery.parseJSON($.ajax({
|
|
|
|
url: '/ts_api/entries/' + username + '/' +
|
|
|
|
data.initialTimelineId,
|
|
|
|
async: false}).responseText);
|
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
return data; },
|
2011-06-10 11:49:45 -05:00
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
periodicRefresh: function() {
|
|
|
|
|
|
|
|
var now = new Date();
|
2013-11-04 03:55:41 +00:00
|
|
|
var models = this.entries.collection.models;
|
2013-10-24 14:55:08 +00:00
|
|
|
|
|
|
|
if (this.currentDay.getDate() != now.getDate()) {
|
2013-11-04 03:55:41 +00:00
|
|
|
// If the user is editing any one of the models, don't rerender
|
|
|
|
if (_.any(models, function(model) {
|
|
|
|
return $(model.view.el).hasClass('editing') })) {
|
|
|
|
return }
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// It's a new day! Rerender our whole list.
|
2013-11-04 03:55:41 +00:00
|
|
|
else { this.entries.render(); } }
|
2013-10-24 14:55:08 +00:00
|
|
|
else {
|
2013-11-04 03:55:41 +00:00
|
|
|
var currentModel = models[models.length - 1]
|
|
|
|
|
|
|
|
if ($(currentModel.view.el).hasClass('editing')) { return }
|
|
|
|
|
2013-10-24 14:55:08 +00:00
|
|
|
// Refresh our latest entry view so the duration is up to date.
|
2013-11-04 03:55:41 +00:00
|
|
|
else { currentModelview.render(); } } },
|
2013-10-24 14:55:08 +00:00
|
|
|
|
2011-06-10 11:49:45 -05:00
|
|
|
selectTimeline: function(e) {
|
|
|
|
if (e) {
|
|
|
|
// get the timeline model
|
|
|
|
var tl = this.timelines.collection.get(e.srcElement.text);
|
|
|
|
|
|
|
|
// set the on the timeline view
|
2011-06-16 17:50:47 -05:00
|
|
|
this.timelines.view.selectedModel = tl;
|
2011-06-10 11:49:45 -05:00
|
|
|
|
|
|
|
// set the timeline on the EntryList
|
2011-06-16 17:50:47 -05:00
|
|
|
this.entries.collection.timelineModel = tl;
|
2011-06-10 11:49:45 -05:00
|
|
|
|
2011-06-15 16:50:38 -05:00
|
|
|
// update the last_timeline field of the user model
|
2011-06-15 18:31:53 -05:00
|
|
|
this.user.model.set({last_timeline: tl.get('id')});
|
2011-06-15 16:50:38 -05:00
|
|
|
this.user.model.save();
|
|
|
|
|
2013-10-22 16:46:34 +00:00
|
|
|
// re-render the TimelineListView
|
2011-06-10 11:49:45 -05:00
|
|
|
this.timelines.view.render();
|
|
|
|
|
2013-10-22 16:46:34 +00:00
|
|
|
// fetch the new EntryList records
|
2013-10-22 15:32:22 +00:00
|
|
|
this.entries.collection.fetch() } } });
|
2011-04-27 14:11:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
TS.LoginView = Backbone.View.extend({
|
2013-10-24 20:42:53 +00:00
|
|
|
el: $("#login")[0],
|
2011-05-06 17:45:56 -05:00
|
|
|
|
|
|
|
events: {
|
|
|
|
"keypress #password-input" : "loginOnEnter",
|
2013-10-22 15:32:22 +00:00
|
|
|
"click #login-button a" : "doLogin" },
|
2011-04-27 14:11:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
initialize: function() {
|
2011-05-06 17:45:56 -05:00
|
|
|
_.bindAll(this, 'authenticate', 'doLogin', 'hide', 'loginOnEnter',
|
2013-10-22 15:32:22 +00:00
|
|
|
'show'); },
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
action: function() {},
|
2011-03-08 18:02:33 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
authenticate: function(nextAction) {
|
|
|
|
this.action = nextAction;
|
2013-10-22 15:32:22 +00:00
|
|
|
this.show(); },
|
2011-03-07 16:43:40 -06:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
doLogin: function(){
|
|
|
|
var viewThis = this;
|
2011-05-06 17:45:56 -05:00
|
|
|
var name = this.$("#username-input");
|
|
|
|
var pwd = $("#password-input");
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
// call the API via AJAX
|
|
|
|
$.ajax({
|
|
|
|
url: "/ts_api/login",
|
|
|
|
processData: false,
|
|
|
|
data: JSON.stringify({username: name.val(), password: pwd.val()}),
|
|
|
|
type: "POST",
|
|
|
|
async: false,
|
|
|
|
|
|
|
|
error: function(jqXHR, textStatus, error) {
|
2013-11-04 03:55:41 +00:00
|
|
|
// assuming bad credentials (possible server error or bad request),
|
2011-05-03 12:50:03 -05:00
|
|
|
// we should check that, FIXME
|
|
|
|
var tips = $(".validate-tips");
|
|
|
|
tips.text("Incorrect username/password combination.");
|
2013-10-22 15:32:22 +00:00
|
|
|
tips.slideDown(); },
|
2011-05-03 12:50:03 -05:00
|
|
|
|
|
|
|
success: function(data, textStatus, jqXHR) {
|
2011-05-06 17:45:56 -05:00
|
|
|
viewThis.hide();
|
2013-10-22 15:32:22 +00:00
|
|
|
viewThis.action(); } }); },
|
2011-05-06 17:45:56 -05:00
|
|
|
|
|
|
|
hide: function() { $(this.el).addClass('hidden'); },
|
|
|
|
|
|
|
|
show: function() {
|
|
|
|
$(this.el).removeClass('hidden');
|
2013-10-22 15:32:22 +00:00
|
|
|
this.$("#username-input").focus(); },
|
2011-05-06 17:45:56 -05:00
|
|
|
|
|
|
|
loginOnEnter: function(e) {
|
2013-10-22 15:32:22 +00:00
|
|
|
if (e.keyCode == 13) { this.doLogin(); } } });
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-06-01 06:29:48 -05:00
|
|
|
TS.NewTimelineView = Backbone.View.extend({
|
2013-10-24 20:42:53 +00:00
|
|
|
el: $("#new-timeline")[0],
|
2011-06-01 06:29:48 -05:00
|
|
|
|
|
|
|
events: {
|
|
|
|
"click #new-timeline-create a" : "createTimeline",
|
2013-10-22 15:32:22 +00:00
|
|
|
"click #new-timeline-cancel a" : "hide" },
|
2011-06-01 06:29:48 -05:00
|
|
|
|
|
|
|
initialize: function(options) {
|
|
|
|
_.bindAll(this, 'createTimeline', 'hide', 'show');
|
|
|
|
|
|
|
|
if (options.timelineCollection == undefined) {
|
2013-10-22 15:32:22 +00:00
|
|
|
throw "Can not create the NewTimelineView without the " +
|
|
|
|
"timeline collection." }
|
|
|
|
else { this.timelineCollection = options.timelineCollection; } },
|
2011-06-01 06:29:48 -05:00
|
|
|
|
|
|
|
createTimeline: function() {
|
|
|
|
var timelineId = this.$("#new-timeline-id").val();
|
|
|
|
var timelineDesc = this.$("#new-timeline-desc").val();
|
|
|
|
this.timelineCollection.create(
|
2011-06-07 08:34:20 -05:00
|
|
|
{id: timelineId, description: timelineDesc,
|
2011-06-17 10:58:01 -05:00
|
|
|
created: dateToJSON(new Date())});
|
2013-10-22 15:32:22 +00:00
|
|
|
this.hide(); },
|
2011-06-01 06:29:48 -05:00
|
|
|
|
|
|
|
hide: function() { $(this.el).addClass('hidden'); },
|
|
|
|
|
|
|
|
show: function() {
|
2011-06-07 08:34:20 -05:00
|
|
|
this.$("#new-timeline-id").val("");
|
|
|
|
this.$("#new-timeline-desc").val("");
|
2011-06-01 06:29:48 -05:00
|
|
|
$(this.el).removeClass('hidden');
|
2013-10-22 15:32:22 +00:00
|
|
|
this.$("#new-timeline-id").focus(); } });
|
2011-06-01 06:29:48 -05:00
|
|
|
|
2013-10-22 15:32:22 +00:00
|
|
|
new TS.AppView();
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2013-11-04 03:55:41 +00:00
|
|
|
});
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-06-17 10:58:01 -05:00
|
|
|
function dateToJSON(d) {
|
2011-05-03 12:50:03 -05:00
|
|
|
function pad(n){return n<10 ? '0'+n : n}
|
2011-04-20 09:40:54 -05:00
|
|
|
|
2011-05-03 12:50:03 -05:00
|
|
|
return d.getUTCFullYear()+'-'
|
|
|
|
+ pad(d.getUTCMonth()+1)+'-'
|
|
|
|
+ pad(d.getUTCDate())+'T'
|
|
|
|
+ pad(d.getUTCHours())+':'
|
|
|
|
+ pad(d.getUTCMinutes())+':'
|
|
|
|
+ pad(d.getUTCSeconds())+'Z';
|
2011-03-07 16:43:40 -06:00
|
|
|
}
|