335 lines
10 KiB
JavaScript
335 lines
10 KiB
JavaScript
/**
|
|
* DO NOT EDIT THIS FILE.
|
|
* See the following change record for more information,
|
|
* https://www.drupal.org/node/2815083
|
|
* @preserve
|
|
**/
|
|
|
|
(function (_, $, Backbone, Drupal) {
|
|
|
|
'use strict';
|
|
|
|
Drupal.quickedit.EntityModel = Drupal.quickedit.BaseModel.extend({
|
|
defaults: {
|
|
el: null,
|
|
|
|
entityID: null,
|
|
|
|
entityInstanceID: null,
|
|
|
|
id: null,
|
|
|
|
label: null,
|
|
|
|
fields: null,
|
|
|
|
isActive: false,
|
|
|
|
inTempStore: false,
|
|
|
|
isDirty: false,
|
|
|
|
isCommitting: false,
|
|
|
|
state: 'closed',
|
|
|
|
fieldsInTempStore: [],
|
|
|
|
reload: false
|
|
},
|
|
|
|
initialize: function initialize() {
|
|
this.set('fields', new Drupal.quickedit.FieldCollection());
|
|
|
|
this.listenTo(this, 'change:state', this.stateChange);
|
|
|
|
this.listenTo(this.get('fields'), 'change:state', this.fieldStateChange);
|
|
|
|
Drupal.quickedit.BaseModel.prototype.initialize.call(this);
|
|
},
|
|
|
|
stateChange: function stateChange(entityModel, state, options) {
|
|
var to = state;
|
|
switch (to) {
|
|
case 'closed':
|
|
this.set({
|
|
isActive: false,
|
|
inTempStore: false,
|
|
isDirty: false
|
|
});
|
|
break;
|
|
|
|
case 'launching':
|
|
break;
|
|
|
|
case 'opening':
|
|
entityModel.get('fields').each(function (fieldModel) {
|
|
fieldModel.set('state', 'candidate', options);
|
|
});
|
|
break;
|
|
|
|
case 'opened':
|
|
this.set('isActive', true);
|
|
break;
|
|
|
|
case 'committing':
|
|
var fields = this.get('fields');
|
|
|
|
fields.chain().filter(function (fieldModel) {
|
|
return _.intersection([fieldModel.get('state')], ['active']).length;
|
|
}).each(function (fieldModel) {
|
|
fieldModel.set('state', 'candidate');
|
|
});
|
|
|
|
fields.chain().filter(function (fieldModel) {
|
|
return _.intersection([fieldModel.get('state')], Drupal.quickedit.app.changedFieldStates).length;
|
|
}).each(function (fieldModel) {
|
|
fieldModel.set('state', 'saving');
|
|
});
|
|
break;
|
|
|
|
case 'deactivating':
|
|
var changedFields = this.get('fields').filter(function (fieldModel) {
|
|
return _.intersection([fieldModel.get('state')], ['changed', 'invalid']).length;
|
|
});
|
|
|
|
if ((changedFields.length || this.get('fieldsInTempStore').length) && !options.saved && !options.confirmed) {
|
|
this.set('state', 'opened', { confirming: true });
|
|
|
|
_.defer(function () {
|
|
Drupal.quickedit.app.confirmEntityDeactivation(entityModel);
|
|
});
|
|
} else {
|
|
var invalidFields = this.get('fields').filter(function (fieldModel) {
|
|
return _.intersection([fieldModel.get('state')], ['invalid']).length;
|
|
});
|
|
|
|
entityModel.set('reload', this.get('fieldsInTempStore').length || invalidFields.length);
|
|
|
|
entityModel.get('fields').each(function (fieldModel) {
|
|
if (_.intersection([fieldModel.get('state')], ['candidate', 'highlighted']).length) {
|
|
fieldModel.trigger('change:state', fieldModel, fieldModel.get('state'), options);
|
|
} else {
|
|
fieldModel.set('state', 'candidate', options);
|
|
}
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'closing':
|
|
options.reason = 'stop';
|
|
this.get('fields').each(function (fieldModel) {
|
|
fieldModel.set({
|
|
inTempStore: false,
|
|
state: 'inactive'
|
|
}, options);
|
|
});
|
|
break;
|
|
}
|
|
},
|
|
|
|
_updateInTempStoreAttributes: function _updateInTempStoreAttributes(entityModel, fieldModel) {
|
|
var current = fieldModel.get('state');
|
|
var previous = fieldModel.previous('state');
|
|
var fieldsInTempStore = entityModel.get('fieldsInTempStore');
|
|
|
|
if (current === 'saved') {
|
|
entityModel.set('inTempStore', true);
|
|
|
|
fieldModel.set('inTempStore', true);
|
|
|
|
fieldsInTempStore.push(fieldModel.get('fieldID'));
|
|
fieldsInTempStore = _.uniq(fieldsInTempStore);
|
|
entityModel.set('fieldsInTempStore', fieldsInTempStore);
|
|
} else if (current === 'candidate' && previous === 'inactive') {
|
|
fieldModel.set('inTempStore', _.intersection([fieldModel.get('fieldID')], fieldsInTempStore).length > 0);
|
|
}
|
|
},
|
|
|
|
fieldStateChange: function fieldStateChange(fieldModel, state) {
|
|
var entityModel = this;
|
|
var fieldState = state;
|
|
|
|
switch (this.get('state')) {
|
|
case 'closed':
|
|
case 'launching':
|
|
break;
|
|
|
|
case 'opening':
|
|
_.defer(function () {
|
|
entityModel.set('state', 'opened', {
|
|
'accept-field-states': Drupal.quickedit.app.readyFieldStates
|
|
});
|
|
});
|
|
break;
|
|
|
|
case 'opened':
|
|
if (fieldState === 'changed') {
|
|
entityModel.set('isDirty', true);
|
|
} else {
|
|
this._updateInTempStoreAttributes(entityModel, fieldModel);
|
|
}
|
|
break;
|
|
|
|
case 'committing':
|
|
if (fieldState === 'invalid') {
|
|
_.defer(function () {
|
|
entityModel.set('state', 'opened', { reason: 'invalid' });
|
|
});
|
|
} else {
|
|
this._updateInTempStoreAttributes(entityModel, fieldModel);
|
|
}
|
|
|
|
var options = {
|
|
'accept-field-states': Drupal.quickedit.app.readyFieldStates
|
|
};
|
|
if (entityModel.set('isCommitting', true, options)) {
|
|
entityModel.save({
|
|
success: function success() {
|
|
entityModel.set({
|
|
state: 'deactivating',
|
|
isCommitting: false
|
|
}, { saved: true });
|
|
},
|
|
error: function error() {
|
|
entityModel.set('isCommitting', false);
|
|
|
|
entityModel.set('state', 'opened', { reason: 'networkerror' });
|
|
|
|
var message = Drupal.t('Your changes to <q>@entity-title</q> could not be saved, either due to a website problem or a network connection problem.<br>Please try again.', { '@entity-title': entityModel.get('label') });
|
|
Drupal.quickedit.util.networkErrorModal(Drupal.t('Network problem!'), message);
|
|
}
|
|
});
|
|
}
|
|
break;
|
|
|
|
case 'deactivating':
|
|
_.defer(function () {
|
|
entityModel.set('state', 'closing', {
|
|
'accept-field-states': Drupal.quickedit.app.readyFieldStates
|
|
});
|
|
});
|
|
break;
|
|
|
|
case 'closing':
|
|
_.defer(function () {
|
|
entityModel.set('state', 'closed', {
|
|
'accept-field-states': ['inactive']
|
|
});
|
|
});
|
|
break;
|
|
}
|
|
},
|
|
|
|
save: function save(options) {
|
|
var entityModel = this;
|
|
|
|
var entitySaverAjax = Drupal.ajax({
|
|
url: Drupal.url('quickedit/entity/' + entityModel.get('entityID')),
|
|
error: function error() {
|
|
options.error.call(entityModel);
|
|
}
|
|
});
|
|
|
|
entitySaverAjax.commands.quickeditEntitySaved = function (ajax, response, status) {
|
|
entityModel.get('fields').each(function (fieldModel) {
|
|
fieldModel.set('inTempStore', false);
|
|
});
|
|
entityModel.set('inTempStore', false);
|
|
entityModel.set('fieldsInTempStore', []);
|
|
|
|
if (options.success) {
|
|
options.success.call(entityModel);
|
|
}
|
|
};
|
|
|
|
entitySaverAjax.execute();
|
|
},
|
|
|
|
validate: function validate(attrs, options) {
|
|
var acceptedFieldStates = options['accept-field-states'] || [];
|
|
|
|
var currentState = this.get('state');
|
|
var nextState = attrs.state;
|
|
if (currentState !== nextState) {
|
|
if (_.indexOf(this.constructor.states, nextState) === -1) {
|
|
return '"' + nextState + '" is an invalid state';
|
|
}
|
|
|
|
if (!this._acceptStateChange(currentState, nextState, options)) {
|
|
return 'state change not accepted';
|
|
} else if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) {
|
|
return 'state change not accepted because fields are not in acceptable state';
|
|
}
|
|
}
|
|
|
|
var currentIsCommitting = this.get('isCommitting');
|
|
var nextIsCommitting = attrs.isCommitting;
|
|
if (currentIsCommitting === false && nextIsCommitting === true) {
|
|
if (!this._fieldsHaveAcceptableStates(acceptedFieldStates)) {
|
|
return 'isCommitting change not accepted because fields are not in acceptable state';
|
|
}
|
|
} else if (currentIsCommitting === true && nextIsCommitting === true) {
|
|
return 'isCommitting is a mutex, hence only changes are allowed';
|
|
}
|
|
},
|
|
|
|
_acceptStateChange: function _acceptStateChange(from, to, context) {
|
|
var accept = true;
|
|
|
|
if (!this.constructor.followsStateSequence(from, to)) {
|
|
accept = false;
|
|
|
|
if (from === 'closing' && to === 'closed') {
|
|
accept = true;
|
|
} else if (from === 'committing' && to === 'opened' && context.reason && (context.reason === 'invalid' || context.reason === 'networkerror')) {
|
|
accept = true;
|
|
} else if (from === 'deactivating' && to === 'opened' && context.confirming) {
|
|
accept = true;
|
|
} else if (from === 'opened' && to === 'deactivating' && context.confirmed) {
|
|
accept = true;
|
|
}
|
|
}
|
|
|
|
return accept;
|
|
},
|
|
|
|
_fieldsHaveAcceptableStates: function _fieldsHaveAcceptableStates(acceptedFieldStates) {
|
|
var accept = true;
|
|
|
|
if (acceptedFieldStates.length > 0) {
|
|
var fieldStates = this.get('fields').pluck('state') || [];
|
|
|
|
if (_.difference(fieldStates, acceptedFieldStates).length) {
|
|
accept = false;
|
|
}
|
|
}
|
|
|
|
return accept;
|
|
},
|
|
|
|
destroy: function destroy(options) {
|
|
Drupal.quickedit.BaseModel.prototype.destroy.call(this, options);
|
|
|
|
this.stopListening();
|
|
|
|
this.get('fields').reset();
|
|
},
|
|
|
|
sync: function sync() {
|
|
return;
|
|
}
|
|
|
|
}, {
|
|
states: ['closed', 'launching', 'opening', 'opened', 'committing', 'deactivating', 'closing'],
|
|
|
|
followsStateSequence: function followsStateSequence(from, to) {
|
|
return _.indexOf(this.states, from) < _.indexOf(this.states, to);
|
|
}
|
|
|
|
});
|
|
|
|
Drupal.quickedit.EntityCollection = Backbone.Collection.extend({
|
|
model: Drupal.quickedit.EntityModel
|
|
});
|
|
})(_, jQuery, Backbone, Drupal); |