Skip to content

Commit

Permalink
Custom cell (#26)
Browse files Browse the repository at this point in the history
* Simplify fixed cell template

* Custom cell

* New way of custom header

* use different API to define fixed columns

* Table & column options

* Options for table & columns

* Add custom header test

* Fix test
  • Loading branch information
billy-addepar authored Aug 30, 2017
1 parent 0de5303 commit defa4f8
Show file tree
Hide file tree
Showing 15 changed files with 169 additions and 136 deletions.
29 changes: 13 additions & 16 deletions addon/components/ember-table-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import $ from 'jquery';
import layout from '../templates/components/ember-table-2';
import { htmlSafe } from '@ember/string';
import { run } from '@ember/runloop';
import { isNone } from '@ember/utils';
import { get, set } from '@ember/object';

const { Component } = Ember;

Expand All @@ -21,11 +19,6 @@ export default class EmberTable2 extends Component {

@property layout = layout;

@computed('columns.firstObject.isFixed')
get hasFixedColumn() {
return this.get('columns.firstObject.isFixed');
}

/**
* Defines if this table has a footer or not.
* // TODO(Billy): replace this with an option to pass in footer component.
Expand Down Expand Up @@ -76,6 +69,19 @@ export default class EmberTable2 extends Component {
*/
@property estimateRowHeight = 20;

/**
* Indicates how many left columns will be fixed. With current implementation, only 1 single
* left most column can be a fixed column. Later version of Ember table could change
* implementation to support multiple fixed columns.
*/
@property numFixedColumns = 0;

@computed('numFixedColumns')
get hasFixedColumn() {
const numFixedColumns = this.get('numFixedColumns');
return Number.isInteger(numFixedColumns) && numFixedColumns !== 0;
}

/**
* A string value that defines table row component. By default, this is using ember table row
* component but outer application can override this value to use their custom row. This is
Expand All @@ -93,15 +99,6 @@ export default class EmberTable2 extends Component {
// Create a unique CellProxy class for this table instance, that way transient data won't
// pollute the prototype of the main proxy class.
this.cellProxyClass = class extends CellProxy {};

const columns = this.get('columns');
for (const column of columns) {
if (isNone(get(column, 'headerComponent'))) {
set(column, '_headerComponent', 'ember-table-header');
} else {
set(column, '_headerComponent', get(column, 'headerComponent'));
}
}
}

didInsertElement() {
Expand Down
20 changes: 18 additions & 2 deletions addon/components/ember-table-cell.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Ember from 'ember';
import { htmlSafe } from '@ember/string';
import { computed } from 'ember-decorators/object';
import { get } from '@ember/object';
import { property } from '../utils/class';

import layout from '../templates/components/ember-table-cell';
Expand All @@ -12,16 +13,31 @@ export default class EmberTableCell extends Component {
@property tagName = 'td';
@property attributeBindings = ['style:style'];

@computed('columnIndex', 'column.isFixed')
@computed('columnIndex', 'numFixedColumns')
get isFixed() {
return this.get('columnIndex') === 0 && this.get('column.isFixed');
const numFixedColumns = this.get('numFixedColumns');
return this.get('columnIndex') === 0 && Number.isInteger(numFixedColumns) &&
numFixedColumns !== 0;
}

@computed('row', 'column.valuePath')
get value() {
const row = this.get('row');
const valuePath = this.get('column.valuePath');

return get(row, valuePath);
}

@computed('column.width')
get style() {
return htmlSafe(`min-width: ${this.get('column.width')}px; max-width: ${this.get('column.width')}px;`);
}

@computed('isFixed')
get fixedCellClass() {
return this.get('isFixed') === true ? 'et2-fixed-table-cell' : '';
}

click() {
if (this.get('columnIndex') === 0) {
this.sendAction('toggleRow', this.get('row'));
Expand Down
14 changes: 8 additions & 6 deletions addon/templates/components/ember-table-2.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,18 @@
<thead class="et2-thead">
<tr>
{{#each columns as |column columnIndex|}}
{{#component column._headerComponent
{{#ember-table-header
column=column
columnIndex=columnIndex
numFixedColumns=numFixedColumns
onHeaderClicked="onHeaderClicked"
onColumnResized="onColumnResized"
onColumnResizeEnded="onColumnResizeEnded"
onColumnReorder="onColumnReorder"
onColumnReorderEnds="onColumnReorderEnds"
width=column.width
}}
{{#unless column.headerComponent}}
{{column.columnName}}
{{/unless}}
{{/component}}
{{/ember-table-header}}
{{/each}}
</tr>
</thead>
Expand Down Expand Up @@ -44,8 +42,11 @@
toggleRow="toggleRow"
column=cell.column
columnIndex=cell.columnIndex
numFixedColumns=numFixedColumns
}}
{{yield cell}}
{{#unless cell.column.cellComponent}}
{{yield cell}}
{{/unless}}
{{/ember-table-cell}}
{{/component}}
{{/vertical-collection}}
Expand All @@ -60,6 +61,7 @@
{{#ember-table-footer
column=column
columnIndex=columnIndex
numFixedColumns=numFixedColumns
}}
{{column.columnName}}
{{/ember-table-footer}}
Expand Down
17 changes: 11 additions & 6 deletions addon/templates/components/ember-table-cell.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{{#if isFixed}}
<div class="et2-fixed-table-cell" style={{style}}>
<div class={{fixedCellClass}} style={{style}}>
{{#if column.cellComponent}}
{{#component column.cellComponent
column=column
value=value
}}

{{/component}}
{{else}}
{{yield}}
</div>
{{else}}
{{yield}}
{{/if}}
{{/if}}
</div>
10 changes: 9 additions & 1 deletion addon/templates/components/ember-table-header.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
<div class="et2-table-header {{if isFixed 'et2-fixed-table-header'}}" style={{style}}>
{{yield}}
{{#if column.headerComponent}}
{{#component column.headerComponent
column=column
columnIndex=columnIndex
}}
{{/component}}
{{else}}
{{column.columnName}}
{{/if}}

{{#if column.isResizable}}
<div class="et2-header-resize-area">
Expand Down
21 changes: 7 additions & 14 deletions addon/utils/column-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,24 @@ export default class ColumnDefinition extends EmberObject {
@property valuePath = '';

/**
* Indicates if the column is a fixed column or not. With current implementation, only 1 single
* left most column can be a fixed column. Later version of Ember table could change
* implementation to support multiple fixed columns.
*/
@property isFixed = false;

/**
* Custom component passed in by user.
* Custom header component passed in by user.
*/
@property headerComponent = null;

/**
* Default header component if user does not define any custom header.
* Custom cell component passed in by user.
*/
@property _headerComponent = 'ember-table-header';
@property cellComponent = null;

/**
* Indicates if this column can be resized or not. It's true by default.
* Indicates if this column can be resized or not. It's false by default.
*/
@property isResizable = true;
@property isResizable = false;

/**
* Indicates if this column can be reordered or not. It's true by default.
* Indicates if this column can be reordered or not. It's false by default.
*/
@property isReorderable = true;
@property isReorderable = false;

/**
* Current width of the table.
Expand Down
4 changes: 2 additions & 2 deletions tests/dummy/app/components/custom-text-header.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import EmberTableHeader from '../components/ember-table-header';
import Component from '@ember/component';

export default class CutomTextHeaderComponent extends EmberTableHeader {
export default class CutomTextHeaderComponent extends Component {
}
4 changes: 2 additions & 2 deletions tests/dummy/app/components/image-cell.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import EmberTableCell from '../components/ember-table-cell';
import Component from '@ember/component';

export default class ImageCell extends EmberTableCell {
export default class ImageCell extends Component {
}
2 changes: 1 addition & 1 deletion tests/dummy/app/controllers/custom-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default Controller.extend({
}));
arr.push(EmberObject.create({
headerComponent: 'custom-text-header',
customCell: 'image-cell',
cellComponent: 'image-cell',
valuePath: 'url',
width: 180
}));
Expand Down
5 changes: 3 additions & 2 deletions tests/dummy/app/controllers/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ export default Controller.extend({
arr.pushObject(ColumnDefinition.create({
columnName: 'Column id',
valuePath: 'id',
isFixed: true,
width: columnWidth,
maxWidth
}));
Expand All @@ -64,7 +63,9 @@ export default Controller.extend({
columnName: `Col ${alphabet[j % 26]}`,
valuePath: alphabet[j % 26],
width: columnWidth,
maxWidth
maxWidth,
isResizable: true,
isReorderable: true
}));
}

Expand Down
2 changes: 1 addition & 1 deletion tests/dummy/app/templates/components/image-cell.hbs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<img src={{data}} class="cell-image"/>
<img src={{value}} class="cell-image"/>
1 change: 1 addition & 0 deletions tests/dummy/app/templates/demo.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{{#ember-table-2
rows=rows
columns=columns
numFixedColumns=1
as |cell|
}}

Expand Down
56 changes: 34 additions & 22 deletions tests/helpers/test-scenarios.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ import {
releasePress
} from './drag-helper';

export const DEFAULT_TABLE_OPTIONS = {
numFixedColumns: 1
};

export const DEFAULT_FULL_TABLE_COLUMN_OPTIONS = {
isResizable: true,
isReorderable: true
};

export function generateRows(rowCount, columnCount) {
const arr = emberA();
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
Expand All @@ -29,24 +38,33 @@ export function generateRows(rowCount, columnCount) {
return arr;
}

export function generateColumns(columnCount) {
export function generateColumns(columnCount, columnOptions) {
const arr = emberA();
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const columnWidth = 180;

arr.pushObject(ColumnDefinition.create({
columnName: 'Column id',
valuePath: 'id',
isFixed: true,
width: columnWidth
}));

for (let j = 0; j < columnCount - 1; j++) {
arr.pushObject(ColumnDefinition.create({
const columnDefinition = ColumnDefinition.create({
columnName: `Col ${alphabet[j % 26]}`,
valuePath: alphabet[j % 26],
width: columnWidth
}));
});

arr.pushObject(columnDefinition);
}

for (const columnDefinition of arr) {
for (const property in columnOptions) {
if (columnOptions.hasOwnProperty(property)) {
columnDefinition.set(property, columnOptions[property]);
}
}
}

return arr;
Expand All @@ -70,33 +88,27 @@ export const fullTable = hbs`
{{#ember-table-2
columns=tableColumns
rows=tableRows
rowComponent=customRow
rowComponent=rowComponent
numFixedColumns=numFixedColumns
as |cell|
}}
{{cell.value}}
{{/ember-table-2}}
</div>
`;

export async function setupCustomComponentTable(testContext, customHeader, customRow) {
const rowCount = 5;
const columnCount = 3;
const columns = generateColumns(columnCount);
for (const column of columns) {
column.set('headerComponent', customHeader);
}
testContext.set('tableColumns', columns);
testContext.set('tableRows', generateRows(rowCount, columnCount));
testContext.set('customRow', customRow);

testContext.render(fullTable);
await waitForRender();
}

export async function setupFullTable(testContext) {
export async function setupFullTable(testContext, tableOptions = DEFAULT_TABLE_OPTIONS,
columnOptions = DEFAULT_FULL_TABLE_COLUMN_OPTIONS) {
const rowCount = 20;
const columnCount = 10;
testContext.set('tableColumns', generateColumns(columnCount));

for (const property in tableOptions) {
if (tableOptions.hasOwnProperty(property)) {
testContext.set(property, tableOptions[property]);
}
}

testContext.set('tableColumns', generateColumns(columnCount, columnOptions));
testContext.set('tableRows', generateRows(rowCount, columnCount));
testContext.render(fullTable);
await waitForRender();
Expand Down
Loading

0 comments on commit defa4f8

Please sign in to comment.