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
|
|
|
|