Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
<div class="fx-row fx-malign-space-between">
<div class="fx-row fx-gap-px-12">
{{#if this.shouldDisplay}}
<OSS::Button
@skin="destructive"
@skin="default"
@label={{t "hypertable.column.remove"}}
{{on "click" this.removeColumn}}
class="fx-1"
data-control-name={{concat "hypertable__column_filtering_for_" @column.definition.key "_remove_column"}}
/>
{{else}}
<div class="fx-1"></div>
{{/if}}
<OSS::Button
@label={{t "hypertable.column.clear_filters"}}
{{on "click" this.reset}}
data-control-name={{concat "hypertable__column_filtering_for_" @column.definition.key "_clear_filters"}}
/>

{{#if this.displayClearButton}}
<OSS::Button
@skin="secondary"
@label={{t "hypertable.column.clear_filters"}}
class="fx-1"
{{on "click" this.reset}}
data-control-name={{concat "hypertable__column_filtering_for_" @column.definition.key "_clear_filters"}}
/>
{{/if}}
</div>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { action, computed } from '@ember/object';

import TableHandler from '@upfluence/hypertable/core/handler';
import { Column } from '@upfluence/hypertable/core/interfaces';
Expand All @@ -14,6 +14,11 @@ export default class HyperTableV2FilteringRenderersCommonColumnActions extends C
return !this.args.column.definition.position?.sticky;
}

@computed('args.column.filters.[]', 'args.column.order')
get displayClearButton(): boolean {
return (this.args.column.filters?.length ?? 0) > 0 || this.args.column.order !== undefined;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Reactivity Issues in Glimmer Component Getter

The displayClearButton getter uses the @computed decorator, which is not for Glimmer components and can lead to reactivity issues. Glimmer components rely on tracked properties. This, along with the 'args.column.filters.[]' dependency potentially not tracking changes when filters is initially undefined, may prevent the clear button from updating its display state correctly.

Fix in Cursor Fix in Web


@action
reset(): void {
this.args.handler.resetColumns([this.args.column]);
Expand Down
2 changes: 1 addition & 1 deletion addon/components/hyper-table-v2/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
{{/if}}
</div>
<div class="right-side">
{{#if this.features.global_filters_reset}}
{{#if this.displayResetButton}}
<OSS::Button
class="margin-right-px-12"
@label={{t "hypertable.features.filtering.reset_all"}}
Expand Down
8 changes: 7 additions & 1 deletion addon/components/hyper-table-v2/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action, set } from '@ember/object';
import { action, computed, set } from '@ember/object';
import { debounce, scheduleOnce } from '@ember/runloop';
import { isEmpty } from '@ember/utils';
import { htmlSafe } from '@ember/template';
Expand Down Expand Up @@ -63,6 +63,12 @@ export default class HyperTableV2 extends Component<HyperTableV2Args> {
};
}

@computed('args.handler.columns.@each.{filters,order}')
get displayResetButton(): boolean {
const filtersApplied: boolean = this.args.handler.columns.some((col) => col.filters?.length || col.order);
return filtersApplied && this.features.global_filters_reset;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Reset Button Visibility Inconsistency

The displayResetButton computed property has two issues: it uses a truthy check for col.order, which can lead to inconsistent UI behavior compared to other components checking col.order !== undefined. Additionally, it depends on this.args.features (via this.features.global_filters_reset) but doesn't track this dependency, preventing dynamic updates to the button's visibility.

Fix in Cursor Fix in Web


get displayHeader(): boolean {
return Object.keys(this.features).some((key) => this.features[key as keyof FeatureSet]);
}
Expand Down
17 changes: 15 additions & 2 deletions tests/integration/components/hyper-table-v2-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,21 @@ module('Integration | Component | hyper-table-v2', function (hooks) {
});
});

module('FeatureSet: global_filters_reset', () => {
test('the global Reset all button is displayed by default', async function (assert) {
module('FeatureSet: global_filters_reset', function () {
test('the global Reset all button is not displayed when no filtering or ordering is applied', async function (assert) {
await render(hbs`<HyperTableV2 @handler={{this.handler}} @features={{this.features}} />`);
assert.dom('[data-control-name="hypertable_reset_filters_button"]').doesNotExist();
});

test('the global Reset all button is displayed when filtering is applied', async function (this: TestContext, assert) {
sinon.stub(this.tableManager, 'fetchColumns').callsFake(() => {
return Promise.resolve({
columns: [buildColumn('foo', { filters: [{ key: 'filter1', value: 'toto' }] })]
});
});

await this.handler.fetchColumns();

await render(hbs`<HyperTableV2 @handler={{this.handler}} @features={{this.features}} />`);
assert.dom('[data-control-name="hypertable_reset_filters_button"]').exists();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ module('Integration | Component | hyper-table-v2/filtering-renderers/common/colu
this.column = this.handler.columns[1];
});

test('it renders', async function (assert) {
test('When no filtering or ordering is applied, it renders with remove field button', async function (assert) {
await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
assert.dom('.upf-btn').exists({ count: 2 });
assert.dom('.upf-btn--destructive').exists();

assert.dom('.upf-btn').exists({ count: 1 });
assert.dom('.upf-btn--default').exists();
});

Expand All @@ -53,35 +53,63 @@ module('Integration | Component | hyper-table-v2/filtering-renderers/common/colu
await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
assert.dom('.upf-btn').exists({ count: 1 });
assert.dom('.upf-btn--destructive').doesNotExist();
assert.dom('.upf-btn--default').exists();
assert.dom('.upf-btn').doesNotExist();
});

test('Clicking on the clear button calls the #handler.resetColumns method', async function (this: TestContext, assert) {
const handlerSpy = sinon.spy(this.handler, 'resetColumns');
test('Clear and remove buttons are rendered when filtering is applied', async function (this: TestContext, assert) {
this.column.filters = [{ key: 'existence', value: 'without' }];

await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
await click('.upf-btn--default');
assert.ok(handlerSpy.calledOnce);

assert.dom('.upf-btn').exists({ count: 2 });
assert.dom('.upf-btn--secondary').exists();
assert.dom('.upf-btn--default').exists();
});

test('Clicking on the remove button calls the #handler.removeColumn method', async function (this: TestContext, assert) {
const handlerSpy = sinon.spy(this.handler, 'removeColumn');
test('Clear and remove buttons are rendered when ordering is applied', async function (this: TestContext, assert) {
this.column.order = { key: 'email', direction: 'asc' };

await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
await click('.upf-btn--destructive');
assert.ok(handlerSpy.calledOnce);

assert.dom('.upf-btn').exists({ count: 2 });
assert.dom('.upf-btn--secondary').exists();
assert.dom('.upf-btn--default').exists();
});

test('Clicking on the clear button calls the #handler.triggerEvent with the reset-columns event', async function (this: TestContext, assert) {
const handlerSpy = sinon.spy(this.handler, 'triggerEvent');
await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
await click('.upf-btn--default');
assert.ok(handlerSpy.calledOnceWith('reset-columns'));
module('Buttons call the right handler functions', function (this: TestContext, hooks) {
hooks.beforeEach(async function (this: TestContext) {
this.column.filters = [{ key: 'existence', value: 'without' }];
});

test('Clicking on the clear button calls the #handler.resetColumns method', async function (this: TestContext, assert) {
const handlerSpy = sinon.spy(this.handler, 'resetColumns');
await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
await click('.upf-btn--secondary');
assert.ok(handlerSpy.calledOnceWithExactly([this.column]));
});

test('Clicking on the remove button calls the #handler.removeColumn method', async function (this: TestContext, assert) {
const handlerSpy = sinon.spy(this.handler, 'removeColumn');
await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
await click('.upf-btn--default');
assert.ok(handlerSpy.calledOnceWithExactly(this.column.definition));
});

test('Clicking on the clear button calls the #handler.triggerEvent with the reset-columns event', async function (this: TestContext, assert) {
const handlerSpy = sinon.spy(this.handler, 'triggerEvent');
await render(
hbs`<HyperTableV2::FilteringRenderers::Common::ColumnActions @handler={{this.handler}} @column={{this.column}} />`
);
await click('.upf-btn--secondary');
assert.ok(handlerSpy.calledOnceWith('reset-columns'));
});
});
});
6 changes: 3 additions & 3 deletions translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ hypertable:
search: Search...
features:
filtering:
reset_all: Reset Filters
reset_all: Reset filters
table_views:
title: Table Views
manage_fields:
Expand All @@ -13,8 +13,8 @@ hypertable:
search_placeholder: Search...
no_columns: No columns found
column:
remove: Remove Field
clear_filters: Clear Filters
remove: Remove field
clear_filters: Clear filters
scroll_to_end: More
ordering:
label: Order By
Expand Down