Browse Source

fix(timeline): #2720 Problems with option editable (#2743)

Clean up and centralise edit status for Timeline Items.
revert-2743-editable-option-2017-02-16
Brad Hards 7 years ago
committed by Alexander Wunschik
parent
commit
ceb698626a
6 changed files with 162 additions and 49 deletions
  1. +1
    -4
      lib/timeline/component/item/BoxItem.js
  2. +32
    -27
      lib/timeline/component/item/Item.js
  3. +1
    -5
      lib/timeline/component/item/PointItem.js
  4. +1
    -4
      lib/timeline/component/item/RangeItem.js
  5. +112
    -9
      test/PointItem.test.js
  6. +15
    -0
      test/TestSupport.js

+ 1
- 4
lib/timeline/component/item/BoxItem.js View File

@ -121,10 +121,7 @@ BoxItem.prototype.redraw = function() {
this._updateDataAttributes(this.dom.box);
this._updateStyle(this.dom.box);
var editable = (this.options.editable.updateTime ||
this.options.editable.updateGroup ||
this.editable === true) &&
this.editable !== false;
var editable = (this.editable.updateTime || this.editable.updateGroup);
// update class
var className = (this.data.className? ' ' + this.data.className : '') +

+ 32
- 27
lib/timeline/component/item/Item.js View File

@ -31,19 +31,7 @@ function Item (data, conversion, options) {
this.height = null;
this.editable = null;
if (this.data && this.data.hasOwnProperty('editable')){
if(typeof this.data.editable === 'boolean') {
this.editable = {
updateTime: this.data.editable,
updateGroup: this.data.editable,
remove: this.data.editable
}
}
else if(typeof options.editable === 'object') {
this.editable = {};
util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, options.editable);
};
}
this._updateEditStatus();
}
Item.prototype.stack = true;
@ -77,21 +65,8 @@ Item.prototype.setData = function(data) {
this.parent.itemSet._moveToGroup(this, data.group);
}
if (data.hasOwnProperty('editable')){
if (typeof data.editable === 'boolean') {
this.editable = {
updateTime: this.data.editable,
updateGroup: this.data.editable,
remove: this.data.editable
}
}
else if(typeof this.options.editable === 'object') {
this.editable = {};
util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, data.editable);
}
}
this.data = data;
this._updateEditStatus();
this.dirty = true;
if (this.displayed) this.redraw();
};
@ -461,6 +436,36 @@ Item.prototype._contentToString = function (content) {
return content;
};
/**
* Update the editability of this item.
*/
Item.prototype._updateEditStatus = function() {
if (this.options) {
if(typeof this.options.editable === 'boolean') {
this.editable = {
updateTime: this.options.editable,
updateGroup: this.options.editable,
remove: this.options.editable
};
} else if(typeof this.options.editable === 'object') {
this.editable = {};
util.selectiveExtend(['updateTime', 'updateGroup', 'remove'], this.editable, this.options.editable);
};
}
// Item data overrides, except if options.editable.overrideItems is set.
if (!this.options || !(this.options.editable) || (this.options.editable.overrideItems !== true)) {
if (this.data) {
if (typeof this.data.editable === 'boolean') {
this.editable = {
updateTime: this.data.editable,
updateGroup: this.data.editable,
remove: this.data.editable
}
}
}
}
};
/**
* Return the width of the item left from its start date
* @return {number}

+ 1
- 5
lib/timeline/component/item/PointItem.js View File

@ -99,11 +99,7 @@ PointItem.prototype.redraw = function() {
this._updateDataAttributes(this.dom.point);
this._updateStyle(this.dom.point);
var editable = (this.options.editable.updateTime ||
this.options.editable.updateGroup ||
this.editable === true) &&
this.editable !== false;
var editable = (this.editable.updateTime || this.editable.updateGroup);
// update class
var className = (this.data.className ? ' ' + this.data.className : '') +
(this.selected ? ' vis-selected' : '') +

+ 1
- 4
lib/timeline/component/item/RangeItem.js View File

@ -103,10 +103,7 @@ RangeItem.prototype.redraw = function() {
this._updateDataAttributes(this.dom.box);
this._updateStyle(this.dom.box);
var editable = (this.options.editable.updateTime ||
this.options.editable.updateGroup ||
this.editable === true) &&
this.editable !== false;
var editable = (this.editable.updateTime || this.editable.updateGroup);
// update class
var className = (this.data.className ? (' ' + this.data.className) : '') +

+ 112
- 9
test/PointItem.test.js View File

@ -10,16 +10,15 @@ var TestSupport = require('./TestSupport');
describe('Timeline PointItem', function () {
jsdom();
var now = moment();
it('should initialize with minimal data', function() {
var now = moment().toDate();
var pointItem = new PointItem({start: now}, null, null);
var pointItem = new PointItem({start: now.toDate()}, null, null);
assert.equal(pointItem.props.content.height, 0);
assert.equal(pointItem.data.start, now);
assert.deepEqual(pointItem.data.start, now.toDate());
});
it('should have a default width of 0', function() {
var now = moment().toDate();
var pointItem = new PointItem({start: now}, null, null);
assert.equal(pointItem.getWidthRight(), 0);
assert.equal(pointItem.getWidthLeft(), 0);
@ -30,7 +29,6 @@ describe('Timeline PointItem', function () {
});
it('should be visible if the range is during', function() {
var now = moment();
var range = new Range(TestSupport.buildSimpleTimelineRangeBody());
range.start = now.clone().add(-1, 'second');
range.end = range.start.clone().add(1, 'hour');
@ -39,7 +37,6 @@ describe('Timeline PointItem', function () {
});
it('should not be visible if the range is after', function() {
var now = moment();
var range = new Range(TestSupport.buildSimpleTimelineRangeBody());
range.start = now.clone().add(1, 'second');
range.end = range.start.clone().add(1, 'hour');
@ -58,8 +55,114 @@ describe('Timeline PointItem', function () {
it('should be visible for a "now" point with a default range', function() {
var range = new Range(TestSupport.buildSimpleTimelineRangeBody());
var now = moment().toDate();
var pointItem = new PointItem({start: now}, null, null);
var pointItem = new PointItem({start: now.toDate()}, null, null);
assert(pointItem.isVisible(range));
});
});
it('should redraw() and then not be dirty', function() {
var pointItem = new PointItem({start: now.toDate()}, null, {editable: false});
pointItem.setParent(TestSupport.buildMockItemSet());
assert(pointItem.dirty);
pointItem.redraw();
assert(!pointItem.dirty);
});
it('should redraw() and then have point attached to its parent', function() {
var pointItem = new PointItem({start: now.toDate()}, null, {editable: false});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
assert(!parent.dom.foreground.hasChildNodes());
pointItem.redraw();
assert(parent.dom.foreground.hasChildNodes());
});
it('should redraw() and then have the correct classname for a non-editable item', function() {
var pointItem = new PointItem({start: now.toDate(), editable: false}, null, {editable: false});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-readonly");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-readonly");
});
it('should redraw() and then have the correct classname for an editable item (with object option)', function() {
var pointItem = new PointItem({start: now.toDate()}, null, {editable: {updateTime: true, updateGroup: false}});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-editable");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-editable");
});
it('should redraw() and then have the correct classname for an editable item (with boolean option)', function() {
var pointItem = new PointItem({start: now.toDate()}, null, {editable: true});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-editable");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-editable");
});
it('should redraw() and then have the correct classname for an editable:false override item (with boolean option)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: false}, null, {editable: true});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-readonly");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-readonly");
});
it('should redraw() and then have the correct classname for an editable:true override item (with boolean option)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: true}, null, {editable: false});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-editable");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-editable");
});
it('should redraw() and then have the correct classname for an editable:false override item (with object option)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: false}, null, {editable: {updateTime: true, updateGroup: false}});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-readonly");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-readonly");
});
it('should redraw() and then have the correct classname for an editable:false override item (with object option for group change)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: false}, null, {editable: {updateTime: false, updateGroup: true}});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-readonly");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-readonly");
});
it('should redraw() and then have the correct classname for an editable:true override item (with object option)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: true}, null, {editable: {updateTime: false, updateGroup: false}});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-editable");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-editable");
});
it('should redraw() and then have the correct classname for an editable:true non-override item (with object option)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: true}, null, {editable: {updateTime: false, updateGroup: false, overrideItems: true}});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-readonly");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-readonly");
});
it('should redraw() and then have the correct classname for an editable:false non-override item (with object option)', function() {
var pointItem = new PointItem({start: now.toDate(), editable: false}, null, {editable: {updateTime: true, updateGroup: false, overrideItems: true}});
var parent = TestSupport.buildMockItemSet();
pointItem.setParent(parent);
pointItem.redraw();
assert.equal(pointItem.dom.dot.className, "vis-item vis-dot vis-editable");
assert.equal(pointItem.dom.point.className, "vis-item vis-point vis-editable");
});
});

+ 15
- 0
test/TestSupport.js View File

@ -1,5 +1,20 @@
var vis = require('../dist/vis');
var DataSet = vis.DataSet;
module.exports = {
buildMockItemSet: function() {
var itemset = {
dom: {
foreground: document.createElement('div'),
content: document.createElement('div')
},
itemSet: {
itemsData: new DataSet()
}
};
return itemset;
},
buildSimpleTimelineRangeBody: function () {
var body = {
dom: {

Loading…
Cancel
Save