82 Commits

Author SHA1 Message Date
Jonathan Bernard
1e05258381 Bugfixes.
* ts_api:list_timelines/2 was looking for keys as atoms instead of lists (strings).
* Exported the ts_json:decode_datetime/1 function (needed by ts_api module).
* Fixed a crash case when trying to check the credentials of a non-existent user.
2013-09-15 00:33:02 +00:00
Jonathan Bernard
38dc560686 Updated yaws_api.hrl, prod configuration (to live alongside VBS). 2013-09-13 01:56:45 +00:00
Jonathan Bernard
b01421d45d Adjusted session timeout to be 12 hours. 2011-06-18 09:36:03 -05:00
Jonathan Bernard
f3ef7db088 Work on front-side UI.
* Resolved D0003: Add day separators.

    * Created ``daySeparatorTemplate`` for ICanHaz templating.
    * Refactored ``EntryListView.render`` to spit out day separators in between
      days on the timeline. Fixed the "Today" separator to the top of the entry
      container. We no longer prepend entries to the entry container, we now put
      them after the top separator in the entry container.
    * Created ``EntryListView.formatDaySeparator`` to format the labels
      according to the relative time to today: "Yesterday", "Last Monday",
      "Friday, May 28" for example.
    * Removed the cludgier ``toWords``, ``daysApart``, and `` capitalize``
      functions that were going to serve the same purpose.
* Resolved D0021: Constrain notes width to mark.
2011-06-17 16:11:18 -05:00
Jonathan Bernard
81503112a8 Work on day separators.
* Overrode ``EntryModel.{get,set}`` to return a ``Date`` object and allow you to
  set the value with either a ``Date`` object, or the JSON date string.
* Updated code to reflect the ``EntryModel.timestamp`` data change.
* Added ``daysApart`` to calculate calendar days between given ``Date``s
* Added ``getEnglishDate`` to return a date description relative to the current
  day ("Today", "Last year" for example).
2011-06-17 16:11:12 -05:00
Jonathan Bernard
1fff94b622 Implemented entry exclusions in UI.
* Resolved D0020: Add exclusion filter for entries.
* Refactored ``timeline`` fields of several objects in ``ts.js`` to be
  ``timelineModel`` to be explicit.
* Added support for exclusions in ``EntryListView.renderOne`` and
  ``EntryListView.render``.
2011-06-16 17:55:01 -05:00
Jonathan Bernard
602bdca7e3 Minor fixes needed for last_timeline to work.
* Added route back for PUT /ts_api/user/<username>
* Fixed typo in ``ts_api:put_user/2``.
* Fixed incorrect expected return from ``ts_ext_data:set_property/3``.
* Added missing assignment for ``ts_user.email`` in the appropriate
  ``ts_json:construct_record/3`` clause.
* Fixed model attribute assignment in ``ts.js``.
2011-06-15 18:31:53 -05:00
Jonathan Bernard
cd182d54c3 Fixing problems introduced by the model change.
* Many calls to ``ts_ext_data:get_properties/1`` from ``ts_api`` were passing
  the record reference, not the record itself. Fixed.
* Created ``ts_api:put_user/2`` which updates a ``ts_user`` record. This is
  needed specifically for updating the ``liat_timeline`` extended data property.
* Removed unreachable code in ``ts_api:post_entry/3``
* Fixed return value of some ``ts_user`` functions to use the
  ``{Status, Value}`` convention. TODO: make sure all calls are using the same
  convention.
* Fixed error message formatting in ``ts_ext_data:set_property/3``.
* Added clauses to ``ts_json:ejson_to_record/2``,
  ``ts_json:ejson_to_record_strict/2`` and ``ts_json:construct_record/3`` to
  handle the ``ts_user`` record type.
* Added code to ``AppView.loadInitialData`` and ``AppView.selectTimeline`` to
  support the ``last_timeline`` extended data property.
2011-06-15 16:59:00 -05:00
Jonathan Bernard
3999e736be Bug fixes and implementation refinement around `ts_ext_data`.
* Transformed the test database to match the new data model. Added
  ``ts_ext_data`` table and moved ``ts_user.ext_data`` values to it.
* Added D0022: cascade delete ``ts_ext_data`` when ``ts_entry`` record is
  deleted.
