blob: 07d31c09bf62e6cc5c6ead014493cec11c18ea36 [file] [log] [blame]
/**
* 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.
*/
import Ember from 'ember';
import SQL from './sql';
/**
* Handles Sorting, Searching & Pagination
*/
export default Ember.Object.extend({
isSorting: false,
isSearching: false,
tableDefinition: null,
sql: SQL.create(),
rows: [],
_sortedRows: [],
_searchedRows: [],
_facetFilteredRows: [],
_searchObserver: Ember.on("init", Ember.observer('tableDefinition.searchText', 'tableDefinition._actualSearchType', '_sortedRows.[]', function () {
Ember.run.once(this, "startSearch");
})),
_sortObserver: Ember.on("init", Ember.observer(
'tableDefinition.sortColumnId',
'tableDefinition.sortOrder',
'rows.[]', function () {
Ember.run.once(this, "startSort");
})),
_facetedFilterObserver: Ember.on("init", Ember.observer('tableDefinition.facetConditions', '_searchedRows.[]', function () {
Ember.run.once(this, "startFacetedFilter");
})),
regexSearch: function (clause, rows, columns) {
var regex;
try {
regex = new RegExp(clause, "i");
}
catch(e) {
regex = new RegExp("", "i");
}
function checkRow(column) {
var value;
if(!column.get('enableSearch')) {
return false;
}
value = column.getSearchValue(this);
if(typeof value === 'string') {
value = value.toLowerCase();
return value.match(regex);
}
return false;
}
return rows.filter(function (row) {
return columns.some(checkRow, row);
});
},
startSearch: function () {
var searchText = String(this.get('tableDefinition.searchText')),
rows = this.get('_sortedRows') || [],
columns = this.get('tableDefinition.columns'),
actualSearchType = this.get('tableDefinition._actualSearchType'),
that = this;
if(searchText) {
this.set("isSearching", true);
Ember.run.later(function () {
var result;
switch(actualSearchType) {
case "SQL":
result = that.get("sql").search(searchText, rows, columns);
break;
//case "Regex": Commenting as default will be called anyways
default:
result = that.regexSearch(searchText, rows, columns);
break;
}
that.setProperties({
_searchedRows: result,
isSearching: false
});
});
}
else {
this.set("_searchedRows", rows);
}
},
compareFunction: function (a, b){
// Checking for undefined and null to handle some special cases in JavaScript comparison
// Eg: 1 > undefined = false & 1 < undefined = false
// "a1" > null = false & "a1" < null = false
if(a === undefined || a === null) {
return -1;
}
else if(b === undefined || b === null) {
return 1;
}
else if(a < b) {
return -1;
}
else if(a > b) {
return 1;
}
else {
return 0;
}
},
startSort: function () {
var rows = this.get('rows'),
tableDefinition = this.get('tableDefinition'),
sortColumnId = this.get('tableDefinition.sortColumnId'),
descending = this.get('tableDefinition.sortOrder') === 'desc',
that = this,
column;
if(tableDefinition) {
column = tableDefinition.get('columns').find(function (element) {
return element.get('id') === sortColumnId;
});
}
if(rows && Array.isArray(rows.content)) {
rows = rows.toArray();
}
if(rows && rows.get('length') > 0 && column) {
this.set('isSorting', true);
Ember.run.later(function () {
/*
* Creating sortArray as calling getSortValue form inside the
* sort function every time would be more costly.
*/
var sortArray = rows.map(function (row) {
return {
value: column.getSortValue(row),
row: row
};
}),
compareFunction = that.get("compareFunction");
sortArray.sort(function (a, b) {
var result = compareFunction(a.value, b.value);
if(descending && result) {
result = -result;
}
return result;
});
that.setProperties({
_sortedRows: sortArray.map(function (record) {
return record.row;
}),
isSorting: false
});
});
}
else {
this.set('_sortedRows', rows);
}
},
startFacetedFilter: function () {
var clause = this.get("sql").createFacetClause(this.get('tableDefinition.facetConditions'), this.get("tableDefinition.columns")),
rows = this.get('_searchedRows') || [],
columns = this.get('tableDefinition.columns'),
that = this;
if(clause && columns) {
this.set("isSearching", true);
Ember.run.later(function () {
var result = that.get("sql").search(clause, rows, columns);
that.setProperties({
_facetFilteredRows: result,
isSearching: false
});
});
}
else {
this.set("_facetFilteredRows", rows);
}
},
facetedFields: Ember.computed('_searchedRows.[]', 'tableDefinition.columns', function () {
var searchedRows = this.get("_searchedRows"),
columns = this.get('tableDefinition.columns'),
fields = [];
if(columns) {
columns.forEach(function (column) {
var facetedData;
if(column.facetType) {
facetedData = column.facetType.facetRows(column, searchedRows);
if(facetedData) {
fields.push({
column: column,
facets: facetedData
});
}
}
});
}
return fields;
}),
pageDetails: Ember.computed("tableDefinition.rowCount", "tableDefinition.pageNum", "_facetFilteredRows.length", function () {
var tableDefinition = this.get("tableDefinition"),
pageNum = tableDefinition.get('pageNum'),
rowCount = tableDefinition.get('rowCount'),
startIndex = (pageNum - 1) * rowCount,
totalRecords = this.get('_facetFilteredRows.length');
if(startIndex < 0) {
startIndex = 0;
}
return {
pageNum: pageNum,
totalPages: Math.ceil(totalRecords / rowCount),
rowCount: rowCount,
startIndex: startIndex,
fromRecord: totalRecords ? startIndex + 1 : 0,
toRecord: Math.min(startIndex + rowCount, totalRecords),
totalRecords: totalRecords
};
}),
totalPages: Ember.computed.alias("pageDetails.totalPages"), // Adding an alias for backward compatibility
// Paginate
processedRows: Ember.computed('_facetFilteredRows.[]', 'tableDefinition.rowCount', 'tableDefinition.pageNum', function () {
var rowCount = this.get('tableDefinition.rowCount'),
startIndex = (this.get('tableDefinition.pageNum') - 1) * rowCount;
return this.get('_facetFilteredRows').slice(startIndex, startIndex + rowCount);
}),
});