From 61e8179ef5d973202c8256d1180d2d80fcadfbd4 Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Thu, 3 Apr 2025 15:25:13 +0200 Subject: [PATCH 1/9] Feature flag the following features: manage fields, filters reset, column filtering --- addon/components/hyper-table-v2/column.hbs | 67 +++++++------ addon/components/hyper-table-v2/column.ts | 1 + addon/components/hyper-table-v2/index.hbs | 97 +++++++++++-------- addon/components/hyper-table-v2/index.ts | 14 ++- addon/core/handler.ts | 7 +- app/styles/columns.less | 4 + .../components/hyper-table-v2-test.ts | 32 ++++++ .../components/hyper-table-v2/column-test.ts | 8 ++ 8 files changed, 157 insertions(+), 73 deletions(-) diff --git a/addon/components/hyper-table-v2/column.hbs b/addon/components/hyper-table-v2/column.hbs index 16236d4d..fda7979c 100644 --- a/addon/components/hyper-table-v2/column.hbs +++ b/addon/components/hyper-table-v2/column.hbs @@ -1,6 +1,10 @@
-
+
{{#if this.loadingHeaderComponent}} @@ -10,7 +14,7 @@ @column={{@column}} @extra={{this.headerComponent.args}} /> - {{#if this.isOrderingIndicatorVisible}} + {{#if (and (not @delegatedFiltering) this.isOrderingIndicatorVisible)}} - {{else if (eq @column.order.direction "desc")}} - - {{/if}} + {{#unless @delegatedFiltering}} + {{#if (eq @column.order.direction "asc")}} + + {{else if (eq @column.order.direction "desc")}} + + {{/if}} + {{/unless}}
-
- {{#if (or @column.definition.filterable @column.definition.orderable)}} - - {{/if}} - - {{#if (and this.filteringComponent (eq @handler.tetherOn @column.definition.key))}} -
- + {{#if (or @column.definition.filterable @column.definition.orderable)}} + -
- {{/if}} -
+ {{/if}} + + {{#if (and this.filteringComponent (eq @handler.tetherOn @column.definition.key))}} +
+ +
+ {{/if}} +
+ {{/unless}}
{{yield}} diff --git a/addon/components/hyper-table-v2/column.ts b/addon/components/hyper-table-v2/column.ts index 8001e1c7..47e70e47 100644 --- a/addon/components/hyper-table-v2/column.ts +++ b/addon/components/hyper-table-v2/column.ts @@ -9,6 +9,7 @@ import { Column, FieldSize, ResolvedRenderingComponent } from '@upfluence/hypert interface HyperTableV2ColumnArgs { handler: TableHandler; column: Column; + delegatedFiltering?: boolean; } export default class HyperTableV2Column extends Component { diff --git a/addon/components/hyper-table-v2/index.hbs b/addon/components/hyper-table-v2/index.hbs index a1db5506..51e7ea1b 100644 --- a/addon/components/hyper-table-v2/index.hbs +++ b/addon/components/hyper-table-v2/index.hbs @@ -1,51 +1,57 @@
-
-
-
- {{#if this.features.selection}} -
- {{format-number this.selectionCount}} -
- {{/if}} + {{#if (or (has-block "search") (has-block "contextual-actions") (has-block "table-actions") this.displayHeader)}} +
+
+
+ {{#if this.features.selection}} +
+ {{format-number this.selectionCount}} +
+ {{/if}} - {{#if this.initialFetchColumnsDone}} - - {{/if}} - {{#if (has-block "contextual-actions")}} - {{yield to="contextual-actions"}} - {{/if}} -
-
- + {{#if this.initialFetchColumnsDone}} + + {{/if}} + {{#if (has-block "contextual-actions")}} + {{yield to="contextual-actions"}} + {{/if}} +
+
+ {{#if this.features.global_filters_reset}} + + {{/if}} - {{#if (has-block "table-actions")}} - {{yield to="table-actions"}} - {{/if}} + {{#if (has-block "table-actions")}} + {{yield to="table-actions"}} + {{/if}} - + {{#if this.features.manageable_fields}} + + {{/if}} +
+
- -
+ {{/if}}
{{/if}} - + {{#each @handler.rows as |row|}} { @@ -55,6 +63,10 @@ export default class HyperTableV2 extends Component { }; } + get displayHeader(): boolean { + return Object.keys(this.features).some((key) => this.features[key as keyof FeatureSet]); + } + get selectionCount(): number { if ( !this.args.handler.rowsMeta || diff --git a/addon/core/handler.ts b/addon/core/handler.ts index 454ca356..06e88c33 100644 --- a/addon/core/handler.ts +++ b/addon/core/handler.ts @@ -45,7 +45,12 @@ export default class TableHandler { currentPage: number = 1; - constructor(emberContext: unknown, manager: TableManager, rowsFetcher: RowsFetcher, renderingResolver = undefined) { + constructor( + emberContext: unknown, + manager: TableManager, + rowsFetcher: RowsFetcher, + renderingResolver?: RendererResolver + ) { this._context = emberContext; this.tableManager = manager; this.rowsFetcher = rowsFetcher; diff --git a/app/styles/columns.less b/app/styles/columns.less index 3be32de1..bdb2caa5 100644 --- a/app/styles/columns.less +++ b/app/styles/columns.less @@ -89,6 +89,10 @@ text-overflow: ellipsis; white-space: nowrap; + &.cell-header--delegated-filtering { + width: 100%; + } + .header-title-container { display: flex; align-items: center; diff --git a/tests/integration/components/hyper-table-v2-test.ts b/tests/integration/components/hyper-table-v2-test.ts index 7794c53c..8a311ad9 100644 --- a/tests/integration/components/hyper-table-v2-test.ts +++ b/tests/integration/components/hyper-table-v2-test.ts @@ -122,6 +122,12 @@ module('Integration | Component | hyper-table-v2', function (hooks) { }); }); + test('the actions header is completely missing if all of its features are disabled and no named block is passed', async function (this: TestContext, assert: Assert) { + this.features = { selection: false, searchable: false, manageable_fields: false, global_filters_reset: false }; + await render(hbs``); + assert.dom('.hypertable__upper-header').doesNotExist(); + }); + module('error state', function () { test('It displays an error state when the fetchRows call fails', async function (this: TestContext, assert: Assert) { sinon.stub(this.rowsFetcher, 'fetch').callsFake(() => { @@ -509,6 +515,32 @@ module('Integration | Component | hyper-table-v2', function (hooks) { }); }); + module('FeatureSet: manageable_fields', () => { + test('the Manage field button is displayed by default', async function (assert) { + await render(hbs``); + assert.dom('.hypertable__manage-fields').exists(); + }); + + test('the Manage field button is not displayed if the feature is disabled', async function (this: TestContext, assert) { + this.features = { manageable_fields: false }; + await render(hbs``); + assert.dom('.hypertable__manage-fields').doesNotExist(); + }); + }); + + module('FeatureSet: global_filters_reset', () => { + test('the global Reset all button is displayed by default', async function (assert) { + await render(hbs``); + assert.dom('[data-control-name="hypertable_reset_filters_button"]').exists(); + }); + + test('the global Reset all button is not displayed if the feature is disabled', async function (this: TestContext, assert) { + this.features = { global_filters_reset: false }; + await render(hbs``); + assert.dom('[data-control-name="hypertable_reset_filters_button"]').doesNotExist(); + }); + }); + module('Contextual Actions named-block is displayed if defined', () => { test('if a <:contextual-actions> named-block is passed to the component, then it should be visible in the table', async function (assert: Assert) { await render(hbs` diff --git a/tests/integration/components/hyper-table-v2/column-test.ts b/tests/integration/components/hyper-table-v2/column-test.ts index 3d54ae33..73b2dcdf 100644 --- a/tests/integration/components/hyper-table-v2/column-test.ts +++ b/tests/integration/components/hyper-table-v2/column-test.ts @@ -178,4 +178,12 @@ module('Integration | Component | hyper-table-v2/column', function (hooks) { assert.dom('.filter-command').hasClass('filter-command--opened'); }); }); + + test('the icon commands are not displayed if the @delegatedFiltering arg is truthy', async function (assert) { + await render(hbs` + + `); + + assert.dom('.hypertable__column .icon-commands').doesNotExist(); + }); }); From 76cc558e18837e1a42acc0b23c55b1a6b37ac22e Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Thu, 3 Apr 2025 15:40:24 +0200 Subject: [PATCH 2/9] add setup-table test-support util --- addon-test-support/index.ts | 3 ++- addon-test-support/setup-table.ts | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 addon-test-support/setup-table.ts diff --git a/addon-test-support/index.ts b/addon-test-support/index.ts index 049a04b6..b9d73511 100644 --- a/addon-test-support/index.ts +++ b/addon-test-support/index.ts @@ -1,4 +1,5 @@ import TableManager from './table-manager'; import RowsFetcher, { AllRowsFetcher } from './rows-fetcher'; +import { setupTable } from './setup-table'; -export { TableManager, RowsFetcher, AllRowsFetcher }; +export { TableManager, RowsFetcher, AllRowsFetcher, setupTable }; diff --git a/addon-test-support/setup-table.ts b/addon-test-support/setup-table.ts new file mode 100644 index 00000000..3642d8e3 --- /dev/null +++ b/addon-test-support/setup-table.ts @@ -0,0 +1,23 @@ +import { type TestContext } from '@ember/test-helpers'; + +import TableHandler from '@upfluence/hypertable/core/handler'; +import { TableManager, RowsFetcher } from '@upfluence/hypertable/test-support'; +import sinon from 'sinon'; + +export function setupTable(hooks: NestedHooks): void { + hooks.beforeEach(function (this: TestContext) { + this.tableManager = new TableManager(); + this.tableRowsFetcher = new RowsFetcher(); + this.tableHandler = new TableHandler(this, this.tableManager, this.tableRowsFetcher); + this.tableRows = []; + + sinon.stub(this.tableRowsFetcher, 'fetch').callsFake(() => { + return Promise.resolve({ + rows: this.tableRows, + meta: { + total: this.tableRows.length + } + }); + }); + }); +} From c22fa9225bd35f0bd091f035140c9f56bf702057 Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Tue, 13 May 2025 17:03:50 +0200 Subject: [PATCH 3/9] support hiding the facets loader search's label --- .../filtering-renderers/common/facets-loader.hbs | 4 +++- .../filtering-renderers/common/facets-loader.ts | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs b/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs index e1e18a59..c0d9b8d2 100644 --- a/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs +++ b/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs @@ -1,7 +1,9 @@
{{#if this.searchEnabled}}
- + {{#if this.displaySearchLabel}} + + {{/if}} Date: Tue, 13 May 2025 17:04:46 +0200 Subject: [PATCH 4/9] trigger event after the columns are loaded --- addon/core/handler.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/addon/core/handler.ts b/addon/core/handler.ts index 06e88c33..3209dbf3 100644 --- a/addon/core/handler.ts +++ b/addon/core/handler.ts @@ -73,6 +73,7 @@ export default class TableHandler { .then(({ columns }) => { this.columns = columns; this._lastOrderedColumn = columns.find((column) => column.order); + this.triggerEvent('columns-loaded'); }) .catch(() => { this.communicationError = true; From 3f0e670b6da5d267956db23dcd88924b1e251f6c Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Tue, 13 May 2025 17:05:05 +0200 Subject: [PATCH 5/9] make icon-commands css target looser --- app/styles/columns.less | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/styles/columns.less b/app/styles/columns.less index bdb2caa5..fcf998f4 100644 --- a/app/styles/columns.less +++ b/app/styles/columns.less @@ -117,9 +117,16 @@ } } +<<<<<<< HEAD .filter-command { display: none; margin-left: var(--spacing-px-6); +======= + .icon-commands { + position: absolute; + right: var(--spacing-px-12); + color: var(--color-gray-400); +>>>>>>> 6458064 (make icon-commands css target looser) &--opened { display: flex; From 648f100433efd32717bdc9b6ce72971f6517d6e3 Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Fri, 4 Jul 2025 16:29:38 +0200 Subject: [PATCH 6/9] always safely access facets array --- .../hyper-table-v2/filtering-renderers/common/facets-loader.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.ts b/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.ts index 46c52f4c..55845cbc 100644 --- a/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.ts +++ b/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.ts @@ -138,7 +138,7 @@ export default class HyperTableV2FacetsLoader extends Component { - this.facets = facets.sort(this.facetsSorter); + this.facets = (facets ?? []).sort(this.facetsSorter); this.filteringKey = filtering_key; const filterForKey = this.args.column.filters.find((v) => v.key === this.filteringKey); From 0dc92295f8f1baa0b14c8baaea5067fef4431446 Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Fri, 11 Jul 2025 11:05:54 +0200 Subject: [PATCH 7/9] fix facet count color --- .../hyper-table-v2/filtering-renderers/common/facets-loader.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs b/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs index c0d9b8d2..b8bd7d11 100644 --- a/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs +++ b/addon/components/hyper-table-v2/filtering-renderers/common/facets-loader.hbs @@ -40,7 +40,7 @@ {{/if}} {{yield (hash appliedFacets=this.appliedFacets facet=facet) to="facet-item"}}
-
+
{{facet.count}}
From cc2af8c13e818922ef11d6c757b6d264d00769c3 Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Thu, 7 Aug 2025 12:00:56 +0200 Subject: [PATCH 8/9] fix conflict character issue --- app/styles/columns.less | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/styles/columns.less b/app/styles/columns.less index fcf998f4..1c37003f 100644 --- a/app/styles/columns.less +++ b/app/styles/columns.less @@ -90,6 +90,7 @@ white-space: nowrap; &.cell-header--delegated-filtering { + overflow: visible; width: 100%; } @@ -117,16 +118,9 @@ } } -<<<<<<< HEAD .filter-command { display: none; margin-left: var(--spacing-px-6); -======= - .icon-commands { - position: absolute; - right: var(--spacing-px-12); - color: var(--color-gray-400); ->>>>>>> 6458064 (make icon-commands css target looser) &--opened { display: flex; From e075c97256d367aac07d278bc099215c84c5c2eb Mon Sep 17 00:00:00 2001 From: Philippe Ndiaye Date: Fri, 22 Aug 2025 14:58:08 +0200 Subject: [PATCH 9/9] fix tests --- tests/integration/components/hyper-table-v2-test.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/integration/components/hyper-table-v2-test.ts b/tests/integration/components/hyper-table-v2-test.ts index 8a311ad9..f3797838 100644 --- a/tests/integration/components/hyper-table-v2-test.ts +++ b/tests/integration/components/hyper-table-v2-test.ts @@ -71,13 +71,12 @@ module('Integration | Component | hyper-table-v2', function (hooks) { }); test('it triggers the row-click event correctly', async function (this: TestContext, assert: Assert) { - const handlerSpy = sinon.spy(this.handler); + const triggerEventSpy = sinon.spy(this.handler, 'triggerEvent'); await render(hbs``); await click('.hypertable__sticky-columns > .hypertable__column .hypertable__cell'); - // @ts-ignore - assert.ok(handlerSpy.triggerEvent.calledOnceWithExactly('row-click', this.handler.rows[0])); + assert.ok(triggerEventSpy.calledWithExactly('row-click', this.handler.rows[0])); }); test('when destroyed, the table properly calls the handler teardown method', async function (this: TestContext, assert: Assert) {