* Completed refactor of ``ts_api`` functions to account for extended data:

    * ``post_entry/3``
    * ``put_entry/3``

* Created ``ts_entry:write/2`` to write extended data atomically with the entry.
* Fixed copy/paste bug in ``ts_ext_data:create_table/1``.
* Fixed implementation of ``ts_ext_data:set_property/3`` to be explicit about
  taking a record, not a reference. It then extracts the reference and passes it
  to the underlying implementation in ``ts_ext_data:do_set_property/3``.
* Refactored ``ts_ext_data:do_set_property/3`` to take a record *reference*, not
  the record itself.
* Refactored the ``ts_ext_data:get_property/2`` and
  ``ts_ext_data:get_properties/1`` functions to return key value tuple pairs,
  not ``ts_ext_data{}`` records.
2011-06-15 07:34:41 -05:00
Jonathan Bernard
658091e947 Bugfixing, compile-error-sqhashung. 2011-06-15 00:54:58 -05:00
Jonathan Bernard
7d11112226 Fixed extended data handling in `ts_json` module.
* Refactored ``ts_json:ext_data_to_ejson{1,2}`` from a function that iterates
  over a list of extended data properties and returns a transformed list to
  ``ts_json:ext_data_to_ejson/1``, a function that transforms one extended data
  property. The iteration behavior is acheived using ``lists:map/2``.
* Refactored ``ts_json:ejson_to_ext_data{1,2}`` in a similar fashion to
  ``ts_json:ext_data_to_ejson{1,2}``.
* Fixed ``ts_json:construct_record/3`` to use ``ts_json:ejson_to_ext_data/1``.
2011-06-15 00:26:31 -05:00
Jonathan Bernard
8bb50c058d Changed Data Model
------------------

* Created the extended data table. This is a more generic version of the
  extended data field that was on ``ts_user``. Instead of arbitrary key-value
  pairs going in a list on the user record we will have an additional table, a
  one to many relationship between existing tables and the ``ts_ext_data``
  table, each row being an extended value of the corresponding record.
* Added support to the ``timestamper:create_tables/1`` and
  ``timestamper_dev:create_table/1`` functions for the new ``ts_ext_data`` table.

Documentation
-------------

* Added some general docs about the DB layer code.
* Added two new issues, *D0020*: Entry exclusion filters and *D0021*: notes width.

API Changes
-----------

Necessitated by the change to the data model.

* Updated ``ts_api`` data-retrieval functions to use extended data:

    * ``get_user_summary/2``
    * ``list_timelines/2``
    * ``list_entries/3``

* Updated ``ts_api:put_timeline/3`` to parse the extended data supplied by the
  caller. *FIXME* it is not actually saving this data.
* TODO: Started updating ``ts_api:post_entry/3`` to handle extended data, need
  to finish.

Database Layer
--------------

Changes necessitated by the change to the model.

* Added ``ts_common:do_set_ext_data/2`` which iterates through the extended data
  key-value pairs calling ``ts_ext_data:set_property/3``. It does not provide a
  transaction context.
* Split ``ts_common:new/1`` and ``ts_common:update/1`` functions into multiple
  functions to prevent code-duplication:

    * ``do_{new,update}`` contains the code that performs integrity checks and
      the actual database write function. It does this assuming that it is being
      called from within the context of an mnesia transaction (uses
      ``mnesia:read`` and ``mnesia:write``).
    * ``{new,update}/1`` performs the same function as previously. The
      implementation changed from using mnesia ``dirty_*`` calls to prociding a
      transaction and calling ``do_{new,update}/1``.
    * ``{new,update}/2`` expect the record to update/create and the extended
      data to write atomically with the record. They provide a transaction
      context, call ``do_{new,update}/1``, then call ``do_set_ext_data/2``.

* Similar to the refactoring of ``ts_common:{new,update}/1``,
  ``ts_entry:{new,update}/1`` have been refactored into multiple methods each to
  support extended data properties:

    * ``do_{new,update}/1`` perform the actual update assuming we have already
      established an mnesia transaction.
    * ``{new,update}/1`` behave the same as they used to, but now do so by
      creating an mnesia transaction and calling ``do_{new,update}/1``.
    * ``{new,update}/2`` create an mnesia transaction, call
      ``do_{new,update}/1``, and then call ``ts_common:do_set_ext_data/2``.

