don't persist blank item sort, drag ghost, save it

This commit is contained in:
Anton Dyudin 2015-08-27 14:45:19 -07:00
parent 1fc367377a
commit 71de4f6e98
6 changed files with 83 additions and 65 deletions

View File

@ -54,10 +54,8 @@ module.exports =
setFilter: (key,val) -> Dispatcher.handleViewAction {type:'setFilter', key,val} setFilter: (key,val) -> Dispatcher.handleViewAction {type:'setFilter', key,val}
setSort: (key,val) -> Dispatcher.handleViewAction {type:'setSort',key,val} setSort: (key,val) -> Dispatcher.handleViewAction {type:'setSort',key,val}
moveItem: (list,to,from) -> moveItem: (list,to,from) ->
sort = _.clone list Persistence.put {sort:list}
sort.splice to, 0, sort.splice(from,1)[0] Dispatcher.handleViewAction {type:'moveItems',list,to,from}
Persistence.put {sort}
Dispatcher.handleViewAction {type:'moveItems',list:sort,to,from}
listenList: (type)-> listenList: (type)->
Persistence.subscribe type, (err,d)-> Persistence.subscribe type, (err,d)->

View File

@ -35,22 +35,24 @@ module.exports = recl
onKeyUp: (e) -> onKeyUp: (e) ->
$t = $(e.target).closest '.field' $t = $(e.target).closest '.field'
val = @parse @getVal() _val = @getVal()
if @props.item.ghost and _val is ""
return
val = @parse _val
unless @validate val unless @validate val
@setState invalid:yes @setState invalid:yes
return return
@setState invalid:no @setState invalid:no
unless @equal @props.defaultValue, val unless @equal @props.defaultValue, val
@oldValue ?= [] @oldValue ?= []
@oldValue.push val @oldValue.push val
if @to then clearTimeout @to if @to then clearTimeout @to
@to = setTimeout => @to = setTimeout =>
{item,_key} = @props {item,_key,index} = @props
if item.version >= 0 if item.version >= 0
WorkActions.setItem item, _key, val WorkActions.setItem item, _key, val
else WorkActions.newItem item.index, else WorkActions.newItem index,
id: item.id id: item.id
tags: item.tags tags: item.tags
audience: item.audience audience: item.audience
@ -62,7 +64,7 @@ module.exports = recl
$(@refs.input.getDOMNode()).val() $(@refs.input.getDOMNode()).val()
else $(@refs.input.getDOMNode()).text() else $(@refs.input.getDOMNode()).text()
parse : (text)-> switch @props._key parse: (text)-> switch @props._key
when 'tags' then text.trim().split(" ") when 'tags' then text.trim().split(" ")
when 'audience' then text.trim().split(" ").map (a) -> "~#{a}" when 'audience' then text.trim().split(" ").map (a) -> "~#{a}"
when 'date_due' when 'date_due'
@ -71,12 +73,12 @@ module.exports = recl
new Date(d).valueOf() new Date(d).valueOf()
else text else text
equal: (vol,val) -> switch @props._key equal: (vol=(@parse ""),val) -> switch @props._key
when 'tags', 'audience' when 'tags', 'audience'
(_.xor(vol,val).length is 0) (_.xor(vol,val).length is 0)
when 'date_due' when 'date_due'
vol.valueOf() is val vol.valueOf() is val
else (vol ? "") is val else vol is val
validate: (val) -> switch @props._key validate: (val) -> switch @props._key
when 'date_due' when 'date_due'

View File

@ -73,8 +73,9 @@ module.exports = recl
getInitialState: -> {expand:false} getInitialState: -> {expand:false}
renderField: (_key,props,render=_.identity)-> renderField: (_key,props,render=_.identity)->
defaultValue = @props.item[_key] {item,index} = @props
rece Field, $.extend props, {render,_key,item:@props.item,defaultValue} defaultValue = item[_key]
rece Field, $.extend props, {render,_key,defaultValue,item,index}
renderTopField: (key,props,format)-> renderTopField: (key,props,format)->
_props = _.extend props,{className:"#{props.className ? key} top"} _props = _.extend props,{className:"#{props.className ? key} top"}

View File

