Skip to content

Commit

Permalink
hyper-table-v2/filtering-renderers/date: allow moving option key to b…
Browse files Browse the repository at this point in the history
…e 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
  • Loading branch information
phndiaye authored Dec 31, 2024
1 parent f9571d8 commit ed9f3d5
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 29 deletions.
11 changes: 11 additions & 0 deletions addon-test-support/rows-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
4 changes: 3 additions & 1 deletion addon/components/hyper-table-v2/cell-renderers/date.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{{#if this.value}}
{{this.formattedDate}}
{{else}}
<span class="font-color-gray-500">
{{or @column.definition.empty_state_message ""}}
</span>
{{/if}}
4 changes: 3 additions & 1 deletion addon/components/hyper-table-v2/cell-renderers/numeric.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
</div>
{{else}}
<div class="fx-row fx-1 fx-malign-start">
<span class="font-color-gray-500">
{{or @column.definition.empty_state_message ""}}
</span>
</div>
{{/if}}
4 changes: 3 additions & 1 deletion addon/components/hyper-table-v2/cell-renderers/text.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
{{this.value}}
</span>
{{else}}
<span class="font-color-gray-500">
</span>
{{/if}}
Original file line number Diff line number Diff line change
Expand Up @@ -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<HyperTableV2FilteringRenderersSearchArgs> {
@tracked searchQuery: string = '';
Expand All @@ -30,6 +32,10 @@ export default class HyperTableV2FilteringRenderersSearch extends Component<Hype
});
}

get filterKey(): string {
return this.args.filterKey ?? DEFAULT_FILTER_KEY;
}

setupOnlyNumericListener(element: HTMLElement): void {
const input = element.querySelector('input');
input?.addEventListener('keydown', onlyNumeric);
Expand All @@ -55,7 +61,7 @@ export default class HyperTableV2FilteringRenderersSearch extends Component<Hype
private _applyFilters(): void {
this.args.handler.applyFilters(this.args.column, [
{
key: 'value',
key: this.filterKey,
value: this.searchQuery
}
]);
Expand Down
16 changes: 10 additions & 6 deletions addon/components/hyper-table-v2/filtering-renderers/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ interface HyperTableV2FilteringRenderersDateArgs {
column: Column;
}

type FilterOption = 'moving' | 'fixed';
export type FilterOption = 'moving' | 'fixed';

const DEFAULT_MOVING_OPTION_KEY: FilterOption = 'moving';

export default class HyperTableV2FilteringRenderersDate extends Component<HyperTableV2FilteringRenderersDateArgs> {
@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' }
];

Expand All @@ -42,9 +46,9 @@ export default class HyperTableV2FilteringRenderersDate extends Component<HyperT
constructor(owner: unknown, args: HyperTableV2FilteringRenderersDateArgs) {
super(owner, args);

let filter = this.args.column.filters.find((f) => 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();
Expand Down Expand Up @@ -92,7 +96,7 @@ export default class HyperTableV2FilteringRenderersDate extends Component<HyperT
this.args.handler.applyFilters(this.args.column, [
{ key: 'lower_bound', value: '' },
{ key: 'upper_bound', value: '' },
{ key: 'moving', value: value }
{ key: this.movingOptionKey, value: value }
]);
}

Expand All @@ -102,7 +106,7 @@ export default class HyperTableV2FilteringRenderersDate extends Component<HyperT

if (fromDate && toDate) {
this.args.handler.applyFilters(this.args.column, [
{ key: 'moving', value: '' },
{ key: this.movingOptionKey, value: '' },
{ key: 'lower_bound', value: (+fromDate / 1000).toString() },
{ key: 'upper_bound', value: (+toDate / 1000).toString() }
]);
Expand Down
42 changes: 36 additions & 6 deletions addon/components/hyper-table-v2/filtering-renderers/numeric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ interface HyperTableV2FilteringRenderersNumericArgs {
}

const RANGE_DEBOUNCE_TIME = 500;
const DEFAULT_MULTIPLIER = 1;

export default class HyperTableV2FilteringRenderersNumeric extends Component<HyperTableV2FilteringRenderersNumericArgs> {
@tracked lowerBoundFilter = '';
@tracked upperBoundFilter = '';
@tracked lowerBoundFilter: string = '';
@tracked upperBoundFilter: string = '';

orderingDirections: { [key: string]: OrderDirection } = Object.freeze({
'0 — 9': 'asc',
Expand All @@ -27,14 +28,19 @@ export default class HyperTableV2FilteringRenderersNumeric extends Component<Hyp

constructor(owner: unknown, args: HyperTableV2FilteringRenderersNumericArgs) {
super(owner, args);

args.handler.on('reset-columns', (columns) => {
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 {
Expand Down Expand Up @@ -69,8 +75,32 @@ export default class HyperTableV2FilteringRenderersNumeric extends Component<Hyp

private _addRangeFilter(): void {
this.args.handler.applyFilters(this.args.column, [
...(this.lowerBoundFilter ? [{ key: 'lower_bound', value: this.lowerBoundFilter }] : []),
...(this.upperBoundFilter ? [{ key: 'upper_bound', value: this.upperBoundFilter }] : [])
...(this.lowerBoundFilter
? [{ key: 'lower_bound', value: (parseInt(this.lowerBoundFilter) * this.multiplier).toString() }]
: []),
...(this.upperBoundFilter
? [{ key: 'upper_bound', value: (parseInt(this.upperBoundFilter) * this.multiplier).toString() }]
: [])
]);
}

private initLowerBound(): void {
this.lowerBoundFilter = '';

if (this.args.column.filters.find((filter) => 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();
}
}
}
1 change: 1 addition & 0 deletions addon/core/interfaces/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type ColumnDefinition = {
filterable_by: string[] | null;
facetable: boolean;
facetable_by: string[] | null;
empty_state_message?: string;
position?: {
sticky: boolean;
};
Expand Down
12 changes: 6 additions & 6 deletions tests/integration/components/hyper-table-v2-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`<HyperTableV2 @handler={{this.handler}} />`);

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) {
Expand Down Expand Up @@ -155,7 +155,7 @@ module('Integration | Component | hyper-table-v2', function (hooks) {
await render(hbs`<HyperTableV2 @handler={{this.handler}} @features={{hash selection=true}} />`);

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) {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`<HyperTableV2::CellRenderers::Date @handler={{this.handler}} @row={{this.row}} @column={{this.column}} />`
);

assert.dom().hasText('No date');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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`<HyperTableV2::CellRenderers::Numeric @handler={{this.handler}} @row={{this.row}} @column={{this.column}} />`
);

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`<HyperTableV2::CellRenderers::Numeric @handler={{this.handler}} @row={{this.row}} @column={{this.column}} />`
);

assert.dom().hasText('Custom empty');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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`<HyperTableV2::CellRenderers::Text @handler={{this.handler}} @row={{this.row}} @column={{this.column}} />`
);

assert.dom().hasText('—');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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`<HyperTableV2::FilteringRenderers::Common::Search @handler={{this.handler}} @column={{this.column}} />`
Expand All @@ -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`<HyperTableV2::FilteringRenderers::Common::Search @handler={{this.handler}} @column={{this.column}} @filterKey="foobar" />`
);

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`<HyperTableV2::FilteringRenderers::Common::Search @handler={{this.handler}} @column={{this.column}} />`
Expand Down
Loading

0 comments on commit ed9f3d5

Please sign in to comment.