* Again similar to the refactoring of ``ts_common:{new,update}/1``,
  ``ts_user:{new,update}/1`` have been refactored into multiple methods each to
  support extended data properties:

    * ``do_{new,update}/1`` perform the actual update assuming we have already
      established an mnesia transaction.
    * ``{new,update}/1`` behave the same as they used to, but now do so by
      creating an mnesia transaction and calling ``do_{new,update}/1``.
    * ``{new,update}/2`` create an mnesia transaction, call
      ``do_{new,update}/1``, and then call ``ts_common:do_set_ext_data/2``.

* Created the ``ts_ext_data`` module as the interface to the extended data
  properties introduced in the data model:

    * ``create_table/1`` performs the same function as it does in the other db
      layer modules, creates the table with the appropriate structure given the
      more general table options desired (location, storage type, etc.).
    * ``set_property/3`` takes a record, a property key, and a property value as
      input and sets the property described by the property key on the record to
      the given value, assuming this is a valid property for the record to have.
      For example, currently the ``ts_user`` record can have an associated
      property, ``last_timeline``, which represents the last timeline the user
      was working with. Trying to pass this property with a ``ts_entry`` record
      would result in an exception. This function uses
      ``ts_ext_data:do_set_property/3`` as its underlying implementation.
    * ``get_property/2`` takes a record and a property key and returns the value
      of that property for the given record, or ``not_set`` if the property has
      not been set on that record. This method creates its own mnesia
      transaction.
    * ``get_properties/1`` takes a record and returns a list of key-value tuples
      representing all of the extended data properties set for the given record.
      This method creates its own mnesia transaction.
    * ``do_set_property/3`` takes a record reference (not the whole record), a
      a property key, and adds the property assignment to the ``ts_ext_data``
      table. It creates its own mnesia transaction.

* Added ``new/2`` and ``update/2`` to the ``ts_timeline`` module to support
  extended data properties. They delegate implementation to
  ``ts_common:{new,update}/2``.

JSON Encoding/Decoding
----------------------

Changes necessitated by the change to the data model.

The JSON objects now contain a potentially unlimited number of fields, as each
extended data property is encoded as a seperate field, and looks no different
from any of the required fields on the object. The intended explanation in API
documentation is that each object type (``user``, ``timeline``, or ``entry``)
now has both *required* fields that *MUST* be present in every message in either
direction and *optional* fields that may or may not be present in any
communication with the API. There should be a clear distinction between which
fields are required and which are optional. It might also be a good idea to
provide a suggested default for optional values when they are not present.

* Updated documentation about JSON record structures to reflect the fact that
  there are now potentially many optional attributes in addition to the required
  attributes for each record.
* ``record_to_ejson/1`` refactored to ``record_to_ejson/2`` which also takes
  the extended data attributes and appends them as additional attributes to
  the end of the record structure.
