Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/devextreme/js/ui/gantt/ui.gantt.data.option.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class DataOption extends Component {
this._optionName = optionName;
this._getLoadPanel = getLoadPanel;
this._dataSourceChangedCallback = dataSourceChangedCallback;
this._pendingReloadRequestInfo = null;
}
insert(data, callback, errorCallback) {
this._showLoadPanel();
Expand Down Expand Up @@ -78,6 +79,46 @@ class DataOption extends Component {
_getItems() {
return this._getStore()._array || this._dataSource.items();
}
_createPendingReloadRequestPromise() {
let resolve = null;

let promise = new Promise(_resolve => {
resolve = _resolve;
});

promise = promise.then(() => {
return new Promise(_resolve => {
this._reloadDataSource()
.done(data => {
_resolve(data);
});
});
});

return { promise, resolve, counter: 1 };
}
_addPendingReloadRequest() {
if(!this._pendingReloadRequestInfo) {
this._pendingReloadRequestInfo = this._createPendingReloadRequestPromise();
} else {
this._pendingReloadRequestInfo.counter++;
}
}
_resolvePendingReloadRequests() {
if(!this._pendingReloadRequestInfo) { return; }

this._pendingReloadRequestInfo.counter--;
if(this._pendingReloadRequestInfo.counter <= 0) {
this._pendingReloadRequestInfo.resolve();
}

return this._pendingReloadRequestInfo.promise
.then(data => {
this._pendingReloadRequestInfo = null;

return data;
});
}
_reloadDataSource() {
return this._dataSource.load();
}
Expand Down
13 changes: 10 additions & 3 deletions packages/devextreme/js/ui/gantt/ui.gantt.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ class Gantt extends Widget {
_onRecordInserted(optionName, record, callback) {
const dataOption = this[`_${optionName}Option`];
if(dataOption) {
dataOption._addPendingReloadRequest();

const data = GanttHelper.getStoreObject(this.option(optionName), record);
const isTaskInsert = optionName === GANTT_TASKS;
if(isTaskInsert) {
Expand All @@ -328,7 +330,8 @@ class Gantt extends Widget {
this._executeFuncSetters(optionName, record, insertedId);
this._dataProcessingHelper.addCompletionAction(() => { this._actionsManager.raiseInsertedAction(optionName, data, insertedId); }, true, isTaskInsert);
this._ganttTreeList.saveExpandedKeys();
dataOption._reloadDataSource().done(data => {

dataOption._resolvePendingReloadRequests().then(data => {
if(isTaskInsert) {
this._ganttTreeList.onTaskInserted(insertedId, record.parentId);
}
Expand All @@ -340,6 +343,8 @@ class Gantt extends Widget {
const dataOption = this[`_${optionName}Option`];
const isTaskUpdated = optionName === GANTT_TASKS;
if(dataOption) {
dataOption._addPendingReloadRequest();

const data = this._mappingHelper.convertCoreToMappedData(optionName, values);
const hasCustomFieldsData = isTaskUpdated && this._customFieldsManager.cache.hasData(key);
if(hasCustomFieldsData) {
Expand All @@ -349,17 +354,19 @@ class Gantt extends Widget {
this._executeFuncSetters(optionName, values, key);
this._ganttTreeList.saveExpandedKeys();
this._dataProcessingHelper.addCompletionAction(() => { this._actionsManager.raiseUpdatedAction(optionName, data, key); }, true, isTaskUpdated);
dataOption._reloadDataSource();
dataOption._resolvePendingReloadRequests();
});
}
}
_onRecordRemoved(optionName, key, data) {
const dataOption = this[`_${optionName}Option`];
if(dataOption) {
dataOption._addPendingReloadRequest();

dataOption.remove(key, () => {
this._ganttTreeList.saveExpandedKeys();
this._dataProcessingHelper.addCompletionAction(() => { this._actionsManager.raiseDeletedAction(optionName, key, this._mappingHelper.convertCoreToMappedData(optionName, data)); }, true, optionName === GANTT_TASKS);
dataOption._reloadDataSource();
dataOption._resolvePendingReloadRequests();
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,40 @@ const moduleConfig = {
};

QUnit.module('Actions', moduleConfig, () => {
test('expand', function(assert) {
test('expand', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
const expandedElement = this.$element.find(Consts.TREELIST_EXPANDED_SELECTOR).first();
expandedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);
});
test('collapse', function(assert) {
test('collapse', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
const collapsedElement = this.$element.find(Consts.TREELIST_COLLAPSED_SELECTOR).first();
collapsedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
});
test('expand/collapse All', function(assert) {
test('expand/collapse All', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
this.instance._collapseAll();
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);

this.clock.tick(10);
await this.clock.tickAsync(10);
this.instance._expandAll();
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
});
test('collapse and expand after inserting', function(assert) {
test('collapse and expand after inserting', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.instance.option('editing.enabled', true);
this.clock.tick(10);
await this.clock.tickAsync(10);

const tasksCount = data.tasks.length;
const newStart = new Date('2019-02-21');
Expand All @@ -66,7 +66,7 @@ QUnit.module('Actions', moduleConfig, () => {
parentId: '2'
};
getGanttViewCore(this.instance).commandManager.createTaskCommand.execute(taskData);
this.clock.tick(10);
await this.clock.tickAsync(10);

assert.equal(data.tasks.length, tasksCount + 1, 'new task was created in ds');
const createdTask = data.tasks[data.tasks.length - 1];
Expand All @@ -76,20 +76,20 @@ QUnit.module('Actions', moduleConfig, () => {

const expandedElement = this.$element.find(Consts.TREELIST_EXPANDED_SELECTOR).eq(1);
expandedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);

const collapsedElement = this.$element.find(Consts.TREELIST_COLLAPSED_SELECTOR).first();
collapsedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
});

test('collapse and expand after inserting in auto update mode', function(assert) {
test('collapse and expand after inserting in auto update mode', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.instance.option('editing.enabled', true);
this.instance.option('validation.autoUpdateParentTasks', true);
this.clock.tick(10);
await this.clock.tickAsync(10);

const tasksCount = data.tasks.length;
const newStart = new Date('2019-02-21');
Expand All @@ -103,7 +103,7 @@ QUnit.module('Actions', moduleConfig, () => {
parentId: '2'
};
getGanttViewCore(this.instance).commandManager.createTaskCommand.execute(taskData);
this.clock.tick(10);
await this.clock.tickAsync(10);

assert.equal(data.tasks.length, tasksCount + 1, 'new task was created in ds');
const createdTask = data.tasks[data.tasks.length - 1];
Expand All @@ -113,23 +113,23 @@ QUnit.module('Actions', moduleConfig, () => {

const expandedElement = this.$element.find(Consts.TREELIST_EXPANDED_SELECTOR).eq(1);
expandedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);

const collapsedElement = this.$element.find(Consts.TREELIST_COLLAPSED_SELECTOR).first();
collapsedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
});

test('collapse and check state after validation option changed (T997932)', function(assert) {
test('collapse and check state after validation option changed (T997932)', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.instance.option('editing.enabled', true);
this.clock.tick(10);
await this.clock.tickAsync(10);

const expandedElement = this.$element.find(Consts.TREELIST_EXPANDED_SELECTOR).eq(1);
expandedElement.trigger('dxclick');
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);

this.instance.option('validation.autoUpdateParentTasks', true);
Expand All @@ -143,9 +143,9 @@ QUnit.module('Actions', moduleConfig, () => {
assert.strictEqual($parentTasks.length, 0, 'not parent tasks');
});

test('move splitter', function(assert) {
test('move splitter', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);

const splitterWrapper = this.$element.find(Consts.SPLITTER_WRAPPER_SELECTOR);
const splitter = this.$element.find(Consts.SPLITTER_SELECTOR);
Expand Down Expand Up @@ -203,11 +203,11 @@ QUnit.module('Actions', moduleConfig, () => {
assert.equal(ganttView.width(), splitter.width());
assert.equal(parseFloat(splitterWrapper.css('left')) + parseFloat(splitter.css('margin-left')), splitterContainerWrapperWidth - splitter.width(), 'Splitter has not cross the right side');
});
test('splitter should resize panels with 2 gantts (T1091934)', function(assert) {
test('splitter should resize panels with 2 gantts (T1091934)', async function(assert) {
this.createInstance(options.allSourcesOptions);
const $element2 = $('<div>').attr('id', 'gantt2').appendTo('#qunit-fixture');
const instance2 = $element2.dxGantt().dxGantt('instance');
this.clock.tick(10);
await this.clock.tickAsync(10);

[this.$element, $element2].forEach(($element, index) => {
const splitterWrapper = $element.find(Consts.SPLITTER_WRAPPER_SELECTOR);
Expand Down Expand Up @@ -270,60 +270,60 @@ QUnit.module('Actions', moduleConfig, () => {
instance2.dispose();
$element2.remove();
});
test('expand api', function(assert) {
test('expand api', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);
this.clock.tick(10);
await this.clock.tickAsync(10);
this.instance.collapseAll();
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);

this.clock.tick(10);
await this.clock.tickAsync(10);
this.instance.expandAll();
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);

this.instance.expandAllToLevel(1);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);

this.instance.expandToTask(7);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);

this.instance.expandToTask(2);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);

this.instance.expandTask(2);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, data.tasks.length - 1);

this.instance.collapseTask(2);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);
});
test('showResources()', function(assert) {
test('showResources()', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_RESOURCES_SELECTOR).length, data.resourceAssignments.length);
this.instance.showResources(false);
assert.equal(this.$element.find(Consts.TASK_RESOURCES_SELECTOR).length, 0);
this.instance.showResources(true);
assert.equal(this.$element.find(Consts.TASK_RESOURCES_SELECTOR).length, data.resourceAssignments.length);
});
test('showDependencies()', function(assert) {
test('showDependencies()', async function(assert) {
this.createInstance(options.allSourcesOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_ARROW_SELECTOR).length, data.dependencies.length);
this.instance.showDependencies(false);
assert.equal(this.$element.find(Consts.TASK_ARROW_SELECTOR).length, 0);
this.instance.showDependencies(true);
assert.equal(this.$element.find(Consts.TASK_ARROW_SELECTOR).length, data.dependencies.length);
});

test('collapse and check state after custom field updating', function(assert) {
test('collapse and check state after custom field updating', async function(assert) {
const taskOptions = {
tasks: {
dataSource: [
Expand All @@ -341,10 +341,10 @@ QUnit.module('Actions', moduleConfig, () => {
};

this.createInstance(taskOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);
this.instance._collapseAll();
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);

const customText = 'new';
Expand All @@ -353,11 +353,11 @@ QUnit.module('Actions', moduleConfig, () => {
};

this.instance.updateTask('1', data);
this.clock.tick(500);
await this.clock.tickAsync(500);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);
});

test('collapse and check state after custom field updating (autoUpdateParentTasks=true)', function(assert) {
test('collapse and check state after custom field updating (autoUpdateParentTasks=true)', async function(assert) {
const taskOptions = {
tasks: {
dataSource: [
Expand All @@ -375,10 +375,10 @@ QUnit.module('Actions', moduleConfig, () => {
};

this.createInstance(taskOptions);
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 2);
this.instance._collapseAll();
this.clock.tick(10);
await this.clock.tickAsync(10);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);

const customText = 'new';
Expand All @@ -387,7 +387,7 @@ QUnit.module('Actions', moduleConfig, () => {
};

this.instance.updateTask('1', data);
this.clock.tick(500);
await this.clock.tickAsync(500);
assert.equal(this.$element.find(Consts.TASK_WRAPPER_SELECTOR).length, 1);
});
});
Loading
Loading