From e16af170a67492d4644ff113836706f0595387cc Mon Sep 17 00:00:00 2001 From: RedTn Date: Wed, 25 Oct 2017 23:44:08 -0700 Subject: [PATCH] feat(table-header): custom icon components (#489) * feat(custom-icons): base files * fix(column-base): sort icon displayed with sortable:false * feat(dummy): cookbook for custom-sort-icon * loosen ember-one-way-controls version requirement * yarn.lock updates * [BUGFIX release]: Added check for target column is droppable (#496) * [chore]: Update ember-truth-helpers to latest version. (#497) * [BUGFIX release]: Ensure the drop target remains properly identified (#418) * fix(feedback): iconComponent comments, iconComponent test * fix(feedback-v2): iconComponent comments, iconComponent test --- addon/mixins/table-header.js | 13 +++++-- addon/templates/components/columns/base.hbs | 4 ++- .../cookbook/custom-sort-icon-table.js | 34 ++++++++++++++++++ .../dummy/app/components/materialize-icon.js | 9 +++++ tests/dummy/app/index.html | 1 + tests/dummy/app/router.js | 1 + .../app/routes/cookbook/custom-sort-icon.js | 1 + tests/dummy/app/templates/application.hbs | 3 ++ .../cookbook/custom-sort-icon-table.hbs | 26 ++++++++++++++ .../templates/components/materialize-icon.hbs | 3 ++ .../templates/cookbook/custom-sort-icon.hbs | 12 +++++++ tests/integration/components/lt-head-test.js | 35 +++++++++++++++++++ 12 files changed, 139 insertions(+), 3 deletions(-) create mode 100644 tests/dummy/app/components/cookbook/custom-sort-icon-table.js create mode 100644 tests/dummy/app/components/materialize-icon.js create mode 100644 tests/dummy/app/routes/cookbook/custom-sort-icon.js create mode 100644 tests/dummy/app/templates/components/cookbook/custom-sort-icon-table.hbs create mode 100644 tests/dummy/app/templates/components/materialize-icon.hbs create mode 100644 tests/dummy/app/templates/cookbook/custom-sort-icon.hbs diff --git a/addon/mixins/table-header.js b/addon/mixins/table-header.js index 450b1514..6c549685 100644 --- a/addon/mixins/table-header.js +++ b/addon/mixins/table-header.js @@ -106,6 +106,15 @@ export default Mixin.create({ */ iconDescending: '', + /** + * Custom sorting component name to use instead of the default `` template. + * See `iconSortable`, `iconAsending`, or `iconDescending`. + * @property iconComponent + * @type {String} + * @default false + */ + iconComponent: null, + /** * ID of main table component. Used to generate divs for ember-wormhole * @type {String} @@ -117,8 +126,8 @@ export default Mixin.create({ subColumns: computed.readOnly('table.visibleSubColumns'), columns: computed.readOnly('table.visibleColumns'), - sortIcons: computed('iconSortable', 'iconAscending', 'iconDescending', function() { - return this.getProperties(['iconSortable', 'iconAscending', 'iconDescending']); + sortIcons: computed('iconSortable', 'iconAscending', 'iconDescending', 'iconComponent', function() { + return this.getProperties(['iconSortable', 'iconAscending', 'iconDescending', 'iconComponent']); }).readOnly(), init() { diff --git a/addon/templates/components/columns/base.hbs b/addon/templates/components/columns/base.hbs index bfb7193d..81f8cca4 100644 --- a/addon/templates/components/columns/base.hbs +++ b/addon/templates/components/columns/base.hbs @@ -2,7 +2,9 @@ {{component column.component column=column table=table tableActions=tableActions extra=extra sortIcons=sortIcons}} {{else}} {{label}} - {{#if sortIconProperty}} + {{#if (and sortIcons.iconComponent sortIconProperty)}} + {{component sortIcons.iconComponent sortIcons=sortIcons sortIconProperty=sortIconProperty}} + {{else if sortIconProperty}} {{/if}} {{/if}} diff --git a/tests/dummy/app/components/cookbook/custom-sort-icon-table.js b/tests/dummy/app/components/cookbook/custom-sort-icon-table.js new file mode 100644 index 00000000..8579cfcb --- /dev/null +++ b/tests/dummy/app/components/cookbook/custom-sort-icon-table.js @@ -0,0 +1,34 @@ +// BEGIN-SNIPPET custom-sort-icon-table +import Component from '@ember/component'; +import TableCommon from '../../mixins/table-common'; +import { computed } from '@ember/object'; + +export default Component.extend(TableCommon, { + columns: computed(function() { + return [{ + label: 'Avatar', + valuePath: 'avatar', + width: '60px', + sortable: false, + cellComponent: 'user-avatar' + }, { + label: 'First Name', + valuePath: 'firstName', + width: '150px' + }, { + label: 'Last Name', + valuePath: 'lastName', + width: '150px' + }, { + label: 'Address', + valuePath: 'address' + }, { + label: 'State', + valuePath: 'state' + }, { + label: 'Country', + valuePath: 'country' + }]; + }) +}); +// END-SNIPPET diff --git a/tests/dummy/app/components/materialize-icon.js b/tests/dummy/app/components/materialize-icon.js new file mode 100644 index 00000000..d880d448 --- /dev/null +++ b/tests/dummy/app/components/materialize-icon.js @@ -0,0 +1,9 @@ +// BEGIN-SNIPPET materialize-icon +import Component from '@ember/component'; +import layout from '../templates/components/materialize-icon'; + +export default Component.extend({ + tagName: 'span', + layout +}); +// END-SNIPPET diff --git a/tests/dummy/app/index.html b/tests/dummy/app/index.html index 23ea3bf2..1b1c999b 100644 --- a/tests/dummy/app/index.html +++ b/tests/dummy/app/index.html @@ -13,6 +13,7 @@ + {{content-for "head-footer"}} diff --git a/tests/dummy/app/router.js b/tests/dummy/app/router.js index 93afae07..a620ebd6 100644 --- a/tests/dummy/app/router.js +++ b/tests/dummy/app/router.js @@ -28,6 +28,7 @@ Router.map(function() { this.route('custom-row'); this.route('table-actions'); this.route('horizontal-scrolling'); + this.route('custom-sort-icon'); }); }); diff --git a/tests/dummy/app/routes/cookbook/custom-sort-icon.js b/tests/dummy/app/routes/cookbook/custom-sort-icon.js new file mode 100644 index 00000000..0040140d --- /dev/null +++ b/tests/dummy/app/routes/cookbook/custom-sort-icon.js @@ -0,0 +1 @@ +export { default } from '../table-route'; diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index 4553c6e6..7bf2183b 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -71,6 +71,9 @@ {{#link-to 'cookbook.pagination' tagName="li"}} {{link-to 'Pagination' 'cookbook.pagination'}} {{/link-to}} + {{#link-to 'cookbook.custom-sort-icon' tagName="li"}} + {{link-to 'Custom Sort Icon' 'cookbook.custom-sort-icon'}} + {{/link-to}} {{/link-to}}
  • Documentation
  • diff --git a/tests/dummy/app/templates/components/cookbook/custom-sort-icon-table.hbs b/tests/dummy/app/templates/components/cookbook/custom-sort-icon-table.hbs new file mode 100644 index 00000000..1a1f1cdc --- /dev/null +++ b/tests/dummy/app/templates/components/cookbook/custom-sort-icon-table.hbs @@ -0,0 +1,26 @@ +{{!-- BEGIN-SNIPPET custom-sort-icon-table --}} +{{#light-table table height='65vh' as |t|}} + + {{t.head + onColumnClick=(action 'onColumnClick') + iconSortable='unfold_more' + iconAscending='keyboard_arrow_up' + iconDescending='keyboard_arrow_down' + iconComponent='materialize-icon' + fixed=true + }} + + {{#t.body + canSelect=false + onScrolledToBottom=(action 'onScrolledToBottom') + as |body| + }} + {{#if isLoading}} + {{#body.loader}} + {{table-loader}} + {{/body.loader}} + {{/if}} + {{/t.body}} + +{{/light-table}} +{{!-- END-SNIPPET --}} diff --git a/tests/dummy/app/templates/components/materialize-icon.hbs b/tests/dummy/app/templates/components/materialize-icon.hbs new file mode 100644 index 00000000..02ee0d69 --- /dev/null +++ b/tests/dummy/app/templates/components/materialize-icon.hbs @@ -0,0 +1,3 @@ +{{!-- BEGIN-SNIPPET materialize-icon --}} +{{get sortIcons sortIconProperty}} +{{!-- END-SNIPPET --}} diff --git a/tests/dummy/app/templates/cookbook/custom-sort-icon.hbs b/tests/dummy/app/templates/cookbook/custom-sort-icon.hbs new file mode 100644 index 00000000..7e783bd4 --- /dev/null +++ b/tests/dummy/app/templates/cookbook/custom-sort-icon.hbs @@ -0,0 +1,12 @@ +{{#code-panel + title="Custom Sort Icon" + snippets=(array + "custom-sort-icon-table.js" + "table-common.js" + "custom-sort-icon-table.hbs" + "user-avatar.hbs" + "table-loader.hbs" + "materialize-icon.hbs" +)}} + {{cookbook/custom-sort-icon-table model=model}} +{{/code-panel}} diff --git a/tests/integration/components/lt-head-test.js b/tests/integration/components/lt-head-test.js index 45c1699f..cf9378b8 100644 --- a/tests/integration/components/lt-head-test.js +++ b/tests/integration/components/lt-head-test.js @@ -4,6 +4,8 @@ import hbs from 'htmlbars-inline-precompile'; import Table from 'ember-light-table'; import Columns, { GroupedColumns } from '../../helpers/table-columns'; import hasClass from '../../helpers/has-class'; +import Component from '@ember/component'; +import { isPresent } from '@ember/utils'; moduleForComponent('lt-head', 'Integration | Component | lt head', { integration: true @@ -92,6 +94,39 @@ test('render sort icons', function(assert) { assert.notOk(hasClass(sortIcon, 'fa-sort-asc')); }); +test('custom iconComponent has arguments', function(assert) { + const sortableColumns = Columns.filter((column) => { + return column.sortable !== false; + }); + + assert.expect(6 * sortableColumns.length); + const iconSortable = 'unfold_more'; + const iconAscending = 'fa-sort-asc'; + const iconDescending = 'fa-sort-desc'; + const iconComponent = 'custom-icon-component'; + + this.setProperties({ + iconSortable, + iconAscending, + iconDescending, + iconComponent, + table: new Table(Columns) + }); + this.register(`component:${iconComponent}`, Component.extend({ + init() { + this._super(...arguments); + assert.ok(isPresent(this.get('sortIconProperty'))); + assert.ok(isPresent(this.get('sortIcons'))); + assert.equal(this.get('sortIcons.iconSortable'), iconSortable); + assert.equal(this.get('sortIcons.iconAscending'), iconAscending); + assert.equal(this.get('sortIcons.iconDescending'), iconDescending); + assert.equal(this.get('sortIcons.iconComponent'), iconComponent); + } + })); + + this.render(hbs`{{lt-head table=table renderInPlace=true iconSortable=iconSortable iconAscending=iconAscending iconDescending=iconDescending iconComponent=iconComponent}}`); +}), + test('double click', function(assert) { this.set('table', new Table(Columns)); this.on('onColumnDoubleClick', (column) => {