blob: 79aae3d480a3f6dd7b86b04e2b5f6d495cd9cc3b [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 Definition from '../utils/table-definition';
import ColumnDefinition from '../utils/column-definition';
import DataProcessor from '../utils/data-processor';
import layout from '../templates/components/em-table';
const DEFAULT_ROW_HIGHLIGHT_COLOR = "#EEE";
function createAssigner(targetPath, targetKey, sourcePath) {
return Ember.on("init", Ember.observer(targetPath, sourcePath, function () {
var target = this.get(targetPath),
source = this.get(sourcePath);
if(target && source !== undefined) {
target.set(targetKey, source);
}
}));
}
const HANDLERS = {
// Mouse handlers
mouseOver: function(event) {
var index = Ember.$(this).index() + 1;
event.data.highlightRow(index);
},
mouseLeave: function(event) {
event.data.highlightRow(-1);
},
// Scroll handler
onScroll: function(event) {
var tableBody = event.currentTarget,
scrollValues = event.data.get("scrollValues");
scrollValues.set("left", tableBody.scrollLeft);
scrollValues.set("width", tableBody.scrollWidth);
}
};
export default Ember.Component.extend({
layout: layout,
classNames: ["em-table"],
classNameBindings: ["showScrollShadow", "showLeftScrollShadow", "showRightScrollShadow"],
definition: null,
dataProcessor: null,
highlightRowOnMouse: false, // Could be true or {color: "#XYZ"}
headerComponentNames: ['em-table-search-ui', 'em-table-pagination-ui'],
footerComponentNames: ['em-table-pagination-ui'],
leftPanelComponentName: "em-table-facet-panel",
rightPanelComponentName: "",
columnWidthChangeAction: null,
scrollChangeAction: null,
scrollValues: null,
_widthTrackerTimer: null,
init: function() {
this._super();
this.set("scrollValues", Ember.Object.create({
left: 0,
width: 0,
viewPortWidth: 0
}));
},
showScrollShadow: false,
showLeftScrollShadow: false,
showRightScrollShadow: false,
assignDefinitionInProcessor: createAssigner('_dataProcessor', 'tableDefinition', '_definition'),
assignRowsInProcessor: createAssigner('_dataProcessor', 'rows', 'rows'),
assignColumnsInDefinition: createAssigner('_definition', 'columns', 'columns'),
assignEnableSortInDefinition: createAssigner('_definition', 'enableSort', 'enableSort'),
assignEnableSearchInDefinition: createAssigner('_definition', 'enableSearch', 'enableSearch'),
assignEnablePaginationInDefinition: createAssigner('_definition', 'enablePagination', 'enablePagination'),
assignRowCountInDefinition: createAssigner('_definition', 'rowCount', 'rowCount'),
_definition: Ember.computed('definition', 'definitionClass', function () {
return this.get('definition') || (this.get('definitionClass') || Definition).create();
}),
_dataProcessor: Ember.computed('dataProcessor', 'dataProcessorClass', function () {
return this.get('dataProcessor') || (this.get('dataProcessorClass') || DataProcessor).create();
}),
displayFooter: Ember.computed("_definition.minRowsForFooter", "_dataProcessor.processedRows.length", function () {
return this.get("_definition.minRowsForFooter") <= this.get("_dataProcessor.processedRows.length");
}),
_processedRowsObserver: Ember.observer('_dataProcessor.processedRows', function () {
this.sendAction('rowsChanged', this.get('_dataProcessor.processedRows'));
}),
_setColumnWidth: function (columns) {
var widthText = (100 / columns.length) + "%";
columns.forEach(function (column) {
if(!column.width) {
column.width = widthText;
}
});
},
_columns: Ember.computed('_definition.columns', function () {
var rawColumns = this.get('_definition.columns'),
normalisedColumns = {
left: [],
center: [],
right: [],
length: rawColumns.length
};
rawColumns.forEach(function (column) {
normalisedColumns[column.get("pin")].push({
definition: column,
width: column.width
});
});
if(normalisedColumns.center.length === 0) {
normalisedColumns.center = [{
definition: ColumnDefinition.fillerColumn,
}];
}
this._setColumnWidth(normalisedColumns.center);
return normalisedColumns;
}),
message: Ember.computed('_dataProcessor.message', '_columns.length', '_dataProcessor.processedRows.length', function () {
var message = this.get("_dataProcessor.message");
if(message) {
return message;
}
else if(!this.get('_columns.length')) {
return "No columns available!";
}
else if(!this.get("_dataProcessor.processedRows.length")) {
let identifiers = Ember.String.pluralize(this.get('_definition.recordType') || "record");
return `No ${identifiers} available!`;
}
}),
highlightRow: function (index) {
var element = Ember.$(this.get("element")),
sheet = element.find("style")[0].sheet,
elementID = element.attr("id"),
color = this.get("highlightRowOnMouse.color") || DEFAULT_ROW_HIGHLIGHT_COLOR;
try {
sheet.deleteRule(0);
}catch(e){}
if(index >= 0) {
sheet.insertRule(`#${elementID} .table-cell:nth-child(${index}){ background-color: ${color}; }`, 0);
}
},
didInsertElement: function () {
Ember.run.scheduleOnce('afterRender', this, function() {
this.highlightRowOnMouseObserver();
this.scrollChangeActionObserver();
});
},
highlightRowOnMouseObserver: Ember.observer("highlightRowOnMouse", function () {
var highlightRowOnMouse = this.get("highlightRowOnMouse"),
element = this.get("element");
if(element) {
element = Ember.$(element).find(".table-mid");
if(highlightRowOnMouse) {
element.on('mouseover', '.table-cell', this, HANDLERS.mouseOver);
element.on('mouseleave', this, HANDLERS.mouseLeave);
}
else {
element.off('mouseover', '.table-cell', HANDLERS.mouseOver);
element.off('mouseleave', HANDLERS.mouseLeave);
}
}
}),
scrollValuesObserver: Ember.observer("scrollValues.left", "scrollValues.width", "scrollValues.viewPortWidth", function () {
var scrollValues = this.get("scrollValues");
this.sendAction("scrollChangeAction", scrollValues);
this.set("showLeftScrollShadow", scrollValues.left > 1);
this.set("showRightScrollShadow", scrollValues.left < (scrollValues.width - scrollValues.viewPortWidth));
}),
scrollChangeActionObserver: Ember.observer("scrollChangeAction", "message", "showScrollShadow", function () {
Ember.run.scheduleOnce('afterRender', this, function() {
var addScrollListener = this.get("scrollChangeAction") || this.get("showScrollShadow"),
element = this.$().find(".table-body"),
scrollValues = this.get("scrollValues");
if(addScrollListener && element) {
element = element.get(0);
clearInterval(this.get("_widthTrackerTimer"));
if(element) {
if(addScrollListener) {
Ember.$(element).on('scroll', this, HANDLERS.onScroll);
this.set("_widthTrackerTimer", setInterval(function () {
scrollValues.setProperties({
width: element.scrollWidth,
viewPortWidth: element.offsetWidth
});
}, 1000));
}
else {
element.off('scroll', HANDLERS.onScroll);
}
}
}
});
}),
willDestroyElement: function () {
this._super();
clearInterval(this.get("_widthTrackerTimer"));
Ember.$(this.$().find(".table-body")).off();
Ember.$(this.$().find(".table-mid")).off();
Ember.$(this.$()).off();
},
actions: {
search: function (searchText, actualSearchType) {
this.set('_definition.searchText', searchText);
this.set('_definition._actualSearchType', actualSearchType);
this.sendAction("searchAction", searchText);
},
sort: function (sortColumnId, sortOrder) {
this.get("_definition").setProperties({
sortColumnId,
sortOrder
});
this.sendAction("sortAction", sortColumnId, sortOrder);
},
rowChanged: function (rowCount) {
this.set('_definition.rowCount', rowCount);
this.sendAction("rowAction", rowCount);
},
pageChanged: function (pageNum) {
this.set('_definition.pageNum', pageNum);
this.sendAction("pageAction", pageNum);
},
columnWidthChanged: function (width, columnDefinition, index) {
this.sendAction("columnWidthChangeAction", width, columnDefinition, index);
}
}
});