@ -38,7 +38,10 @@ module.exports = recl
to = Number @over.closest('.item-wrap').attr('data-index') to = Number @over.closest('.item-wrap').attr('data-index')
if from<to then to-- if from<to then to--
if @drop is 'after' then to++ if @drop is 'after' then to++
WorkActions.moveItem (id for {id} in @state.list), to, from sort = _.clone @state.list
sort.splice to, 0, sort.splice(from,1)[0]
list = (id for {id,version} in sort when (version ? -1) >= 0)
WorkActions.moveItem list, to, from
@dragged.removeClass 'hidden' @dragged.removeClass 'hidden'
@placeholder.remove() @placeholder.remove()
@ -69,18 +72,17 @@ module.exports = recl
index++ index++
ins = @state.selected+1 # XX consolidate ins = @state.selected+1 # XX consolidate
@setState {selected:ins,select:true} @setState {selected:ins,select:true}
{tags,audience} = item unless item.ghost
WorkActions.newItem index, {tags,audience} {tags,audience} = item
item = {tags,audience}
WorkActions.newItem index, item
# backspace - remove if at 0 # backspace - remove if at 0
when 8 when 8
if (window.getSelection().getRangeAt(0).endOffset is 0) and if (window.getSelection().getRangeAt(0).endOffset is 0) and
(e.target.innerText.length is 0) (e.target.innerText.length is 0)
if i.props.item.ghost if @state.selected isnt 0
WorkActions.moveGhost null @setState {selected:@state.selected-1,select:"end"}
else WorkActions.removeItem i.props.item
if @state.selected isnt 0
@setState {selected:@state.selected-1,select:"end"}
WorkActions.removeItem i.props.item
e.preventDefault() e.preventDefault()
# up # up
when 38 when 38
@ -149,14 +151,17 @@ module.exports = recl
}, _.map @state.list,(item,index) => }, _.map @state.list,(item,index) =>
className = "item-wrap" className = "item-wrap"
key = item.id key = item.id
if item.ghost then className += " ghost" draggable = @state.canSort
if item.ghost
className += " ghost"
draggable = false
(div {className,key,'data-index':index}, (div {className,key,'data-index':index},
rece(ItemComponent,{ rece(ItemComponent,{
item item
index index
draggable
@_focus @_focus
@title_keyDown @title_keyDown
draggable:@state.canSort
@_dragStart @_dragStart
@_dragEnd}) @_dragEnd})
) )

View File