* Created ``ext_data_to_ejson/{1,2}`` to provide a mechanism for reformatting
  extended data properties whose internal representations are not immediately
  translatable into JSON. Currently only the ``entry_exclusions`` property,
  which is a list of strings, needs to be treated this way (changing from
  ``[val, val]`` to ``{array, [val, val]}`` as needed by ``json:encode/1``.
  ``ext_data_to_ejson/1`` acts as a more user-friendly facade to
  ``ext_data_to_ejson/2``.
* Rewrote ``ejson_to_record/{2,3}`` and ``ejson_to_record_strict/{2,3}`` to
  handle extended data. They now use a common method, ``construct_record/3`` to
  create the actual record object and extended data key-value list.
  ``ejson_to_record_strict/{2,3}`` only differs in that it checks for the
  presence of each required field of the record after the record is constructed.
  The three-parameter versions of these functions also take in the intended
  reference for the constructed record, replacing anything that is in the EJSON
  body as the record reference (useful when the body does not have the record
  ids). These methods now return a tuple: ``{Record, ExtData}`` instead of just
  the record.
* Created ``construct_record/3`` takes a record and the EJSON fields from the
  input object. The third parameter is an accumulator for the extended data
  properties found when constructing the record. This method works by iterating
  over the list of input fields. It recognizes any required fields and updates
  the record being built with the value. Any fields it does not recognize it
  assumes are extended data properties and adds to its list. When all input
  fields have been visited it returns the record and list it has constructed.
* ``ejson_to_ext_data/{1,2}`` is the inverse of ``ext_data_to_ejson/{1,2}``.
  *TODO*: this method is not actually being used by the ``ejson_to_record*``
  methods.
2011-06-14 16:48:04 -05:00
Jonathan Bernard
99d04935cb Implemented timeline selection.
* Added personal VIM ide extension.
* Implemented timeline selection (resolves D0007)
* Slightly restyled the new timeline button and timeline list menu.
2011-06-10 11:49:45 -05:00
Jonathan Bernard
b5eadd6fc4 Fixed timeline creation, API logical fixes.
* Resolved issues:

    * #0006: Fix timeline menu UI.
    * #0015: Create new timeline button in timeline menu.
    * #0017: Implement timeline creation.

* Removed ts_api:post_timeline/3, corresponded to `POST` to
  `/ts_api/timelines/<user-id>`, which makes no sense as there is no way to
  auto-generate new timeline-ids.
* Changed ts_api:put_timeline/3 to use ts_timeline:write. This resolved #0017.
* Changed ts_api:put_entry/4 to use ts_entry:write.
* Implemented ts_entry:write/1 and ts_timeline:write/1. These functions are
  simple passthroughs to mnesia:dirty_write/1.
* Added clarifing documentation for ts_json:record_to_ejson JSON formats.
* Renamed ts_json:ejson_to_record/2 to ts_json:ejson_to_record_strict/2 and
  added ts_json:ejson_to_record/2 as a lax version of the same.
* Updated all ts_api functions to use updated ts_json methods.
2011-06-07 20:47:23 -05:00
Jonathan Bernard
bc364b2ebd Merge branch 'client-redesign'
Conflicts:
	yaws.dev.conf
2011-06-07 08:38:09 -05:00
Jonathan Bernard
89336e844f Implemented new timeline functionality client-side.
* Fixed returned information in ts_api:put_timeline/3
* Added UI for new timeline button.
* Added client-side implementation of new timeline creation. There is a problem
  on the server-side, PUT should support creating new items and updating
  existing items.
2011-06-07 08:34:20 -05:00
Jonathan Bernard
76083b5972 Added icons for timeline creation. 2011-06-07 08:29:26 -05:00
Jonathan Bernard
cf42d133f6 Added UI for timeline creation. 2011-06-01 06:29:48 -05:00
Jonathan Bernard
72ef1ac277 Moved issues to issue tracker. 2011-05-27 09:50:43 -05:00
Jonathan Bernard
2cc17b85f1 Implemented notes UI.
- Switched from a global reset in www/css/ts-screen.scss to a selected
  top-level elements reset to allow default formatting for user notes.
- Restructured the #entry-list and entry displays.
- Restructured notes div, now has a sub-div for text and a textarea
  element for input.
- Added Showdown.js, a JavaScript Markdown library for formatting comments.
- Moved EntryView blur events to the View events map.
- Added images for expansion of notes.
- Added the ability to edit notes.
- Split EntryListView.addOne into renderOne and addOne so that renderOne
  can be called with a new entry (fixes duration glitch)
2011-05-16 04:09:37 -05:00
Jonathan Bernard
65a9a517f9 Updated test data. 2011-05-09 10:54:24 -05:00
Jonathan Bernard
808492154d Adding hover-able icons to timeline entries.
- Added notes and delete icons right and left entry marks respectively.
- Notes icon slide toggles the notes display (hidden by default).
2011-05-09 10:52:21 -05:00
Jonathan Bernard
74d8a7f015 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
Jonathan Bernard
036177cfed 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
Jonathan Bernard
b22c10c6c2 Created todo documentation. 2011-05-07 21:30:32 -05:00
Jonathan Bernard
850edf9e25 Updated test data. 2011-05-07 21:30:00 -05:00
Jonathan Bernard
1161f6b752 Added feature brainstorming doc. 2011-05-06 17:47:16 -05:00
Jonathan Bernard
65dbab9c13 Replaced jQuery UI login dialog with home-grown login.
- New login hides the entire underlying page when open.
- Fits the current design.
2011-05-06 17:45:56 -05:00
Jonathan Bernard
06556020d4 UI Tweak: column headers, re-alignments.
- Added 'start' and 'duration' headers to day seperators.
- Right-aligned start and duration columns.
- Changed duration to 'Xhr Ym' instead of 'HH:MM:SS'.
- Added a section using 12hr time format instead of 24hr for comparison.
2011-05-06 13:14:57 -05:00
Jonathan Bernard
dd3387a0f1 Trying to tighten up the design. More functionality implemented. 2011-05-03 12:50:03 -05:00
Jonathan Bernard
cf5153c90b Merge branch 'api-redesign' into client-redesign 2011-05-03 12:40:06 -05:00
Jonathan Bernard
ac80d57cd3 Updated dev conf to reflect the new location of the Timestamper project. 2011-05-03 12:37:15 -05:00
Jonathan Bernard
3d89477f7e Added ext_data field to ts_user. 2011-05-03 12:27:39 -05:00
Jonathan Bernard
ebd4b117c9 Updated database to use lists instead of atoms for table keys. 2011-05-03 12:27:13 -05:00
Jonathan Bernard
9b3f587974 Changed record keys to use lists instead of atoms.
Using atoms will not scale in the large. Also, using atoms as keys forced the
API to convert arbitrary end-user input to atoms, adding another potential
drain of the finite atom-space available.

- ts_api: url paths are now treated and matched as lists, not atoms.
  Usernames and API calls all use lists now.
- ts_json: key items (username, timeline ids) are now expected to be lists,
  not atoms.
2011-05-03 12:24:23 -05:00
Jonathan Bernard
77fc3f2a07 Created prototype HTML. 2011-05-03 12:00:27 -05:00
Jonathan Bernard
f4fe5559b1 Reorganizing UI, adding TimelineListView. 2011-04-27 16:59:33 -05:00
Jonathan Bernard
302bc9ccdd Trying to gather thoughts and code coherently.
Added client-side architecture model.
Playing with UI code.
2011-04-27 14:11:54 -05:00
Jonathan Bernard
9025a2f8f6 Trying a view for user, timeline(s), entry(ies). 2011-04-20 09:40:54 -05:00
Jonathan Bernard
aec172536e Merge branch 'api-redesign' into client-redesign 2011-04-15 14:30:28 -05:00
Jonathan Bernard
5b267ec67b Switched usage of POST and PUT verbs.
- POST and PUT were being used counter to typical usage, POST updating existing
  records and PUT creating new ones. Changed to PUT updating existing records
  and POST creating records.
2011-04-15 13:53:24 -05:00
Jonathan Bernard
17c5b9cbd1 API now returns just the content in the body.
- Instead of returning Meta-Data (status) in the header and the body, we now
  only return the content in the body, except in error when we return the error
  message.

- JSON entries use the 'id' name for entity ids (instead of 'username',
  'timeline_id', and 'entry_id')
2011-04-15 13:51:01 -05:00
Jonathan Bernard
e10ec26a21 Implementing new client design using Backbone.js. 2011-04-15 13:26:55 -05:00
Jonathan Bernard
d0aab2d0c6 merge. 2011-04-10 17:20:43 -05:00
Jonathan Bernard
b6d05665bf Moved timestamper to root of server. 2011-04-10 17:16:30 -05:00
Jonathan Bernard
81fb56022c Merge branch 'stable' 2011-03-17 04:17:26 +00:00
Jonathan Bernard
76f32ac834 Moved timestamper under JDB Labs. 2011-03-17 04:17:10 +00:00
Jonathan Bernard
4d124ffeba Fixing dev config. Starting to implement sign-up.
Added 'default' make target to only compile.
Reset development configuration.
Commented out starts of tests.
Added sign-up GUI to login panel.
Moved application from /ts/ to /
2011-03-16 07:39:09 -05:00
Jonathan Bernard
1b981b206c Created timestamper_dev module, logging. 2011-03-11 15:08:18 +00:00
Jonathan Bernard
b59b628cb5 Deployed to dev01 on the Rrackspace cloud. 2011-03-11 12:32:06 +00:00