From ed9f3d59f25640485c8857799f2bfeb41ad5c109 Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Tue, 31 Dec 2024 13:12:29 +0100 Subject: [PATCH] hyper-table-v2/filtering-renderers/date: allow moving option key to be extended (#216) * hyper-table-v2/filtering-renderers/date: allow moving option key to be extended * hypertable v2: add support for empty_state_message (#217) * hypertable v2: add support for empty_state_message * add more test scenarios for rows and fix tests * hyper-table-v2/filtering-renderers/numeric: add multiplier option, allows for extension in money-type columns * feat(hyper-table-v2/filtering-renderers/common/search): add support for passing a filterKey * fix pr feedback --- addon-test-support/rows-fetcher.ts | 11 +++++ .../hyper-table-v2/cell-renderers/date.hbs | 4 +- .../hyper-table-v2/cell-renderers/numeric.hbs | 4 +- .../hyper-table-v2/cell-renderers/text.hbs | 4 +- .../filtering-renderers/common/search.ts | 8 +++- .../filtering-renderers/date.ts | 16 ++++--- .../filtering-renderers/numeric.ts | 42 ++++++++++++++++--- addon/core/interfaces/column.ts | 1 + .../components/hyper-table-v2-test.ts | 12 +++--- .../cell-renderers/date-test.ts | 12 ++++++ .../cell-renderers/numeric-test.ts | 23 ++++++++++ .../cell-renderers/text-test.ts | 11 +++++ .../filtering-renderers/common/search-test.ts | 28 ++++++++++++- tests/unit/core/handler-test.ts | 12 +++--- 14 files changed, 159 insertions(+), 29 deletions(-) diff --git a/addon-test-support/rows-fetcher.ts b/addon-test-support/rows-fetcher.ts index 5dfccdc8..76852672 100644 --- a/addon-test-support/rows-fetcher.ts +++ b/addon-test-support/rows-fetcher.ts @@ -26,6 +26,17 @@ export default class RowsFetcher { bar: 'second bar', total: 123123, date: 0 + }, + { + influencerId: 44, + recordId: 14, + record_id: 14, + holderId: 58, + holderType: 'list', + foo: null, + bar: 'second bar', + total: null, + date: 0 } ], meta: { total: 12 } diff --git a/addon/components/hyper-table-v2/cell-renderers/date.hbs b/addon/components/hyper-table-v2/cell-renderers/date.hbs index d520ea86..8982312c 100644 --- a/addon/components/hyper-table-v2/cell-renderers/date.hbs +++ b/addon/components/hyper-table-v2/cell-renderers/date.hbs @@ -1,5 +1,7 @@ {{#if this.value}} {{this.formattedDate}} {{else}} - — + + {{or @column.definition.empty_state_message "—"}} + {{/if}} \ No newline at end of file diff --git a/addon/components/hyper-table-v2/cell-renderers/numeric.hbs b/addon/components/hyper-table-v2/cell-renderers/numeric.hbs index 72f5a739..9cab45e2 100644 --- a/addon/components/hyper-table-v2/cell-renderers/numeric.hbs +++ b/addon/components/hyper-table-v2/cell-renderers/numeric.hbs @@ -6,6 +6,8 @@ {{else}}
- — + + {{or @column.definition.empty_state_message "—"}} +
{{/if}} \ No newline at end of file diff --git a/addon/components/hyper-table-v2/cell-renderers/text.hbs b/addon/components/hyper-table-v2/cell-renderers/text.hbs index d19e7b13..99a1fe36 100644 --- a/addon/components/hyper-table-v2/cell-renderers/text.hbs +++ b/addon/components/hyper-table-v2/cell-renderers/text.hbs @@ -3,5 +3,7 @@ {{this.value}} {{else}} - — + + — + {{/if}} \ No newline at end of file diff --git a/addon/components/hyper-table-v2/filtering-renderers/common/search.ts b/addon/components/hyper-table-v2/filtering-renderers/common/search.ts index c084ee40..b724953b 100644 --- a/addon/components/hyper-table-v2/filtering-renderers/common/search.ts +++ b/addon/components/hyper-table-v2/filtering-renderers/common/search.ts @@ -10,10 +10,12 @@ import { onlyNumeric } from '@upfluence/hypertable/utils'; interface HyperTableV2FilteringRenderersSearchArgs { handler: TableHandler; column: Column; + filterKey?: string; type?: string; } const SEARCH_DEBOUNCE_TIME: number = 300; +const DEFAULT_FILTER_KEY: string = 'value'; export default class HyperTableV2FilteringRenderersSearch extends Component { @tracked searchQuery: string = ''; @@ -30,6 +32,10 @@ export default class HyperTableV2FilteringRenderersSearch extends Component { @tracked _currentDateValue: Date[] = []; @tracked _currentMovingDateOption: any; @tracked filterOption: FilterOption; + protected movingOptionKey: FilterOption = DEFAULT_MOVING_OPTION_KEY; + private _calendarContainer: any = null; filteringOptions: { label: string; value: FilterOption }[] = [ - { label: 'Moving', value: 'moving' }, + { label: 'Moving', value: this.movingOptionKey }, { label: 'Fixed', value: 'fixed' } ]; @@ -42,9 +46,9 @@ export default class HyperTableV2FilteringRenderersDate extends Component f.key === 'moving'); + let filter = this.args.column.filters.find((f) => f.key === this.movingOptionKey); this._currentMovingDateOption = filter ? filter.value : null; - this.filterOption = this._currentMovingDateOption ? 'moving' : 'fixed'; + this.filterOption = this._currentMovingDateOption ? this.movingOptionKey : 'fixed'; args.handler.on('reset-columns', (columns) => { if (columns.includes(args.column)) { this._resetStates(); @@ -92,7 +96,7 @@ export default class HyperTableV2FilteringRenderersDate extends Component { - @tracked lowerBoundFilter = ''; - @tracked upperBoundFilter = ''; + @tracked lowerBoundFilter: string = ''; + @tracked upperBoundFilter: string = ''; orderingDirections: { [key: string]: OrderDirection } = Object.freeze({ '0 — 9': 'asc', @@ -27,14 +28,19 @@ export default class HyperTableV2FilteringRenderersNumeric extends Component { if (columns.includes(args.column)) { this._resetStates(); } }); - this.lowerBoundFilter = args.column.filters.find((filter) => filter.key === 'lower_bound')?.value || ''; - this.upperBoundFilter = args.column.filters.find((filter) => filter.key === 'upper_bound')?.value || ''; + this.initLowerBound(); + this.initUpperBound(); + } + + get multiplier(): number { + return DEFAULT_MULTIPLIER; } get hasBoundFiltersDefined(): boolean { @@ -69,8 +75,32 @@ export default class HyperTableV2FilteringRenderersNumeric extends Component filter.key === 'lower_bound')?.value) { + this.lowerBoundFilter = ( + parseInt(this.args.column.filters.find((filter) => filter.key === 'lower_bound')!.value) / this.multiplier + ).toString(); + } + } + + private initUpperBound(): void { + this.upperBoundFilter = ''; + + if (this.args.column.filters.find((filter) => filter.key === 'upper_bound')?.value) { + this.upperBoundFilter = ( + parseInt(this.args.column.filters.find((filter) => filter.key === 'upper_bound')!.value) / this.multiplier + ).toString(); + } + } } diff --git a/addon/core/interfaces/column.ts b/addon/core/interfaces/column.ts index 65cfbc7b..01f35651 100644 --- a/addon/core/interfaces/column.ts +++ b/addon/core/interfaces/column.ts @@ -19,6 +19,7 @@ export type ColumnDefinition = { filterable_by: string[] | null; facetable: boolean; facetable_by: string[] | null; + empty_state_message?: string; position?: { sticky: boolean; }; diff --git a/tests/integration/components/hyper-table-v2-test.ts b/tests/integration/components/hyper-table-v2-test.ts index c9c8a379..1cd7bfe5 100644 --- a/tests/integration/components/hyper-table-v2-test.ts +++ b/tests/integration/components/hyper-table-v2-test.ts @@ -42,9 +42,9 @@ module('Integration | Component | hyper-table-v2', function (hooks) { test('it sets up the rows correctly', async function (assert: Assert) { await render(hbs``); - assert.dom('.hypertable__cell').exists({ count: 8 }); - assert.dom('.hypertable__sticky-columns .hypertable__column .hypertable__cell').exists({ count: 2 }); - assert.dom('.hypertable__column:nth-child(2) .hypertable__cell').exists({ count: 2 }); + assert.dom('.hypertable__cell').exists({ count: 12 }); + assert.dom('.hypertable__sticky-columns .hypertable__column .hypertable__cell').exists({ count: 3 }); + assert.dom('.hypertable__column:nth-child(2) .hypertable__cell').exists({ count: 3 }); }); test('it resets the filters', async function (assert: Assert) { @@ -155,7 +155,7 @@ module('Integration | Component | hyper-table-v2', function (hooks) { await render(hbs``); assert.dom('.hypertable__column.hypertable__column--selection').exists(); - assert.dom('.upf-checkbox').exists({ count: 3 }); + assert.dom('.upf-checkbox').exists({ count: 4 }); }); test('the selection column is present when the feature is enabled', async function (assert: Assert) { @@ -258,7 +258,7 @@ module('Integration | Component | hyper-table-v2', function (hooks) { await click('.hypertable__column.hypertable__column--selection header .upf-checkbox'); assert .dom('.hypertable__column.hypertable__column--selection .hypertable__cell .upf-checkbox') - .exists({ count: 2 }); + .exists({ count: 3 }); findAll('.hypertable__column.hypertable__column--selection .hypertable__cell .upf-checkbox input').forEach( (checkbox) => { assert.dom(checkbox).isChecked(); @@ -309,7 +309,7 @@ module('Integration | Component | hyper-table-v2', function (hooks) { assert .dom('.hypertable__column.hypertable__column--selection .hypertable__cell .upf-checkbox') - .exists({ count: 2 }); + .exists({ count: 3 }); findAll('.hypertable__column.hypertable__column--selection .hypertable__cell .upf-checkbox input').forEach( (checkbox) => { assert.dom(checkbox).isChecked(); diff --git a/tests/integration/components/hyper-table-v2/cell-renderers/date-test.ts b/tests/integration/components/hyper-table-v2/cell-renderers/date-test.ts index cd572114..a3850282 100644 --- a/tests/integration/components/hyper-table-v2/cell-renderers/date-test.ts +++ b/tests/integration/components/hyper-table-v2/cell-renderers/date-test.ts @@ -42,4 +42,16 @@ module('Integration | Component | hyper-table-v2/cell-renderers/date', function assert.equal(this.row[this.column.definition.key], '0'); assert.dom().hasText('—'); }); + + test('it renders @column.definition.empty_state_message when present and the value is null', async function (assert) { + this.column = this.handler.columns[3]; + this.column.definition.empty_state_message = 'No date'; + this.row = this.handler.rows[1]; + + await render( + hbs`` + ); + + assert.dom().hasText('No date'); + }); }); diff --git a/tests/integration/components/hyper-table-v2/cell-renderers/numeric-test.ts b/tests/integration/components/hyper-table-v2/cell-renderers/numeric-test.ts index 0b287e0d..64b3c624 100644 --- a/tests/integration/components/hyper-table-v2/cell-renderers/numeric-test.ts +++ b/tests/integration/components/hyper-table-v2/cell-renderers/numeric-test.ts @@ -42,4 +42,27 @@ module('Integration | Component | hyper-table-v2/cell-renderers/numeric', functi assert.equal(this.row[this.column.definition.key], '123123'); assert.dom().hasText('123k'); }); + + test('it renders a default - when the value is null', async function (assert) { + this.column = this.handler.columns[2]; + this.row = this.handler.rows[2]; + + await render( + hbs`` + ); + + assert.dom().hasText('—'); + }); + + test('it renders @column.definition.empty_state_message when present and the value is null', async function (assert) { + this.column = this.handler.columns[2]; + this.column.definition.empty_state_message = 'Custom empty'; + this.row = this.handler.rows[2]; + + await render( + hbs`` + ); + + assert.dom().hasText('Custom empty'); + }); }); diff --git a/tests/integration/components/hyper-table-v2/cell-renderers/text-test.ts b/tests/integration/components/hyper-table-v2/cell-renderers/text-test.ts index be1a8c84..57ae93f9 100644 --- a/tests/integration/components/hyper-table-v2/cell-renderers/text-test.ts +++ b/tests/integration/components/hyper-table-v2/cell-renderers/text-test.ts @@ -29,4 +29,15 @@ module('Integration | Component | hyper-table-v2/cell-renderers/text', function assert.equal(this.row[this.column.definition.key], 'ekip'); assert.dom('span').hasText('ekip'); }); + + test('it renders a default - when the value is null', async function (assert) { + this.column = this.handler.columns[0]; + this.row = this.handler.rows[2]; + + await render( + hbs`` + ); + + assert.dom().hasText('—'); + }); }); diff --git a/tests/integration/components/hyper-table-v2/filtering-renderers/common/search-test.ts b/tests/integration/components/hyper-table-v2/filtering-renderers/common/search-test.ts index ee773cfc..7f8c292b 100644 --- a/tests/integration/components/hyper-table-v2/filtering-renderers/common/search-test.ts +++ b/tests/integration/components/hyper-table-v2/filtering-renderers/common/search-test.ts @@ -38,7 +38,7 @@ module('Integration | Component | hyper-table-v2/filtering-renderers/common/sear assert.dom('.oss-input-container').exists(); }); - test('When text is inputed, the applyFilters is called', async function (assert: Assert) { + test('When text is inputted, the applyFilters is called', async function (assert: Assert) { const handlerSpy = sinon.spy(this.handler); await render( hbs`` @@ -64,6 +64,32 @@ module('Integration | Component | hyper-table-v2/filtering-renderers/common/sear ); }); + test('the provided filter key is used when apply filters', async function (assert: Assert) { + const handlerSpy = sinon.spy(this.handler); + await render( + hbs`` + ); + + await fillIn('.oss-input-container input', 'test'); + await triggerKeyEvent( + '.oss-input-container input', + 'keyup', + 'Enter', + //@ts-ignore + { code: 'Enter' } + ); + + assert.ok( + //@ts-ignore + handlerSpy.applyFilters.calledWith(this.column, [ + { + key: 'foobar', + value: 'test' + } + ]) + ); + }); + test('The remove icon is displayed when text is entered', async function (assert: Assert) { await render( hbs`` diff --git a/tests/unit/core/handler-test.ts b/tests/unit/core/handler-test.ts index ad25db19..237bc9c3 100644 --- a/tests/unit/core/handler-test.ts +++ b/tests/unit/core/handler-test.ts @@ -38,7 +38,7 @@ module('Unit | core/handler', function (hooks) { const handler = new TableHandler(getContext(), this.tableManager, this.rowsFetcher); assert.equal(handler.rows.length, 0); await handler.fetchRows(); - assert.equal(handler.rows.length, 2); + assert.equal(handler.rows.length, 3); }); test('it removes duplicated row by record_id', async function (assert: Assert) { @@ -224,7 +224,7 @@ module('Unit | core/handler', function (hooks) { handler.applyOrder(handler.columns[1], 'asc'); handler.toggleSelectAll(true); - assert.equal(handler.selection.length, 2); + assert.equal(handler.selection.length, 3); handler.resetColumns(handler.columns); @@ -243,7 +243,7 @@ module('Unit | core/handler', function (hooks) { assert.ok(rowsFetcherSpy.fetch.calledTwice); // @ts-ignore assert.ok(rowsFetcherSpy.fetch.calledWithExactly(1, 20)); - assert.equal(handler.rows.length, 2); + assert.equal(handler.rows.length, 3); }); test('Handler#removeRow', async function (assert: Assert) { @@ -251,10 +251,10 @@ module('Unit | core/handler', function (hooks) { const handlerTriggerEventSpy = sinon.spy(handler, 'triggerEvent'); await handler.fetchRows(); - assert.equal(handler.rows.length, 2); + assert.equal(handler.rows.length, 3); handler.removeRow(12); - assert.equal(handler.rows.length, 1); + assert.equal(handler.rows.length, 2); assert.equal(handler.rows[0].recordId, 13); // @ts-ignore assert.ok(handlerTriggerEventSpy.calledOnceWithExactly('remove-row')); @@ -302,7 +302,7 @@ module('Unit | core/handler', function (hooks) { await handler.fetchRows(); handler.toggleSelectAll(true); - assert.equal(handler.selection.length, 2); + assert.equal(handler.selection.length, 3); }); test('it selects all the rows', async function (assert: Assert) {