All files / web/bundles/pimui/js/form/common state.js

87.5% Statements 28/32
56.25% Branches 9/16
83.33% Functions 10/12
87.5% Lines 28/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168                  546x                                     546x                   708x           708x 708x 708x   708x             706x 706x 706x 706x 706x 706x   706x   706x             672x             4413x 705x     4413x           4413x             1287x             582x 582x             1x 1x                       123x 1x                   4537x                                                                  
'use strict';
/**
 * State manager extension
 *
 * @author    Julien Sanchez <julien@akeneo.com>
 * @author    Filips Alpe <filips@akeneo.com>
 * @copyright 2015 Akeneo SAS (http://www.akeneo.com)
 * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
define(
    [
        'jquery',
        'underscore',
        'oro/translator',
        'backbone',
        'pim/dialog',
        'pim/form',
        'pim/template/form/state'
    ],
    function (
        $,
        _,
        __,
        Backbone,
        Dialog,
        BaseForm,
        template
    ) {
        return BaseForm.extend({
            className: 'updated-status',
            template: _.template(template),
            state: null,
            linkSelector: 'a[href^="/"]:not(".no-hash")',
 
            /**
             * {@inheritdoc}
             */
            initialize: function (meta) {
                this.config = _.extend({}, {
                    confirmationMessage: 'pim_enrich.entity.fallback.module.edit.discard_changes',
                    confirmationTitle: 'pim_enrich.entity.fallback.module.edit.leave',
                    message: 'pim_common.entity_updated'
                }, meta.config);
 
                this.confirmationMessage = __(this.config.confirmationMessage, {entity: __(this.config.entity)});
                this.confirmationTitle   = __(this.config.confirmationTitle);
                this.message             = __(this.config.message);
 
                BaseForm.prototype.initialize.apply(this, arguments);
            },
 
            /**
             * @inheritdoc
             */
            configure: function () {
                this.listenTo(this.getRoot(), 'pim_enrich:form:entity:update_state', this.render);
                this.listenTo(this.getRoot(), 'pim_enrich:form:entity:post_update', this.render);
                this.listenTo(this.getRoot(), 'pim_enrich:form:entity:post_fetch', this.collectAndRender);
                this.listenTo(this.getRoot(), 'pim_enrich:form:state:confirm', this.onConfirmation);
                this.listenTo(this.getRoot(), 'pim_enrich:form:can-leave', this.linkClicked);
                $(window).on('beforeunload', this.beforeUnload.bind(this));
 
                Backbone.Router.prototype.on('route', this.unbindEvents);
 
                return BaseForm.prototype.configure.apply(this, arguments);
            },
 
            /**
             * Detach event listeners
             */
            unbindEvents: function () {
                $(window).off('beforeunload', this.beforeUnload);
            },
 
            /**
             * @inheritdoc
             */
            render: function () {
                if (null === this.state || undefined === this.state) {
                    this.collectState();
                }
 
                this.$el.html(
                    this.template({
                        message: this.message
                    })
                ).css('opacity', this.hasModelChanged() ? 1 : 0);
 
                return this;
            },
 
            /**
             * Store a stringified representation of the form model for further comparisons
             */
            collectState: function () {
                this.state = JSON.stringify(this.getFormData());
            },
 
            /**
             * Force collect state and re-render
             */
            collectAndRender: function () {
                this.collectState();
                this.render();
            },
 
            /**
             * Callback triggered on beforeunload event
             */
            beforeUnload: function () {
                Eif (this.hasModelChanged()) {
                    return this.confirmationMessage;
                }
            },
 
            /**
             * Callback triggered on any link click event to ask confirmation if there are unsaved changes
             *
             * @param {Object} event
             *
             * @return {boolean}
             */
            linkClicked: function (event) {
                if (this.hasModelChanged()) {
                    event.canLeave = confirm(this.confirmationMessage);
                }
            },
 
            /**
             * Check if current form model has changed compared to the stored model state
             *
             * @return {boolean}
             */
            hasModelChanged: function () {
                return this.state !== JSON.stringify(this.getFormData());
            },
 
            /**
             * Display a dialog modal to ask an action confirmation if model has changed
             *
             * @param {string} message
             * @param {string} title
             * @param {function} action
             */
            confirmAction: function (message, title, action) {
                if (this.hasModelChanged()) {
                    Dialog.confirm(message, title, action);
                } else {
                    action();
                }
            },
 
            /**
             * Callback that can be triggered from anywhere to ask an action confirmation
             *
             * @param {Object} event
             */
            onConfirmation: function (event) {
                this.confirmAction(
                    event.message || this.confirmationMessage,
                    event.title || this.confirmationTitle,
                    event.action
                );
            }
        });
    }
);