diff --git a/addon/components/ui-filter/input/component.ts b/addon/components/ui-filter/input/component.ts index 503dabc..486a9ef 100644 --- a/addon/components/ui-filter/input/component.ts +++ b/addon/components/ui-filter/input/component.ts @@ -15,6 +15,11 @@ export default class UiFilterInput extends Component { */ public label?: string = 'Filter Input Field'; + /** + * The text input's title text. + */ + public title?: string; + /** * The text input's placeholder text. */ diff --git a/addon/components/ui-filter/input/template.hbs b/addon/components/ui-filter/input/template.hbs index ab1da71..5254798 100644 --- a/addon/components/ui-filter/input/template.hbs +++ b/addon/components/ui-filter/input/template.hbs @@ -20,6 +20,7 @@ value="{{this.value}}" class="form-control" placeholder={{this.placeholder}} + title={{this.title}} disabled={{this.disabled}} aria-label="{{this.label}}" oninput={{this.handleInputChange}} diff --git a/addon/components/ui-table/component.ts b/addon/components/ui-table/component.ts index 63101ea..e2ab074 100644 --- a/addon/components/ui-table/component.ts +++ b/addon/components/ui-table/component.ts @@ -44,6 +44,11 @@ export default class UiTable extends Component { */ public filterPlaceholder?: string; + /** + * The filter text input's title text. + */ + public filterTitle?: string; + /** * Whether filtering of the table's contents is enabled. By default, this * includes adding some UI to the top control bar such a text input to @@ -57,6 +62,16 @@ export default class UiTable extends Component { */ public pagingEnabled = true; + /** + * Text to display when there are no records. + */ + public noRecordsText?: string = 'No records exist'; + + /** + * Text to display when there are no records found while filtering. + */ + public noFilterResultsText?: string = 'Nothing found to display'; + protected get tableGuid() { return `${guidFor(this)}-table`; } diff --git a/addon/components/ui-table/template.hbs b/addon/components/ui-table/template.hbs index 9377804..6f118d9 100644 --- a/addon/components/ui-table/template.hbs +++ b/addon/components/ui-table/template.hbs @@ -27,6 +27,7 @@ input of the next tier down. filters = this.filters showClearButton = this.showFilterClearButton placeholder = this.filterPlaceholder + title = this.filterTitle ) as |PagerSizeOptions PagerNavbar FilterInput|}} {{#if (has-block "topControlBar")}} @@ -113,6 +114,17 @@ input of the next tier down. {{/each}} {{/if}} + {{#if (or (eq Filter.filteredRecords.length 0) (eq this.records.length 0))}} + + + {{#if (eq this.records.length 0)}} + {{this.noRecordsText}} + {{else}} + {{this.noFilterResultsText}} + {{/if}} + + + {{/if}} @@ -135,6 +147,7 @@ input of the next tier down. filters = this.filters showClearButton = this.showFilterClearButton placeholder = this.filterPlaceholder + title = this.filterTitle ) as |PagerSizeOptions PagerNavbar FilterInput|}} {{#if (has-block "bottomControlBar")}} diff --git a/addon/components/ui-table/ui-table.stories.ts b/addon/components/ui-table/ui-table.stories.ts index 9027400..13e5a03 100644 --- a/addon/components/ui-table/ui-table.stories.ts +++ b/addon/components/ui-table/ui-table.stories.ts @@ -59,8 +59,11 @@ export const Default = (context: unknown) => { @filterRules={{this.filterRules}} @showFilterClearButton={{this.showFilterClearButton}} @filterPlaceholder={{this.filterPlaceholder}} + @filterTitle={{this.filterTitle}} @pagingEnabled={{this.pagingEnabled}} @filterEnabled={{this.filterEnabled}} + @noRecordsText={{this.noRecordsText}} + @noFilterResultsText={{this.noFilterResultsText}} /> `, }; diff --git a/tests/integration/components/ui-table-test.ts b/tests/integration/components/ui-table-test.ts new file mode 100644 index 0000000..5c6f43f --- /dev/null +++ b/tests/integration/components/ui-table-test.ts @@ -0,0 +1,112 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { click, fillIn, render } from '@ember/test-helpers'; +import hbs from 'htmlbars-inline-precompile'; + +module('Integration | Component | ui-table', function (hooks) { + setupRenderingTest(hooks); + + const filterRules = ['firstName', 'lastName']; + + const columns = [ + { propertyName: 'firstName', sortOn: 'firstName', label: 'First Name' }, + { propertyName: 'lastName', sortOn: 'lastName', label: 'Last Name' }, + ]; + + const recordSet = [ + { firstName: 'Herbert', lastName: 'Labadie' }, + { firstName: 'Caleb', lastName: 'Welch' }, + { firstName: 'Lila', lastName: 'Yundt' }, + { firstName: 'Brittany', lastName: 'Kuhic' }, + { firstName: 'Terence', lastName: 'Brakus' }, + { firstName: 'Iris', lastName: 'Feil' }, + { firstName: 'Homer', lastName: 'Dietrich' }, + { firstName: 'Stacy', lastName: 'Dietrich' }, + { firstName: 'Karla', lastName: 'Dietrich' }, + { firstName: 'Clifton', lastName: 'Koelpin' }, + { firstName: 'Olive', lastName: 'Abernathy' }, + { firstName: 'Debra', lastName: 'Feil' }, + { firstName: 'Melody', lastName: 'Kreiger' }, + { firstName: 'Belinda', lastName: 'Emard' }, + { firstName: 'Lyle', lastName: 'Halvorson' }, + ]; + + async function renderComponent() { + // language=handlebars + await render(hbs` + + `); + } + + /** + * Basic Table Display, no results. + */ + test('ui table display, when there no records displays a row with no records text', async function (assert) { + this.set('columns', columns); + this.set('records', recordSet); + + await renderComponent(); + + assert.dom('.ui-table').isVisible(); + assert.dom('.ui-table').hasTagName('div'); + + assert.strictEqual(recordSet.length, 15, 'Table has 15 rows'); + + assert.dom('table thead tr').exists({ count: 1 }); + + // No records + this.set('records', []); + this.set('noRecordsText', 'No records exist'); + + await renderComponent(); + assert.dom('table tbody tr').hasText('No records exist'); + }); + + /** + * Filter Tests. + */ + test('ui table filter tests, it filters an array using string filter rules', async function (assert) { + this.set('columns', columns); + this.set('records', recordSet); + this.set('filterEnabled', true); + this.set('filterRules', filterRules); + this.set('showFilterClearButton', true); + this.set('filterPlaceholder', 'Filter'); + this.set('filterTitle', 'Filter title'); + this.set('noFilterResultsText', 'Nothing found to display'); + + await renderComponent(); + + assert.dom('table tbody tr').exists({ count: 15 }); + assert.dom('input[type="text"]').hasNoValue(); + assert.dom('input[type="text"]').hasProperty('placeholder', 'Filter'); + assert.dom('input[type="text"]').hasProperty('title', 'Filter title'); + + await fillIn('input[type="text"]', 'Dietrich'); + assert.dom('table tbody tr').exists({ count: 3 }); + + await fillIn('input[type="text"]', 'Caleb'); + assert.dom('table tbody tr').exists({ count: 1 }); + + await fillIn('input[type="text"]', 'asjd'); + + assert.dom('table tbody tr td').hasText('Nothing found to display'); + + assert.dom('.input-group button.ui-filter-reset').hasAria('label', 'Reset Filter Input Field'); + + await click('.input-group button.ui-filter-reset'); + + assert.dom('input[type="text"]').hasNoValue(); + }); +});