SearchLayoutView.js 28.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

define(['require',
    'backbone',
    'hbs!tmpl/search/SearchLayoutView_tmpl',
    'utils/Utils',
23 24
    'utils/UrlLinks',
    'utils/Globals',
25
    'collection/VSearchList',
26
    'utils/CommonViewFunction'
27
], function(require, Backbone, SearchLayoutViewTmpl, Utils, UrlLinks, Globals, VSearchList, CommonViewFunction) {
28 29 30 31 32 33 34 35 36 37
    'use strict';

    var SearchLayoutView = Backbone.Marionette.LayoutView.extend(
        /** @lends SearchLayoutView */
        {
            _viewName: 'SearchLayoutView',

            template: SearchLayoutViewTmpl,

            /** Layout sub regions */
38 39 40 41
            regions: {
                RSaveSearchBasic: "[data-id='r_saveSearchBasic']",
                RSaveSearchAdvance: "[data-id='r_saveSearchAdvance']"
            },
42 43 44 45

            /** ui selector cache */
            ui: {
                searchInput: '[data-id="searchInput"]',
46 47
                searchType: 'input[name="queryType"]',
                searchBtn: '[data-id="searchBtn"]',
48
                clearSearch: '[data-id="clearSearch"]',
49
                typeLov: '[data-id="typeLOV"]',
50 51
                tagLov: '[data-id="tagLOV"]',
                refreshBtn: '[data-id="refreshBtn"]',
52 53 54
                advancedInfoBtn: '[data-id="advancedInfo"]',
                typeAttrFilter: '[data-id="typeAttrFilter"]',
                tagAttrFilter: '[data-id="tagAttrFilter"]'
55 56
            },

57 58 59 60 61 62
            /** ui events hash */
            events: function() {
                var events = {},
                    that = this;
                events["keyup " + this.ui.searchInput] = function(e) {
                    var code = e.which;
63
                    this.value.query = e.currentTarget.value;
64
                    if (code == 13) {
65
                        that.findSearchResult();
66
                    }
67
                    this.checkForButtonVisiblity();
68
                };
69 70 71
                events["change " + this.ui.searchType] = 'dslFulltextToggle';
                events["click " + this.ui.searchBtn] = 'findSearchResult';
                events["click " + this.ui.clearSearch] = 'clearSearchData';
72 73
                events["change " + this.ui.typeLov] = 'checkForButtonVisiblity';
                events["change " + this.ui.tagLov] = 'checkForButtonVisiblity';
74
                events["click " + this.ui.refreshBtn] = 'onRefreshButton';
75
                events["click " + this.ui.advancedInfoBtn] = 'advancedInfo';
76 77 78 79 80 81
                events["click " + this.ui.typeAttrFilter] = function() {
                    this.openAttrFilter('type');
                };
                events["click " + this.ui.tagAttrFilter] = function() {
                    this.openAttrFilter('tag');
                };
82 83 84 85 86 87 88
                return events;
            },
            /**
             * intialize a new SearchLayoutView Layout
             * @constructs
             */
            initialize: function(options) {
89
                _.extend(this, _.pick(options, 'value', 'typeHeaders', 'searchVent', 'entityDefCollection', 'enumDefCollection', 'classificationDefCollection', 'searchTableColumns', 'searchTableFilters'));
90
                this.type = "basic";
91 92 93
                var param = Utils.getUrlState.getQueryParams();
                this.query = {
                    dsl: {
94
                        query: null,
95 96 97
                        type: null,
                        pageOffset: null,
                        pageLimit: null
98
                    },
99
                    basic: {
100 101
                        query: null,
                        type: null,
102
                        tag: null,
103
                        attributes: null,
104
                        tagFilters: null,
105 106
                        pageOffset: null,
                        pageLimit: null,
107
                        entityFilters: null,
108
                        includeDE: null
109 110
                    }
                };
111 112 113
                if (!this.value) {
                    this.value = {};
                }
114
                this.dsl = false;
115
                if (param && param.searchType) {
116 117
                    this.type = param.searchType;
                    this.updateQueryObject(param);
118
                }
119
                this.bindEvents();
120
            },
121 122
            renderSaveSearch: function() {
                var that = this;
123
                require(['views/search/save/SaveSearchView'], function(SaveSearchView) {
124 125 126 127
                    var saveSearchBaiscCollection = new VSearchList(),
                        saveSearchAdvanceCollection = new VSearchList(),
                        saveSearchCollection = new VSearchList();
                    saveSearchCollection.url = UrlLinks.saveSearchApiUrl();
128 129 130 131 132 133
                    saveSearchBaiscCollection.fullCollection.comparator = function(model) {
                        return model.get('name').toLowerCase();
                    }
                    saveSearchAdvanceCollection.fullCollection.comparator = function(model) {
                        return model.get('name').toLowerCase();
                    }
134 135 136 137 138 139 140 141 142 143 144 145 146
                    var obj = {
                        value: that.value,
                        searchVent: that.searchVent,
                        typeHeaders: that.typeHeaders,
                        fetchCollection: fetchSaveSearchCollection,
                        classificationDefCollection: that.classificationDefCollection,
                        entityDefCollection: that.entityDefCollection,
                        getValue: function() {
                            var queryObj = that.query[that.type],
                                entityObj = that.searchTableFilters['entityFilters'],
                                tagObj = that.searchTableFilters['tagFilters'],
                                urlObj = Utils.getUrlState.getQueryParams();
                            if (urlObj) {
147
                                // includeDE value in because we need to send "true","false" to the server.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
                                if (urlObj.includeDE == "true") {
                                    urlObj.includeDE = true;
                                } else {
                                    urlObj.includeDE = false;
                                }
                            }
                            return _.extend({}, queryObj, urlObj, {
                                'entityFilters': entityObj ? entityObj[queryObj.type] : null,
                                'tagFilters': tagObj ? tagObj[queryObj.tag] : null,
                                'type': queryObj.type,
                                'query': queryObj.query,
                                'tag': queryObj.tag
                            })
                        },
                        applyValue: function(model, searchType) {
                            that.manualRender(_.extend(searchType, CommonViewFunction.generateUrlFromSaveSearchObject({
                                value: model.get('searchParameters'),
                                classificationDefCollection: that.classificationDefCollection,
                                entityDefCollection: that.entityDefCollection
                            })));
                        }
                    }
                    that.RSaveSearchBasic.show(new SaveSearchView(_.extend(obj, {
                        isBasic: true,
172
                        collection: saveSearchBaiscCollection.fullCollection
173 174 175
                    })));
                    that.RSaveSearchAdvance.show(new SaveSearchView(_.extend(obj, {
                        isBasic: false,
176
                        collection: saveSearchAdvanceCollection.fullCollection
177 178 179 180 181
                    })));

                    function fetchSaveSearchCollection() {
                        saveSearchCollection.fetch({
                            success: function(collection, data) {
182 183
                                saveSearchAdvanceCollection.fullCollection.reset(_.where(data, { "searchType": "ADVANCED" }));
                                saveSearchBaiscCollection.fullCollection.reset(_.where(data, { "searchType": "BASIC" }));
184 185 186 187 188 189 190
                            },
                            silent: true
                        });
                    }
                    fetchSaveSearchCollection();
                });
            },
191
            bindEvents: function(param) {
192
                this.listenTo(this.typeHeaders, "reset", function(value) {
193
                    this.initializeValues();
194 195
                }, this);
            },
196 197 198 199 200 201
            initializeValues: function() {
                this.renderTypeTagList();
                this.setValues();
                this.checkForButtonVisiblity();
                this.renderSaveSearch();
            },
202 203 204 205 206 207 208 209 210 211
            makeFilterButtonActive: function(filtertypeParam) {
                var filtertype = ['entityFilters', 'tagFilters'],
                    that = this;
                if (filtertypeParam) {
                    if (_.isArray(filtertypeParam)) {
                        filtertype = filtertypeParam;
                    } else if (_.isString(filtertypeParam)) {
                        filtertype = [filtertypeParam];
                    }
                }
212
                var typeCheck = function(filterObj, type) {
213 214 215
                    if (that.value.type) {
                        if (filterObj && filterObj.length) {
                            that.ui.typeAttrFilter.addClass('active');
216
                        } else {
217
                            that.ui.typeAttrFilter.removeClass('active');
218
                        }
219 220 221 222
                        that.ui.typeAttrFilter.prop('disabled', false);
                    } else {
                        that.ui.typeAttrFilter.removeClass('active');
                        that.ui.typeAttrFilter.prop('disabled', true);
223
                    }
224
                }
225
                var tagCheck = function(filterObj, type) {
226 227 228 229
                    if (that.value.tag) {
                        that.ui.tagAttrFilter.prop('disabled', false);
                        if (filterObj && filterObj.length) {
                            that.ui.tagAttrFilter.addClass('active');
230
                        } else {
231
                            that.ui.tagAttrFilter.removeClass('active');
232
                        }
233 234 235
                    } else {
                        that.ui.tagAttrFilter.removeClass('active');
                        that.ui.tagAttrFilter.prop('disabled', true);
236 237
                    }
                }
238
                _.each(filtertype, function(type) {
239
                    var filterObj = that.searchTableFilters[type];
240
                    if (type == "entityFilters") {
241
                        typeCheck(filterObj[that.value.type], type);
242 243
                    }
                    if (type == "tagFilters") {
244
                        tagCheck(filterObj[that.value.tag], type);
245 246
                    }
                });
247
            },
248
            checkForButtonVisiblity: function(e, options) {
249 250 251 252 253 254 255 256 257
                if (this.type == "basic" && e && e.currentTarget) {
                    var $el = $(e.currentTarget),
                        isTagEl = $el.data('id') == "tagLOV" ? true : false;
                    if (e.type == "change" && $el.select2('data')) {
                        var value = $el.val(),
                            key = (isTagEl ? 'tag' : 'type'),
                            filterType = (isTagEl ? 'tagFilters' : 'entityFilters'),
                            value = value.length ? value : null;
                        if (this.value) {
258 259
                            //On Change handle
                            if (this.value[key] !== value || (!value && !this.value[key])) {
260 261 262
                                var temp = {};
                                temp[key] = value;
                                _.extend(this.value, temp);
263
                                // on change of type/tag change the offset.
264 265 266
                                if (_.isUndefined(options)) {
                                    this.value.pageOffset = 0;
                                }
267
                                _.extend(this.query[this.type], temp);
268 269 270 271 272 273
                            } else {
                                // Initial loading handle.
                                var filterObj = this.searchTableFilters[filterType];
                                if (filterObj && this.value[key]) {
                                    this.searchTableFilters[filterType][this.value[key]] = this.value[filterType] ? this.value[filterType] : null;
                                }
274 275 276 277 278 279 280 281 282 283 284 285 286
                                if (this.value.type) {
                                    if (this.value.attributes) {
                                        var attributes = _.sortBy(this.value.attributes.split(',')),
                                            tableColumn = this.searchTableColumns[this.value.type];
                                        if (_.isEmpty(this.searchTableColumns) || !tableColumn) {
                                            this.searchTableColumns[this.value.type] = attributes
                                        } else if (tableColumn.join(",") !== attributes.join(",")) {
                                            this.searchTableColumns[this.value.type] = attributes;
                                        }
                                    } else if (this.searchTableColumns[this.value.type]) {
                                        this.searchTableColumns[this.value.type] = undefined;
                                    }
                                }
287
                            }
288
                            this.makeFilterButtonActive(filterType);
289 290 291 292 293 294
                        } else {
                            this.ui.tagAttrFilter.prop('disabled', true);
                            this.ui.typeAttrFilter.prop('disabled', true);
                        }
                    }
                }
295 296
                var that = this,
                    value = this.ui.searchInput.val() || this.ui.typeLov.val();
297
                if (!this.dsl && !value) {
298 299 300 301 302 303 304 305 306 307 308
                    value = this.ui.tagLov.val();
                }
                if (value && value.length) {
                    this.ui.searchBtn.removeAttr("disabled");
                    setTimeout(function() {
                        that.ui.searchInput.focus();
                    }, 0);
                } else {
                    this.ui.searchBtn.attr("disabled", "true");
                }
            },
309 310
            onRender: function() {
                // array of tags which is coming from url
311
                this.initializeValues();
312
            },
313 314 315 316
            updateQueryObject: function(param) {
                if (param && param.searchType) {
                    this.type = param.searchType;
                }
317 318 319
                _.extend(this.query[this.type],
                    (this.type == "dsl" ? {
                        query: null,
320 321 322
                        type: null,
                        pageOffset: null,
                        pageLimit: null
323
                    } : {
324 325
                        query: null,
                        type: null,
326
                        tag: null,
327
                        attributes: null,
328
                        tagFilters: null,
329 330
                        pageOffset: null,
                        pageLimit: null,
331
                        entityFilters: null,
332
                        includeDE: null
333
                    }), param);
334
            },
335
            fetchCollection: function(value) {
336
                this.typeHeaders.fetch({ reset: true });
337
            },
338 339
            onRefreshButton: function() {
                this.fetchCollection();
340
                //to check url query param contain type or not
341 342
                var checkURLValue = Utils.getUrlState.getQueryParams(this.url);
                if (this.searchVent && (_.has(checkURLValue, "tag") || _.has(checkURLValue, "type") || _.has(checkURLValue, "query"))) {
343 344
                    this.searchVent.trigger('search:refresh');
                }
345
            },
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
            advancedInfo: function(e) {
                require([
                    'views/search/AdvancedSearchInfoView',
                    'modules/Modal'
                ], function(AdvancedSearchInfoView, Modal) {
                    var view = new AdvancedSearchInfoView();
                    var modal = new Modal({
                        title: 'Advanced Search Queries',
                        content: view,
                        okCloses: true,
                        showFooter: true,
                        allowCancel: false
                    }).open();
                    view.on('closeModal', function() {
                        modal.trigger('cancel');
                    });
                });
            },
364 365 366 367 368 369 370 371 372 373 374
            openAttrFilter: function(filterType) {
                var that = this;
                require(['views/search/SearchQueryView'], function(SearchQueryView) {
                    that.attrModal = new SearchQueryView({
                        value: that.value,
                        tag: (filterType === "tag" ? true : false),
                        type: (filterType === "type" ? true : false),
                        searchVent: that.searchVent,
                        typeHeaders: that.typeHeaders,
                        entityDefCollection: that.entityDefCollection,
                        enumDefCollection: that.enumDefCollection,
375 376
                        classificationDefCollection: that.classificationDefCollection,
                        searchTableFilters: that.searchTableFilters
377
                    });
378 379
                    that.attrModal.on('ok', function(scope, e) {
                        that.okAttrFilterButton(e);
380 381 382
                    });
                });
            },
383
            okAttrFilterButton: function(e) {
384 385
                var isTag = this.attrModal.tag ? true : false,
                    filtertype = isTag ? 'tagFilters' : 'entityFilters',
386 387 388 389
                    queryBuilderRef = this.attrModal.RQueryBuilder.currentView.ui.builder;
                if (queryBuilderRef.data('queryBuilder')) {
                    var rule = queryBuilderRef.queryBuilder('getRules');
                }
390
                if (rule) {
391
                    var ruleUrl = CommonViewFunction.attributeFilter.generateUrl({ "value": rule.rules, "formatedDateToLong": true });
392
                    this.searchTableFilters[filtertype][(isTag ? this.value.tag : this.value.type)] = ruleUrl;
393
                    this.makeFilterButtonActive(filtertype);
394
                    if (!isTag && this.value && this.value.type && this.searchTableColumns) {
395 396 397 398 399
                        if (!this.searchTableColumns[this.value.type]) {
                            this.searchTableColumns[this.value.type] = ["selected", "name", "owner", "description", "tag", "typeName"]
                        }
                        this.searchTableColumns[this.value.type] = _.sortBy(_.union(this.searchTableColumns[this.value.type], _.pluck(rule.rules, 'id')));
                    }
400
                    this.attrModal.modal.close();
401 402
                    if ($(e.currentTarget).hasClass('search')) {
                        this.findSearchResult();
403 404 405
                    }
                }
            },
406
            manualRender: function(paramObj) {
407
                this.updateQueryObject(paramObj);
408
                this.setValues(paramObj);
409
            },
410
            renderTypeTagList: function() {
411 412
                var that = this;
                this.ui.typeLov.empty();
413 414
                var typeStr = '<option></option>',
                    tagStr = typeStr;
415
                this.typeHeaders.fullCollection.each(function(model) {
416
                    var name = Utils.getName(model.toJSON(), 'name');
417
                    if (model.get('category') == 'ENTITY') {
418
                        typeStr += '<option>' + (name) + '</option>';
419 420
                    }
                    if (model.get('category') == 'CLASSIFICATION') {
421
                        tagStr += '<option>' + (name) + '</option>';
422
                    }
423
                });
424 425
                that.ui.typeLov.html(typeStr);
                that.ui.tagLov.html(tagStr);
426 427 428 429 430 431 432 433
                this.ui.typeLov.select2({
                    placeholder: "Select",
                    allowClear: true
                });
                this.ui.tagLov.select2({
                    placeholder: "Select",
                    allowClear: true
                });
434
            },
435
            setValues: function(paramObj) {
436 437
                var arr = [],
                    that = this;
438 439 440 441
                if (paramObj) {
                    this.value = paramObj;
                }
                if (this.value) {
442
                    this.ui.searchInput.val(this.value.query || "");
443
                    if (this.value.dslChecked == "true") {
444 445 446
                        if (!this.ui.searchType.prop("checked")) {
                            this.ui.searchType.prop("checked", true).trigger("change");
                        }
447
                    } else {
448 449 450
                        if (this.ui.searchType.prop("checked")) {
                            this.ui.searchType.prop("checked", false).trigger("change");
                        }
451
                    }
452
                    this.ui.typeLov.val(this.value.type);
453
                    if (this.ui.typeLov.data('select2')) {
454 455
                        if (this.ui.typeLov.val() !== this.value.type) {
                            this.value.type = null;
456
                            this.ui.typeLov.val("").trigger("change", { 'manual': true });
457
                        } else {
458
                            this.ui.typeLov.trigger("change", { 'manual': true });
459
                        }
460
                    }
461

462
                    if (!this.dsl) {
463
                        this.ui.tagLov.val(this.value.tag);
464
                        if (this.ui.tagLov.data('select2')) {
465 466 467
                            // To handle delete scenario.
                            if (this.ui.tagLov.val() !== this.value.tag) {
                                this.value.tag = null;
468
                                this.ui.tagLov.val("").trigger("change", { 'manual': true });
469
                            } else {
470
                                this.ui.tagLov.trigger("change", { 'manual': true });
471
                            }
472 473
                        }
                    }
474 475 476
                    setTimeout(function() {
                        that.ui.searchInput.focus();
                    }, 0);
477 478 479
                }
            },
            findSearchResult: function() {
480 481 482
                this.triggerSearch(this.ui.searchInput.val());
            },
            triggerSearch: function(value) {
483 484
                var params = {
                    searchType: this.type,
485 486 487
                    dslChecked: this.ui.searchType.is(':checked'),
                    tagFilters: null,
                    entityFilters: null
488
                }
489
                params['type'] = this.ui.typeLov.select2('val') || null;
490
                if (!this.dsl) {
491
                    params['tag'] = this.ui.tagLov.select2('val') || null;
492 493 494 495 496 497 498 499
                    var entityFilterObj = this.searchTableFilters['entityFilters'],
                        tagFilterObj = this.searchTableFilters['tagFilters'];
                    if (this.value.tag) {
                        params['tagFilters'] = tagFilterObj[this.value.tag]
                    }
                    if (this.value.type) {
                        params['entityFilters'] = entityFilterObj[this.value.type]
                    }
500
                    var columnList = this.value && this.value.type && this.searchTableColumns ? this.searchTableColumns[this.value.type] : null;
501
                    if (columnList) {
502
                        params['attributes'] = columnList.join(',');
503
                    }
504 505 506
                    if (_.isUndefinedNull(this.value.includeDE)) {
                        params['includeDE'] = false;
                    } else {
507 508 509
                        params['includeDE'] = this.value.includeDE;
                    }
                }
510
                if (!_.isUndefinedNull(this.value.pageLimit)) {
511
                    params['pageLimit'] = this.value.pageLimit;
512
                }
513 514
                if (!_.isUndefinedNull(this.value.pageOffset)) {
                    if (!_.isUndefinedNull(this.query[this.type]) && this.query[this.type].query != value) {
515
                        params['pageOffset'] = 0;
516
                    } else {
517
                        params['pageOffset'] = this.value.pageOffset;
518 519
                    }
                }
520 521
                params['query'] = value || null;
                _.extend(this.query[this.type], params);
522 523
                Utils.setUrl({
                    url: '#!/search/searchResult',
524
                    urlParams: _.extend({}, this.query[this.type]),
525
                    mergeBrowserUrl: false,
526 527
                    trigger: true,
                    updateTabState: true
528 529 530
                });
            },
            dslFulltextToggle: function(e) {
531
                var paramObj = Utils.getUrlState.getQueryParams();
532 533 534
                if (paramObj && this.type == paramObj.searchType) {
                    this.updateQueryObject(paramObj);
                }
535 536
                if (e.currentTarget.checked) {
                    this.type = "dsl";
537
                    this.dsl = true;
538
                    this.$('.tagBox').hide();
539
                    this.$('.temFilterBtn').hide();
540 541
                    this.$('.temFilter').addClass('col-sm-12');
                    this.$('.temFilter').removeClass('col-sm-10');
542 543
                    this.$('.basicSaveSearch').hide();
                    this.$('.advanceSaveSearch').show();
544 545
                    this.$('.searchText').text('Search By Query');
                    this.ui.searchInput.attr("placeholder", 'Search By Query eg. where name="sales_fact"');
546
                } else {
547 548
                    this.$('.temFilter').addClass('col-sm-10');
                    this.$('.temFilter').removeClass('col-sm-12');
549
                    this.$('.temFilterBtn').show();
550
                    this.$('.tagBox').show();
551 552
                    this.$('.basicSaveSearch').show();
                    this.$('.advanceSaveSearch').hide();
553
                    this.dsl = false;
554
                    this.type = "basic";
555 556
                    this.$('.searchText').text('Search By Text');
                    this.ui.searchInput.attr("placeholder", "Search By Text");
557
                }
558 559 560 561 562
                if (Utils.getUrlState.isSearchTab()) {
                    Utils.setUrl({
                        url: '#!/search/searchResult',
                        urlParams: _.extend(this.query[this.type], {
                            searchType: this.type,
563
                            dslChecked: this.ui.searchType.is(':checked')
564 565
                        }),
                        mergeBrowserUrl: false,
566 567
                        trigger: true,
                        updateTabState: true
568
                    });
569
                }
570 571
            },
            clearSearchData: function() {
572
                this.updateQueryObject();
573
                this.ui.typeLov.val("").trigger("change");
574
                this.ui.tagLov.val("").trigger("change");
575
                this.ui.searchInput.val("");
576 577 578 579 580 581
                var type = "basicSaveSearch";
                if (this.type == "dsl") {
                    type = "advanceSaveSearch";
                }
                this.$('.' + type + ' .saveSearchList').find('li.active').removeClass('active');
                this.$('.' + type + ' [data-id="saveBtn"]').attr('disabled', true);
582
                if (!this.dsl) {
583 584 585
                    this.searchTableFilters.tagFilters = {};
                    this.searchTableFilters.entityFilters = {};
                }
586
                this.checkForButtonVisiblity();
587
                Utils.setUrl({
588 589 590 591 592
                    url: '#!/search/searchResult',
                    urlParams: {
                        searchType: this.type,
                        dslChecked: this.ui.searchType.is(':checked')
                    },
593 594 595
                    mergeBrowserUrl: false,
                    trigger: true
                });
596
            }
597 598
        });
    return SearchLayoutView;
599
});