Test Setup Failed
Push — master ( 982d9a...a2862f )
by
unknown
03:40
created

EntityComponentView   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
define(function(require) {
2
    'use strict';
3
4
    var EntityComponentView;
5
    var Backbone = require('backbone');
6
    var _ = require('underscore');
7
    var __ = require('orotranslation/js/translator');
8
    var EntityModel = require('./model');
9
    var componentTemplate = require('text!./templates/component.html');
10
    var entityTemplate = require('text!./templates/entity-item.html');
11
    var formTemplate = require('text!./templates/form.html');
12
    var entitySelectResultTemplate = require('text!./templates/select2/result.html');
13
    var entitySelectSelectionTemplate = require('text!./templates/select2/selection.html');
14
    var Select2Component = require('oro/select2-component');
15
16
    require('oroui/js/items-manager/editor');
17
    require('oroui/js/items-manager/table');
18
19
    var modes = {
20
        VIEW_MODE: 1,
21
        EDIT_MODE: 2
22
    };
23
24
    /**
25
     * @class   orochannel.entityManagement.EntityComponentView
26
     * @extends Backbone.View
27
     */
28
    EntityComponentView = Backbone.View.extend({
29
        /**
30
         * Widget mode constants
31
         *
32
         * @const
33
         */
34
        MODES: _.clone(modes),
35
36
        /**
37
         * @type {function(Object)}
38
         */
39
        template: _.template(componentTemplate),
40
41
        /**
42
         * @type {function(Object)}
43
         */
44
        itemTemplate: _.template(entityTemplate),
45
46
        /**
47
         * @type {function(Object)}
48
         */
49
        formTemplate: _.template(formTemplate),
50
51
        /**
52
         * @type {object}
53
         */
54
        options: {
55
            data: [],
56
            mode: modes.VIEW_MODE,
57
            entityModel: EntityModel,
58
            metadata: null,
59
            lockedEntities: []
60
        },
61
62
        /**
63
         * @type {Backbone.Collection}
64
         */
65
        collection: null,
66
67
        /**
68
         * @type {jQuery}
69
         */
70
        $formContainer: null,
71
72
        /**
73
         * @type {jQuery}
74
         */
75
        $listContainer: null,
76
77
        /**
78
         * @type {jQuery}
79
         */
80
        $noDataContainer: null,
81
82
        /**
83
         * @inheritDoc
84
         */
85
        constructor: function EntityComponentView() {
86
            EntityComponentView.__super__.constructor.apply(this, arguments);
87
        },
88
89
        /**
90
         * Initialize view
91
         *
92
         * @param {object} options
93
         */
94
        initialize: function(options) {
95
            this.options = _.defaults(options || {}, this.options);
96
            if (!this.options.metadata) {
97
                throw new Error('Missing "metadata" options for entity selection compoment');
98
            }
99
100
            var models = this.options.data.length > 0 ? _.map(this.options.data, _.bind(this._createModel, this)) : [];
101
            this.collection = this.collection || new (Backbone.Collection)(models, {model: EntityModel});
102
            this.listenTo(this.collection, 'add remove reset', this._onCollectionChange);
103
            this.listenTo(this.collection, 'add', this._onItemAdded);
104
        },
105
106
        /**
107
         * Renders component
108
         */
109
        render: function() {
110
            var templateContext = {__: __};
111
112
            this.$el.html(this.template(_.extend({}, templateContext)));
113
            this.$formContainer = this.$el.find('.form-container');
114
            this.$listContainer = this.$el.find('.grid-container');
115
            this.$noDataContainer = this.$el.find('.no-data');
116
117
            if (this.options.mode === modes.EDIT_MODE) {
118
                this.$formContainer.html(this.formTemplate(_.extend({}, templateContext)));
119
                _.defer(_.bind(this._initializeForm, this));
120
            }
121
122
            _.defer(_.bind(this._initializeList, this));
123
        },
124
125
        /**
126
         * Initialize form component
127
         *
128
         * @private
129
         */
130
        _initializeForm: function() {
131
            var configs = {
132
                placeholder: __('oro.channel.form.entity'),
133
                result_template: entitySelectResultTemplate,
134
                selection_template: entitySelectSelectionTemplate,
135
                data: _.bind(function() {
136
                    var notSelected = _.omit(this.options.metadata, this.collection.pluck('name'));
137
                    var options = _.map(notSelected, function(entityMetadata) {
138
                        return {
139
                            id: entityMetadata.name,
140
                            text: entityMetadata.label,
141
                            icon: entityMetadata.icon,
142
                            type: entityMetadata.type
143
                        };
144
                    });
145
                    var optionGroups = _.groupBy(options, function(entityMetadata) {
146
                        return entityMetadata.type;
147
                    });
148
                    var results = [];
149
150
                    _.each(_.keys(optionGroups).sort().reverse(), function(groupName) {
151
                        results.push({
152
                            text: __('oro.channel.entity_owner.' + groupName),
153
                            icon: null,
154
                            children: optionGroups[groupName]
155
                        });
156
                    });
157
158
                    return {results: results};
159
                }, this)
160
            };
161
            var $el = this.$formContainer.find('[data-purpose="entity-selector"]');
162
            var select2Component = new Select2Component({
163
                configs: configs,
164
                _sourceElement: $el
165
            });
166
            this.pageComponent('entity-selector', select2Component, $el);
167
            this.$formContainer.itemsManagerEditor({
168
                collection: this.collection
169
            });
170
        },
171
172
        /**
173
         * Initialize list component
174
         *
175
         * @private
176
         */
177
        _initializeList: function() {
178
            this.$listContainer.find('tbody').itemsManagerTable({
179
                collection: this.collection,
180
                itemTemplate: this.itemTemplate,
181
                itemRender: function itemRender(template, data) {
182
                    var context = _.extend({__: __}, data);
183
184
                    return template(context);
185
                },
186
                deleteHandler: _.partial(function(collection, model, data) {
0 ignored issues
show
Unused Code introduced by
The parameter data is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
187
                    collection.remove(model);
188
                }, this.collection),
189
                sorting: false
190
            });
191
            // emulate reset for first time
192
            this._onCollectionChange();
193
        },
194
195
        /**
196
         * Collection change handler. Shows/Hides empty message
197
         *
198
         * @private
199
         */
200
        _onCollectionChange: function() {
201
            if (!this.collection.isEmpty()) {
202
                this.$listContainer.show();
203
                this.$noDataContainer.hide();
204
            } else {
205
                this.$listContainer.hide();
206
                this.$noDataContainer.show();
207
            }
208
        },
209
210
        /**
211
         * Appends single item to list
212
         *
213
         * @param {Object.<orochannel.entityManagement.Model>} model
214
         * @private
215
         */
216
        _onItemAdded: function(model) {
217
            model.set(this._prepareModelAttributes(model));
218
        },
219
220
        /**
221
         * Prepares model attributes
222
         *
223
         * @param   {Object.<orochannel.entityManagement.Model>} model
224
         * @returns {object}
225
         * @private
226
         */
227
        _prepareModelAttributes: function(model) {
228
            var entityName = model.get('name');
229
            var entityMetadata = this.options.metadata[entityName] || {};
230
            var actions = [];
231
            var lockedEntities = this.options.lockedEntities;
232
233
            if ((entityName.indexOf(lockedEntities) === -1) && this.options.mode === modes.EDIT_MODE) {
234
                actions.push({
235
                    collectionAction: 'delete',
236
                    title: 'Delete',
237
                    icon: 'fa-trash-o'
238
                });
239
            } else if (this.options.mode === modes.VIEW_MODE) {
240
                actions.push({
241
                    title: 'View',
242
                    icon: 'fa-eye',
243
                    url: entityMetadata.view_link
244
                });
245
                actions.push({
246
                    title: 'Edit',
247
                    icon: 'fa-pencil-square-o',
248
                    url: entityMetadata.edit_link
249
                });
250
            }
251
252
            return _.defaults(entityMetadata, {name: entityName, label: entityName, actions: actions});
253
        },
254
255
        /**
256
         * Creates model form name
257
         *
258
         * @param   {string} entityName
259
         * @returns {Object.<orochannel.entityManagement.Model>}
260
         * @private
261
         */
262
        _createModel: function(entityName) {
263
            var model = new EntityModel({name: entityName});
264
            model.set(this._prepareModelAttributes(model));
265
266
            return model;
267
        }
268
    });
269
270
    return EntityComponentView;
271
});
272