/core/modules/quickedit/js/models/EntityModel.js
JavaScript | 329 lines | 264 code | 59 blank | 6 comment | 51 complexity | 14f098c4e6e50b7a00c3e8b99b338550 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
- /**
- * DO NOT EDIT THIS FILE.
- * See the following change record for more information,
- * https://www.drupal.org/node/2815083
- * @preserve
- **/
- (function (_, $, Backbone, Drupal) {
- 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';
- }
- 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() {}
- }, {
- 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);