Skip to content
3 changes: 2 additions & 1 deletion addon-test-support/index.ts
Original file line number Diff line number Diff line change
@@ -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 };
23 changes: 23 additions & 0 deletions addon-test-support/setup-table.ts
Original file line number Diff line number Diff line change
@@ -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
}
});
});
});
}
75 changes: 43 additions & 32 deletions addon/components/hyper-table-v2/column.hbs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<div id={{this.elementId}} class={{this.computedClasses}} ...attributes>
<header class="fx-row fx-malign-space-between" {{sortable-handle}}>
<div class="cell-header" role="button" {{on "click" this.orderColumn}}>
<div
class={{concat "cell-header" (if @delegatedFiltering " cell-header--delegated-filtering")}}
role="button"
{{on "click" this.orderColumn}}
>
<div class="header-title-container">
{{#if this.loadingHeaderComponent}}
<OSS::Icon @icon="fa-spinner fa-spin" />
Expand All @@ -10,7 +14,7 @@
@column={{@column}}
@extra={{this.headerComponent.args}}
/>
{{#if this.isOrderingIndicatorVisible}}
{{#if (and (not @delegatedFiltering) this.isOrderingIndicatorVisible)}}
<OSS::Icon
class="order-command"
@icon="fa-arrow-down-arrow-up"
Expand All @@ -19,40 +23,47 @@
{{/if}}
{{/if}}

{{#if (eq @column.order.direction "asc")}}
<OSS::Icon class="font-color-primary-500" @icon="fa-long-arrow-up" />
{{else if (eq @column.order.direction "desc")}}
<OSS::Icon class="font-color-primary-500" @icon="fa-long-arrow-down" />
{{/if}}
{{#unless @delegatedFiltering}}
{{#if (eq @column.order.direction "asc")}}
<OSS::Icon class="font-color-primary-500" @icon="fa-long-arrow-up" />
{{else if (eq @column.order.direction "desc")}}
<OSS::Icon class="font-color-primary-500" @icon="fa-long-arrow-down" />
{{/if}}
{{/unless}}
</div>
</div>

<div data-control-name={{concat "table_column_filter_sort_toggle_" @column.definition.key}}>
{{#if (or @column.definition.filterable @column.definition.orderable)}}
<OSS::Button
class={{concat "filter-command" (if (eq @handler.tetherOn @column.definition.key) " filter-command--opened")}}
@icon="fa-filter"
@square={{true}}
@size="xs"
{{on "click" this.toggleFilteringComponent}}
{{enable-tooltip title=(t "hypertable.column.filtering.tooltip") placement="top"}}
/>
{{/if}}

{{#if (and this.filteringComponent (eq @handler.tetherOn @column.definition.key))}}
<div
class="available-filters"
{{on-click-outside this.toggleFilteringComponent}}
{{did-insert this.setDropdownHeight}}
>
<this.filteringComponent.component
@handler={{@handler}}
@column={{@column}}
@extra={{this.filteringComponent.args}}
{{#unless @delegatedFiltering}}
<div data-control-name={{concat "table_column_filter_sort_toggle_" @column.definition.key}}>
{{#if (or @column.definition.filterable @column.definition.orderable)}}
<OSS::Button
class={{concat
"filter-command"
(if (eq @handler.tetherOn @column.definition.key) " filter-command--opened")
}}
@icon="fa-filter"
@square={{true}}
@size="xs"
{{on "click" this.toggleFilteringComponent}}
{{enable-tooltip title=(t "hypertable.column.filtering.tooltip") placement="top"}}
/>
</div>
{{/if}}
</div>
{{/if}}

{{#if (and this.filteringComponent (eq @handler.tetherOn @column.definition.key))}}
<div
class="available-filters"
{{on-click-outside this.toggleFilteringComponent}}
{{did-insert this.setDropdownHeight}}
>
<this.filteringComponent.component
@handler={{@handler}}
@column={{@column}}
@extra={{this.filteringComponent.args}}
/>
</div>
{{/if}}
</div>
{{/unless}}
</header>

{{yield}}
Expand Down
1 change: 1 addition & 0 deletions addon/components/hyper-table-v2/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<HyperTableV2ColumnArgs> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<div class="hypertable__facetting fx-col">
{{#if this.searchEnabled}}
<div class="fx-col fx-gap-px-6 margin-bottom-px-6">
<label>{{t "hypertable.column.filtering.search_term.label"}}</label>
{{#if this.displaySearchLabel}}
<label>{{t "hypertable.column.filtering.search_term.label"}}</label>
{{/if}}
<OSS::SearchField
@value={{this.searchQuery}}
@onChange={{this.onInputChanged}}
Expand Down Expand Up @@ -38,7 +40,7 @@
{{/if}}
{{yield (hash appliedFacets=this.appliedFacets facet=facet) to="facet-item"}}
</div>
<div class="count">
<div class="font-color-gray-400">
{{facet.count}}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface FacetsLoaderArgs {
facettingKey: string;
searchEnabled: boolean;
searchPlaceholder?: string;
displaySearchLabel?: boolean;
sortCompareFn?(a: Facet, b: Facet): number;
}

Expand Down Expand Up @@ -50,6 +51,10 @@ export default class HyperTableV2FacetsLoader extends Component<FacetsLoaderArgs
return this.args.searchEnabled ?? false;
}

get displaySearchLabel(): boolean {
return this.args.displaySearchLabel ?? true;
}

get searchPlaceholder(): string {
return this.args.searchPlaceholder ?? this.intl.t('hypertable.column.filtering.search_term.placeholder');
}
Expand Down Expand Up @@ -133,7 +138,7 @@ export default class HyperTableV2FacetsLoader extends Component<FacetsLoaderArgs
this.searchQuery
)
.then(({ facets, filtering_key }: FacetsResponse) => {
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);
Expand Down
97 changes: 54 additions & 43 deletions addon/components/hyper-table-v2/index.hbs
Original file line number Diff line number Diff line change
@@ -1,51 +1,57 @@
<div class="hypertable-container" {{will-destroy this.teardown}} ...attributes>
<div class="hypertable__upper-header">
<div class="fx-row">
<div class="left-side">
{{#if this.features.selection}}
<div class="selected-count">
{{format-number this.selectionCount}}
</div>
{{/if}}
{{#if (or (has-block "search") (has-block "contextual-actions") (has-block "table-actions") this.displayHeader)}}
<div class="hypertable__upper-header">
<div class="fx-row">
<div class="left-side">
{{#if this.features.selection}}
<div class="selected-count">
{{format-number this.selectionCount}}
</div>
{{/if}}

{{#if this.initialFetchColumnsDone}}
<div class="search">
{{#if (has-block "search")}}
{{yield to="search"}}
{{else if this.features.searchable}}
<HyperTableV2::Search @handler={{@handler}} />
{{/if}}
</div>
{{/if}}
{{#if (has-block "contextual-actions")}}
{{yield to="contextual-actions"}}
{{/if}}
</div>
<div class="right-side">
<OSS::Button
class="margin-right-xx-sm"
@label={{t "hypertable.features.filtering.reset_all"}}
{{on "click" this.resetFilters}}
@loading={{this.loadingResetFilters}}
data-control-name="hypertable_reset_filters_button"
/>
{{#if this.initialFetchColumnsDone}}
<div class="search">
{{#if (has-block "search")}}
{{yield to="search"}}
{{else if this.features.searchable}}
<HyperTableV2::Search @handler={{@handler}} />
{{/if}}
</div>
{{/if}}
{{#if (has-block "contextual-actions")}}
{{yield to="contextual-actions"}}
{{/if}}
</div>
<div class="right-side">
{{#if this.features.global_filters_reset}}
<OSS::Button
class="margin-right-px-12"
@label={{t "hypertable.features.filtering.reset_all"}}
{{on "click" this.resetFilters}}
@loading={{this.loadingResetFilters}}
data-control-name="hypertable_reset_filters_button"
/>
{{/if}}

{{#if (has-block "table-actions")}}
{{yield to="table-actions"}}
{{/if}}
{{#if (has-block "table-actions")}}
{{yield to="table-actions"}}
{{/if}}

<HyperTableV2::ManageColumns @handler={{@handler}} @didInsertColumn={{this.scrollToEnd}} />
{{#if this.features.manageable_fields}}
<HyperTableV2::ManageColumns @handler={{@handler}} @didInsertColumn={{this.scrollToEnd}} />
{{/if}}
</div>
</div>
<HyperTableV2::Selection
class={{if (gt this.selectionCount 0) "margin-top-px-18"}}
@selected={{this.selectionCount}}
@total={{@handler.rowsMeta.total}}
@intlKeyPath={{@options.selectionIntlKeyPath}}
@onSelectAll={{this.selectAllGlobal}}
@onClear={{this.clearSelection}}
/>
</div>
<HyperTableV2::Selection
class={{if (gt this.selectionCount 0) "margin-top-px-18"}}
@selected={{this.selectionCount}}
@total={{@handler.rowsMeta.total}}
@intlKeyPath={{@options.selectionIntlKeyPath}}
@onSelectAll={{this.selectAllGlobal}}
@onClear={{this.clearSelection}}
/>
</div>
{{/if}}

<div
class="hypertable__table hypertable__table--v2"
Expand Down Expand Up @@ -131,7 +137,11 @@
</div>
{{/if}}

<HyperTableV2::Column @handler={{@handler}} @column={{column}}>
<HyperTableV2::Column
@handler={{@handler}}
@column={{column}}
@delegatedFiltering={{@options.delegatedFiltering}}
>
{{#each @handler.rows as |row|}}
<HyperTableV2::Cell
@handler={{@handler}}
Expand All @@ -156,6 +166,7 @@
<HyperTableV2::Column
@handler={{@handler}}
@column={{column}}
@delegatedFiltering={{@options.delegatedFiltering}}
class={{if
column.definition.position.sticky
(concat "hypertable__column--sticky-" column.definition.position.side)
Expand Down
14 changes: 13 additions & 1 deletion addon/components/hyper-table-v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import { Column, Row } from '@upfluence/hypertable/core/interfaces';
type FeatureSet = {
selection: boolean;
searchable: boolean;
manageable_fields: boolean;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure what's the use of the feature flags? Is it to enable/disable one or another part of the feature?

global_filters_reset: boolean;
};

type OptionSet = {
selectionIntlKeyPath?: string;
delegatedFiltering?: boolean;
};

interface HyperTableV2Args {
Expand All @@ -23,7 +26,12 @@ interface HyperTableV2Args {
options?: OptionSet;
}

const DEFAULT_FEATURES_SET: FeatureSet = { selection: false, searchable: true };
const DEFAULT_FEATURES_SET: FeatureSet = {
selection: false,
searchable: true,
manageable_fields: true,
global_filters_reset: true
};
const RESET_DEBOUNCE_TIME = 300;

export default class HyperTableV2 extends Component<HyperTableV2Args> {
Expand Down Expand Up @@ -55,6 +63,10 @@ export default class HyperTableV2 extends Component<HyperTableV2Args> {
};
}

get displayHeader(): boolean {
return Object.keys(this.features).some((key) => this.features[key as keyof FeatureSet]);
}

get selectionCount(): number {
if (
!this.args.handler.rowsMeta ||
Expand Down
8 changes: 7 additions & 1 deletion addon/core/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -68,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;
Expand Down
5 changes: 5 additions & 0 deletions app/styles/columns.less
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
text-overflow: ellipsis;
white-space: nowrap;

&.cell-header--delegated-filtering {
overflow: visible;
width: 100%;
}

.header-title-container {
display: flex;
align-items: center;
Expand Down
Loading