@ -142,15 +142,12 @@ module.exports = {
}); });
}, },
moveItem: function(list, to, from) { moveItem: function(list, to, from) {
var sort;
sort = _.clone(list);
sort.splice(to, 0, sort.splice(from, 1)[0]);
Persistence.put({ Persistence.put({
sort: sort sort: list
}); });
return Dispatcher.handleViewAction({ return Dispatcher.handleViewAction({
type: 'moveItems', type: 'moveItems',
list: sort, list: list,
to: to, to: to,
from: from from: from
}); });
@ -221,9 +218,13 @@ module.exports = recl({
}, div(props))); }, div(props)));
}, },
onKeyUp: function(e) { onKeyUp: function(e) {
var $t, val; var $t, _val, val;
$t = $(e.target).closest('.field'); $t = $(e.target).closest('.field');
val = this.parse(this.getVal()); _val = this.getVal();
if (this.props.item.ghost && _val === "") {
return;
}
val = this.parse(_val);
if (!this.validate(val)) { if (!this.validate(val)) {
this.setState({ this.setState({
invalid: true invalid: true
@ -243,12 +244,12 @@ module.exports = recl({
} }
return this.to = setTimeout((function(_this) { return this.to = setTimeout((function(_this) {
return function() { return function() {
var _key, item, obj, ref1; var _key, index, item, obj, ref1;
ref1 = _this.props, item = ref1.item, _key = ref1._key; ref1 = _this.props, item = ref1.item, _key = ref1._key, index = ref1.index;
if (item.version >= 0) { if (item.version >= 0) {
return WorkActions.setItem(item, _key, val); return WorkActions.setItem(item, _key, val);
} else { } else {
return WorkActions.newItem(item.index, ( return WorkActions.newItem(index, (
obj = { obj = {
id: item.id, id: item.id,
tags: item.tags, tags: item.tags,
@ -289,6 +290,9 @@ module.exports = recl({
} }
}, },
equal: function(vol, val) { equal: function(vol, val) {
if (vol == null) {
vol = this.parse("");
}
switch (this.props._key) { switch (this.props._key) {
case 'tags': case 'tags':
case 'audience': case 'audience':
@ -296,7 +300,7 @@ module.exports = recl({
case 'date_due': case 'date_due':
return vol.valueOf() === val; return vol.valueOf() === val;
default: default:
return (vol != null ? vol : "") === val; return vol === val;
} }
}, },
validate: function(val) { validate: function(val) {
@ -554,16 +558,18 @@ module.exports = recl({
}; };
}, },
renderField: function(_key, props, render) { renderField: function(_key, props, render) {
var defaultValue; var defaultValue, index, item, ref1;
if (render == null) { if (render == null) {
render = _.identity; render = _.identity;
} }
defaultValue = this.props.item[_key]; ref1 = this.props, item = ref1.item, index = ref1.index;
defaultValue = item[_key];
return rece(Field, $.extend(props, { return rece(Field, $.extend(props, {
render: render, render: render,
_key: _key, _key: _key,
item: this.props.item, defaultValue: defaultValue,
defaultValue: defaultValue item: item,
index: index
})); }));
}, },
renderTopField: function(key, props, format) { renderTopField: function(key, props, format) {
@ -735,7 +741,7 @@ module.exports = recl({
return this.dragged = i.dragged; return this.dragged = i.dragged;
}, },
_dragEnd: function(e, i) { _dragEnd: function(e, i) {
var from, id, to; var from, id, list, sort, to, version;
from = Number(this.dragged.closest('.item-wrap').attr('data-index')); from = Number(this.dragged.closest('.item-wrap').attr('data-index'));
to = Number(this.over.closest('.item-wrap').attr('data-index')); to = Number(this.over.closest('.item-wrap').attr('data-index'));
if (from < to) { if (from < to) {
@ -744,16 +750,20 @@ module.exports = recl({
if (this.drop === 'after') { if (this.drop === 'after') {
to++; to++;
} }
WorkActions.moveItem((function() { sort = _.clone(this.state.list);
sort.splice(to, 0, sort.splice(from, 1)[0]);
list = (function() {
var j, len, ref1, results; var j, len, ref1, results;
ref1 = this.state.list;
results = []; results = [];
for (j = 0, len = ref1.length; j < len; j++) { for (j = 0, len = sort.length; j < len; j++) {
id = ref1[j].id; ref1 = sort[j], id = ref1.id, version = ref1.version;
results.push(id); if ((version != null ? version : -1) >= 0) {
results.push(id);
}
} }
return results; return results;
}).call(this), to, from); })();
WorkActions.moveItem(list, to, from);
this.dragged.removeClass('hidden'); this.dragged.removeClass('hidden');
return this.placeholder.remove(); return this.placeholder.remove();
}, },
@ -795,25 +805,24 @@ module.exports = recl({
select: true select: true
}); });
} }
tags = item.tags, audience = item.audience; if (!item.ghost) {
WorkActions.newItem(index, { tags = item.tags, audience = item.audience;
tags: tags, item = {
audience: audience tags: tags,
}); audience: audience
};
}
WorkActions.newItem(index, item);
break; break;
case 8: case 8:
if ((window.getSelection().getRangeAt(0).endOffset === 0) && (e.target.innerText.length === 0)) { if ((window.getSelection().getRangeAt(0).endOffset === 0) && (e.target.innerText.length === 0)) {
if (i.props.item.ghost) { if (this.state.selected !== 0) {
WorkActions.moveGhost(null); this.setState({
} else { selected: this.state.selected - 1,
if (this.state.selected !== 0) { select: "end"
this.setState({ });
selected: this.state.selected - 1,
select: "end"
});
}
WorkActions.removeItem(i.props.item);
} }
WorkActions.removeItem(i.props.item);
e.preventDefault(); e.preventDefault();
} }
break; break;
@ -894,11 +903,13 @@ module.exports = recl({
onDragOver: this._dragOver onDragOver: this._dragOver
}, _.map(this.state.list, (function(_this) { }, _.map(this.state.list, (function(_this) {
return function(item, index) { return function(item, index) {
var className, key; var className, draggable, key;
className = "item-wrap"; className = "item-wrap";
key = item.id; key = item.id;
draggable = _this.state.canSort;
if (item.ghost) { if (item.ghost) {
className += " ghost"; className += " ghost";
draggable = false;
} }
return div({ return div({
className: className, className: className,
@ -907,9 +918,9 @@ module.exports = recl({
}, rece(ItemComponent, { }, rece(ItemComponent, {
item: item, item: item,
index: index, index: index,
draggable: draggable,
_focus: _this._focus, _focus: _this._focus,
title_keyDown: _this.title_keyDown, title_keyDown: _this.title_keyDown,
draggable: _this.state.canSort,
_dragStart: _this._dragStart, _dragStart: _this._dragStart,
_dragEnd: _this._dragEnd _dragEnd: _this._dragEnd
})); }));
@ -1557,7 +1568,7 @@ WorkStore = assign({}, EventEmitter.prototype, {
list.reverse(); list.reverse();
} }
} }
if (!(((_filters.creator != null) && _filters.owner !== urb.ship) || (_filters.done != null))) { if (!(((_filters.creator != null) && _filters.owner !== urb.ship) || _filters.done === true)) {
ghost = $.extend({ ghost = $.extend({
ghost: true, ghost: true,
version: -1 version: -1

View File

@ -64,7 +64,8 @@ WorkStore = assign {},EventEmitter.prototype,{
break break
list = _.sortBy list,k,k list = _.sortBy list,k,k
if v is -1 then list.reverse() if v is -1 then list.reverse()
unless (_filters.creator? and _filters.owner isnt urb.ship) or _filters.done? unless (_filters.creator? and _filters.owner isnt urb.ship) or
_filters.done is true
ghost = $.extend {ghost:true,version:-1}, _ghost ghost = $.extend {ghost:true,version:-1}, _ghost
if _filters.tags then ghost.tags = _filters.tags if _filters.tags then ghost.tags = _filters.tags
if _filters.audience then ghost.audience = _filters.audience if _filters.audience then ghost.audience = _filters.audience