Test Setup Failed
Push — master ( 71bdab...214430 )
by
unknown
08:34 queued 04:29
created

src/Oro/Bundle/UIBundle/Resources/public/js/app/components/widget-component.js   B

Complexity

Total Complexity 37
Complexity/F 2.31

Size

Lines of Code 222
Function Count 16

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
wmc 37
c 0
b 0
f 0
nc 48
mnd 2
bc 37
fnc 16
dl 0
loc 222
rs 8.6
bpm 2.3125
cpm 2.3125
noi 0
1
define(function(require) {
2
    'use strict';
3
4
    var WidgetComponent;
5
    var $ = require('jquery');
6
    var _ = require('underscore');
7
    var BaseComponent = require('oroui/js/app/components/base/component');
8
    var mediator = require('oroui/js/mediator');
9
    var tools = require('oroui/js/tools');
10
    var mapWidgetModuleName = require('oroui/js/widget/map-widget-module-name');
11
12
    /**
13
     * @export oroui/js/app/components/widget-component
14
     * @extends oroui.app.components.base.Component
15
     * @class oroui.app.components.WidgetComponent
16
     */
17
    WidgetComponent = BaseComponent.extend({
18
        /**
19
         * @property {oroui.widget.AbstractWidget}
20
         * @constructor
21
         */
22
        widget: null,
23
24
        /**
25
         * @property {boolean}
26
         */
27
        opened: false,
28
29
        /**
30
         * @property {oroui.widget.AbstractWidget}
31
         */
32
        view: null,
33
34
        defaults: {
35
            options: {}
36
        },
37
38
        /**
39
         * @inheritDoc
40
         */
41
        initialize: function(options) {
42
            if (options.initialized) {
43
                // widget is initialized from server, there's nothing to do
44
                return;
45
            }
46
47
            this.options = $.extend(true, {}, this.defaults, options);
48
            this.$element = options._sourceElement;
49
            this.previousWidgetData = {};
50
51
            if (this.$element) {
52
                if (!this.options.options.url) {
53
                    this.options.options.url = this.$element.data('url') || this.$element.attr('href');
54
                }
55
                if (this.options.createOnEvent) {
56
                    this._bindOpenEvent();
57
                } else {
58
                    this._deferredInit();
59
                    this.openWidget().done(_.bind(this._resolveDeferredInit, this));
60
                }
61
            }
62
        },
63
64
        /**
65
         * @inheritDoc
66
         */
67
        dispose: function() {
68
            if (!this.disposed && this.$element) {
69
                this.$element.off('.' + this.cid);
70
            }
71
            WidgetComponent.__super__.dispose.call(this);
72
        },
73
74
        /**
75
         * Bind handler to open widget event on source element if it exists
76
         *
77
         * @protected
78
         */
79
        _bindOpenEvent: function() {
80
            var eventName = this.options.createOnEvent;
81
            var handler = _.bind(function(e) {
82
                e.preventDefault();
83
                this.openWidget();
84
            }, this);
85
            this.$element.on(eventName + '.' + this.cid, handler);
86
87
            mediator.on('widget_dialog:stateChange', _.bind(function(widget, data) {
88
                if (this.previousWidgetData.id === widget.getWid()) {
89
                    this.previousWidgetData.open = data.state === 'minimized';
90
                    this.previousWidgetData.widget = widget;
91
                }
92
            }, this));
93
        },
94
95
        /**
96
         * Handles open widget action to
97
         *  - check if widget module is loaded before open widget
98
         *
99
         *  @return {Promise}
100
         */
101
        openWidget: function() {
102
            var deferredOpen = $.Deferred();
103
            var $element = this.$element;
104
            if ($element) {
105
                $element.addClass('widget-component-processing');
106
                deferredOpen.then(function() {
107
                    $element.removeClass('widget-component-processing');
108
                });
109
            }
110
            var widgetModuleName;
111
            if (!this.widget) {
112
                // defines module name and load the module, before open widget
113
                widgetModuleName = mapWidgetModuleName(this.options.type);
114
                tools.loadModules(widgetModuleName, function(Widget) {
115
                    if (this.disposed) {
116
                        return;
117
                    }
118
                    this.widget = Widget;
119
                    this._openWidget(deferredOpen);
120
                }, this);
121
            } else {
122
                this._openWidget(deferredOpen);
123
            }
124
            return deferredOpen.promise();
125
        },
126
127
        /**
128
         * Instantiates widget and opens (renders) it
129
         *
130
         * @param {jQuery.Deferred} deferredOpen to handle widget opening process
131
         * @protected
132
         */
133
        _openWidget: function(deferredOpen) {
134
            var widget;
135
            var Widget = this.widget;
136
            var options = $.extend(true, {}, this.options.options);
137
138
            if (!this.options.multiple && this.previousWidgetData.open) {
139
                this.previousWidgetData.widget.widget.dialog('restore');
140
                this.previousWidgetData.open = false;
141
            }
142
143
            if (!this.options.multiple && this.opened) {
144
                // single instance is already opened
145
                deferredOpen.resolve();
146
                return;
147
            }
148
149
            // Create and open widget
150
            widget = new Widget(options);
151
            this.previousWidgetData.id = widget.getWid();
152
153
            this._bindEnvironmentEvent(widget);
154
155
            if (!this.options.multiple) {
156
                this.opened = true;
157
                this.listenTo(widget, 'widgetRemove', _.bind(function() {
158
                    this.opened = false;
159
                    delete this.view;
160
                }, this));
161
162
                if (widget.isEmbedded()) {
163
                    // save reference to widget (only for a single + embedded instance)
164
                    // to get access over named component
165
                    this.view = widget;
166
                }
167
            }
168
169
            widget.render();
170
171
            if (widget.isEmbedded()) {
172
                // if the widget is embedded, bind its life cycle with the component
173
                widget.listenTo(this, 'dispose', widget.dispose);
174
            }
175
176
            if (widget.deferredRender) {
177
                widget.deferredRender
178
                    .done(_.bind(deferredOpen.resolve, deferredOpen))
179
                    .fail(_.bind(deferredOpen.reject, deferredOpen));
180
            } else {
181
                deferredOpen.resolve(widget);
182
            }
183
        },
184
185
        /**
186
         * Binds widget instance to environment events
187
         *
188
         * @param {oroui.widget.AbstractWidget} widget
189
         * @protected
190
         */
191
        _bindEnvironmentEvent: function(widget) {
192
            var reloadEvent = this.options['reload-event'];
193
            var reloadGridName = this.options['reload-grid-name'];
194
            var refreshWidgetAlias = this.options['refresh-widget-alias'];
195
            var reloadWidgetAlias = this.options['reload-widget-alias'];
196
197
            reloadEvent = reloadEvent || 'widget_success:' + (widget.getAlias() || widget.getWid());
198
199
            if (refreshWidgetAlias) {
200
                widget.listenTo(mediator, reloadEvent, function() {
201
                    mediator.trigger('widget:doRefresh:' + refreshWidgetAlias);
202
                });
203
            }
204
205
            if (reloadWidgetAlias) {
206
                widget.listenTo(mediator, reloadEvent, function() {
207
                    mediator.execute('widgets:getByAliasAsync', reloadWidgetAlias, function(widget) {
208
                        widget.loadContent();
209
                    });
210
                });
211
            }
212
213
            if (reloadGridName) {
214
                widget.listenTo(mediator, reloadEvent, function() {
215
                    mediator.trigger('datagrid:doRefresh:' + reloadGridName);
216
                });
217
            }
218
        }
219
    });
220
221
    return WidgetComponent;
222
});
223