From 1274baa3cb8ecde926d937211447860ea80c38f1 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Thu, 20 Aug 2015 17:03:19 -0700 Subject: [PATCH] persistence, now two-sided --- ape/work.hoon | 2 +- pub/work/src/js/actions/WorkActions.coffee | 7 +- .../src/js/components/ItemComponent.coffee | 28 ++- .../src/js/components/ListComponent.coffee | 1 + pub/work/src/js/main.js | 227 ++++++++++++------ .../src/js/persistence/Persistence.coffee | 14 +- pub/work/src/js/stores/WorkStore.coffee | 26 +- 7 files changed, 203 insertions(+), 102 deletions(-) diff --git a/ape/work.hoon b/ape/work.hoon index a80952bee..c66cd13fe 100644 --- a/ape/work.hoon +++ b/ape/work.hoon @@ -228,7 +228,7 @@ %+ murn (~(tap by sup)) |= [ust=bone her=ship pax=path] ^- (unit move) - ?:(?=([%repo *] pax) ~ `[ust full-report]) + ?:(?=([%sole *] pax) ~ `[ust full-report]) :: ++ full-report [%diff %work-report tasks sort] ++ peer-repo |=(path [[ost full-report]~ +>.$]) diff --git a/pub/work/src/js/actions/WorkActions.coffee b/pub/work/src/js/actions/WorkActions.coffee index d605b5527..764b2a1a3 100644 --- a/pub/work/src/js/actions/WorkActions.coffee +++ b/pub/work/src/js/actions/WorkActions.coffee @@ -1,7 +1,6 @@ Dispatcher = require '../dispatcher/Dispatcher.coffee' Persistence = require '../persistence/Persistence.coffee' -Persistence.get 'test', console.log.bind(console) module.exports = newItem: (index,list) -> item = @@ -50,3 +49,9 @@ module.exports = type:'addItem' index:index item:item + + listenList: (type)-> + Persistence.subscribe type, (err,d)-> + if d? + {sort,tasks} = d.data + Dispatcher.handleServerAction {type:"getData",sort,tasks} diff --git a/pub/work/src/js/components/ItemComponent.coffee b/pub/work/src/js/components/ItemComponent.coffee index f7e706ec7..225195749 100644 --- a/pub/work/src/js/components/ItemComponent.coffee +++ b/pub/work/src/js/components/ItemComponent.coffee @@ -1,8 +1,14 @@ recl = React.createClass -[div,textarea] = [React.DOM.div,React.DOM.textarea] +rece = React.createElement +{div,textarea} = React.DOM WorkActions = require '../actions/WorkActions.coffee' +cediv = recl render: -> + div _.extend {}, @props, + contentEditable: true + dangerouslySetInnerHTML: __html: $('
').text(@props.text).html() + module.exports = recl _dragStart: (e) -> $t = $(e.target) @@ -54,24 +60,24 @@ module.exports = recl (div {className:'sort ib top'},@props.item.sort) (div {className:'done ib'},'') (div {className:'title ib top'},[ - (div { - contentEditable:true + (rece cediv, { onFocus:@_focus onKeyDown:@_keyDown className:'input ib' - },@props.item.title) + text: @props.item.title + }) ]) (div {className:'date ib top'}, [ - (div { - contentEditable:true + (rece cediv, { className:'input ib' - },@formatDate(@props.item['date-created'])) + text: @formatDate(@props.item['date-created']) + }) ]) (div {className:'tags ib top'},[ - (div { - contentEditable:true + (rece cediv, { className:'input ib' - },@props.item.tags.join(" ")) + text: @props.item.tags.join(" ") + }) ]) (div { className:'expand ib', @@ -105,4 +111,4 @@ module.exports = recl (div {className:'submit'},'Post') ]) ]) - ]) \ No newline at end of file + ]) diff --git a/pub/work/src/js/components/ListComponent.coffee b/pub/work/src/js/components/ListComponent.coffee index b445eacb6..d65698ca4 100644 --- a/pub/work/src/js/components/ListComponent.coffee +++ b/pub/work/src/js/components/ListComponent.coffee @@ -98,6 +98,7 @@ module.exports = recl componentDidMount: -> @placeholder = $ "
x
" WorkStore.addChangeListener @_onChangeStore + WorkActions.listenList @props.list @alias() componentDidUpdate: -> diff --git a/pub/work/src/js/main.js b/pub/work/src/js/main.js index 780132851..21bd2267f 100644 --- a/pub/work/src/js/main.js +++ b/pub/work/src/js/main.js @@ -5,8 +5,6 @@ Dispatcher = require('../dispatcher/Dispatcher.coffee'); Persistence = require('../persistence/Persistence.coffee'); -Persistence.get('test', console.log.bind(console)); - module.exports = { newItem: function(index, list) { var item; @@ -77,6 +75,19 @@ module.exports = { index: index, item: item }); + }, + listenList: function(type) { + return Persistence.subscribe(type, function(err, d) { + var ref, sort, tasks; + if (d != null) { + ref = d.data, sort = ref.sort, tasks = ref.tasks; + return Dispatcher.handleServerAction({ + type: "getData", + sort: sort, + tasks: tasks + }); + } + }); } }; @@ -109,75 +120,84 @@ module.exports = recl({ key = $t.attr('data-key'); if (txt.length === 0) { txt = null; - } - if (key === 'audience') { - txt = txt.split(" "); - } - if (key === 'tags') { - txt = [txt]; + } else { + switch (key) { + case 'audience': + txt = txt.split(" "); + break; + case 'tags': + txt = [txt]; + } } return this.props.onChange(key, txt); }, + fields: [ + { + filter: 'owned', + key: 'owner', + title: 'Owned by:' + }, { + filter: 'tag', + key: 'tags', + title: 'Tag:' + }, { + filter: 'channel', + key: 'audience', + title: 'Audience:' + }, { + filter: 'status', + key: 'status', + title: 'Status:' + } + ], render: function() { return div({ className: 'filters' - }, [ - div({ - className: 'owned filter ib', - 'data-key': 'owner' - }, [ - label({}, 'Owned by:'), div({ - contentEditable: true, - className: 'input ib', - onKeyDown: this._onKeyDown, - onBlur: this._onBlur - }, this.props.filters.owned) - ]), div({ - className: 'tag filter ib', - 'data-key': 'tags' - }, [ - label({}, 'Tag:'), div({ - contentEditable: true, - className: 'input ib', - onKeyDown: this._onKeyDown, - onBlur: this._onBlur - }, this.props.filters.tag) - ]), div({ - className: 'channel filter ib', - 'data-key': 'audience' - }, [ - label({}, 'Audience:'), div({ - contentEditable: true, - className: 'input ib', - onKeyDown: this._onKeyDown, - onBlur: this._onBlur - }, this.props.filters.channel) - ]), div({ - className: 'status filter ib', - 'data-key': 'status' - }, [ - label({}, 'Status:'), div({ - contentEditable: true, - className: 'input ib', - onKeyDown: this._onKeyDown, - onBlur: this._onBlur - }, this.props.filters.status) - ]) - ]); + }, this.fields.map((function(_this) { + return function(arg) { + var filter, key, title; + filter = arg.filter, key = arg.key, title = arg.title; + return div({ + key: key, + 'data-key': key, + className: filter + " filter ib" + }, [ + label({}, title), div({ + contentEditable: true, + className: 'input ib', + onKeyDown: _this._onKeyDown, + onBlur: _this._onBlur + }, _this.props.filters[filter]) + ]); + }; + })(this))); } }); },{}],3:[function(require,module,exports){ -var WorkActions, div, recl, ref, textarea; +var WorkActions, cediv, div, rece, recl, ref, textarea; recl = React.createClass; -ref = [React.DOM.div, React.DOM.textarea], div = ref[0], textarea = ref[1]; +rece = React.createElement; + +ref = React.DOM, div = ref.div, textarea = ref.textarea; WorkActions = require('../actions/WorkActions.coffee'); +cediv = recl({ + render: function() { + return div(_.extend({}, this.props, { + contentEditable: true, + dangerouslySetInnerHTML: { + __html: $('
').text(this.props.text).html() + } + })); + } +}); + module.exports = recl({ _dragStart: function(e) { var $t; @@ -245,26 +265,26 @@ module.exports = recl({ }, ''), div({ className: 'title ib top' }, [ - div({ - contentEditable: true, + rece(cediv, { onFocus: this._focus, onKeyDown: this._keyDown, - className: 'input ib' - }, this.props.item.title) + className: 'input ib', + text: this.props.item.title + }) ]), div({ className: 'date ib top' }, [ - div({ - contentEditable: true, - className: 'input ib' - }, this.formatDate(this.props.item['date-created'])) + rece(cediv, { + className: 'input ib', + text: this.formatDate(this.props.item['date-created']) + }) ]), div({ className: 'tags ib top' }, [ - div({ - contentEditable: true, - className: 'input ib' - }, this.props.item.tags.join(" ")) + rece(cediv, { + className: 'input ib', + text: this.props.item.tags.join(" ") + }) ]), div({ className: 'expand ib', onClick: (function(_this) { @@ -477,6 +497,7 @@ module.exports = recl({ componentDidMount: function() { this.placeholder = $("
x
"); WorkStore.addChangeListener(this._onChangeStore); + WorkActions.listenList(this.props.list); return this.alias(); }, componentDidUpdate: function() { @@ -1026,22 +1047,40 @@ module.exports = Object.assign || function (target, source) { }; },{}],14:[function(require,module,exports){ +var cache, listeners; + urb.appl = 'work'; +listeners = {}; + +cache = null; + +urb.bind("/repo", function(err, dat) { + var cb, k, results; + if (err) { + return document.write(err); + } else { + cache = dat; + results = []; + for (k in listeners) { + cb = listeners[k]; + results.push(cb(null, dat)); + } + return results; + } +}); + module.exports = { put: function(update, cb) { return urb.send(update, { mark: 'work-command' }, cb); }, - get: function(id, cb) { - var url; - url = (urb.util.basepath("/pub/work/")) + id + ".json"; - return $.get(url, {}, function(data) { - if (cb) { - return cb(null, data); - } - }); + subscribe: function(key, cb) { + listeners[key] = cb; + if (cache != null) { + return cb(null, cache); + } } }; @@ -1131,6 +1170,25 @@ WorkStore = assign({}, EventEmitter.prototype, { removeChangeListener: function(cb) { return this.removeListener("change", cb); }, + getData: function(arg) { + var _tasks, i, id, len, sort, tasks; + sort = arg.sort, tasks = arg.tasks; + _tasks = _.clone(tasks); + for (i = 0, len = _list.length; i < len; i++) { + id = _list[i].id; + delete _tasks[id]; + } + return sort.map((function(_this) { + return function(k, index) { + if (_tasks[k]) { + return _this.newItem({ + item: _tasks[k], + index: index + }); + } + }; + })(this)); + }, getList: function(key) { var _k, _v, add, c, k, list, v; list = []; @@ -1194,15 +1252,28 @@ WorkStore = assign({}, EventEmitter.prototype, { } return _sorts[key] = val; }, - newItem: function(arg) { - var _item, index, item; - index = arg.index, item = arg.item; + itemFromData: function(item, index) { + var _item; + if (index == null) { + index = 0; + } _item = _.extend({ sort: index }, item); - _item["date-created"] = new Date(item["date-created"]); _item["date-modified"] = new Date(item["date-modified"]); - return _list.splice(index, 0, _item); + _item["date-created"] = new Date(item["date-created"]); + if (item["date-due"] != null) { + _item["date-due"] = new Date(item["date-due"]); + } + if (item.done != null) { + _item.done = new Date(item.done); + } + return _item; + }, + newItem: function(arg) { + var index, item; + item = arg.item, index = arg.index; + return _list.splice(index, 0, this.itemFromData(item, index)); }, swapItem: function(arg) { var from, to; diff --git a/pub/work/src/js/persistence/Persistence.coffee b/pub/work/src/js/persistence/Persistence.coffee index e71a2e682..de1db17de 100644 --- a/pub/work/src/js/persistence/Persistence.coffee +++ b/pub/work/src/js/persistence/Persistence.coffee @@ -1,6 +1,14 @@ urb.appl = 'work' +listeners = {} +cache = null +urb.bind "/repo", (err,dat)-> + if err + document.write err + else + cache = dat + (cb null,dat) for k,cb of listeners module.exports = put: (update,cb) -> urb.send(update,{mark:'work-command'},cb) - get: (id,cb) -> - url = (urb.util.basepath "/pub/work/")+id+".json" - $.get url, {}, (data) -> if cb then cb null,data + subscribe: (key,cb) -> + listeners[key] = cb + (cb null,cache) if cache? diff --git a/pub/work/src/js/stores/WorkStore.coffee b/pub/work/src/js/stores/WorkStore.coffee index 0b11428e8..6ec983af8 100644 --- a/pub/work/src/js/stores/WorkStore.coffee +++ b/pub/work/src/js/stores/WorkStore.coffee @@ -65,6 +65,14 @@ WorkStore = assign {},EventEmitter.prototype,{ addChangeListener: (cb) -> @on 'change', cb removeChangeListener: (cb) -> @removeListener "change", cb + getData: ({sort,tasks})-> + _tasks = _.clone tasks + for {id} in _list + delete _tasks[id] + sort.map (k,index)=> + if _tasks[k] + @newItem {item:_tasks[k],index} + getList: (key) -> list = [] for k,v of _list @@ -99,15 +107,17 @@ WorkStore = assign {},EventEmitter.prototype,{ _sorts[k] = 0 _sorts[key] = val - newItem: ({index,item}) -> + + itemFromData: (item,index=0)-> _item = _.extend {sort:index}, item - _item["date-created"]=new Date item["date-created"] - _item["date-modified"]=new Date item["date-modified"] - _list.splice index,0,_item - - swapItem: ({to,from}) -> - _list.splice to,0,_list.splice(from,1)[0] - + _item["date-modified"] = new Date item["date-modified"] + _item["date-created"] = new Date item["date-created"] + _item["date-due"] = new Date item["date-due"] if item["date-due"]? + _item.done = new Date item.done if item.done? + _item + + newItem: ({item,index}) -> _list.splice index,0,@itemFromData item,index + swapItem: ({to,from}) -> _list.splice to,0,_list.splice(from,1)[0] removeItem: ({index}) -> _list.splice index,1 }