diff --git a/packages/components/package.json b/packages/components/package.json
index a99475c364a..6d925b0c996 100644
--- a/packages/components/package.json
+++ b/packages/components/package.json
@@ -154,6 +154,7 @@
"./components/hds/advanced-table/th-button-sort.js": "./dist/_app_/components/hds/advanced-table/th-button-sort.js",
"./components/hds/advanced-table/th-button-tooltip.js": "./dist/_app_/components/hds/advanced-table/th-button-tooltip.js",
"./components/hds/advanced-table/th-context-menu.js": "./dist/_app_/components/hds/advanced-table/th-context-menu.js",
+ "./components/hds/advanced-table/th-filter-menu.js": "./dist/_app_/components/hds/advanced-table/th-filter-menu.js",
"./components/hds/advanced-table/th-reorder-drop-target.js": "./dist/_app_/components/hds/advanced-table/th-reorder-drop-target.js",
"./components/hds/advanced-table/th-reorder-handle.js": "./dist/_app_/components/hds/advanced-table/th-reorder-handle.js",
"./components/hds/advanced-table/th-resize-handle.js": "./dist/_app_/components/hds/advanced-table/th-resize-handle.js",
diff --git a/packages/components/src/components/hds/advanced-table/index.hbs b/packages/components/src/components/hds/advanced-table/index.hbs
index 8f8bae33e58..87569ba1513 100644
--- a/packages/components/src/components/hds/advanced-table/index.hbs
+++ b/packages/components/src/components/hds/advanced-table/index.hbs
@@ -3,6 +3,16 @@
SPDX-License-Identifier: MPL-2.0
}}
+{{#if this.hasActiveFilters}}
+
+{{/if}}
@@ -44,6 +47,15 @@
/>
{{#if @column}}
+ {{#if @column.filterOptions}}
+
+ {{/if}}
+
void;
onReorderDragEnd?: () => void;
@@ -59,6 +63,10 @@ export interface HdsAdvancedTableThSortSignature {
column: HdsAdvancedTableColumn,
side: HdsAdvancedTableColumnReorderSide
) => void;
+ onFilter?: (
+ key: string,
+ keyFilter?: HdsAdvancedTableFilter[] | HdsAdvancedTableFilter
+ ) => void;
};
Blocks: {
default?: [];
@@ -113,6 +121,22 @@ export default class HdsAdvancedTableThSort extends Component item['project-name'])),
+ ).map((value) => ({ value, label: value })),
+ 'run-status': Array.from(
+ new Set(SAMPLE_MODEL.map((item) => item['run-status'])),
+ ).map((value) => ({ value, label: value })),
+ 'vcs-repo': Array.from(
+ new Set(SAMPLE_MODEL.map((item) => item['vcs-repo'])),
+ ).map((value) => ({ value, label: value })),
+ 'terraform-version': Array.from(
+ new Set(SAMPLE_MODEL.map((item) => item['terraform-version'])),
+ ).map((value) => ({ value, label: value })),
+ 'state-terraform-version': Array.from(
+ new Set(SAMPLE_MODEL.map((item) => item['state-terraform-version'])),
+ ).map((value) => ({ value, label: value })),
+};
+
+const SAMPLE_COLUMNS = [
+ {
+ isSortable: true,
+ label: 'Name',
+ key: 'name',
+ width: 'max-content',
+ },
+ {
+ label: 'Project name',
+ key: 'project-name',
+ isSortable: true,
+ width: 'max-content',
+ filterOptions: SAMPLE_MODEL_VALUES['project-name'],
+ filterType: 'checkbox',
+ },
+ {
+ label: 'Current run ID',
+ key: 'current-run-id',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'Run status',
+ key: 'run-status',
+ isSortable: true,
+ width: 'max-content',
+ filterOptions: SAMPLE_MODEL_VALUES['run-status'],
+ filterType: 'checkbox',
+ },
+ {
+ label: 'Current run applied',
+ key: 'current-run-applied',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'VCS repo',
+ key: 'vcs-repo',
+ isSortable: true,
+ width: 'max-content',
+ filterOptions: SAMPLE_MODEL_VALUES['vcs-repo'],
+ filterType: 'checkbox',
+ },
+ {
+ label: 'Module count',
+ key: 'module-count',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'Modules',
+ key: 'modules',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'Provider count',
+ key: 'provider-count',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'Providers',
+ key: 'providers',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'Terraform version',
+ key: 'terraform-version',
+ isSortable: true,
+ width: 'max-content',
+ filterOptions: SAMPLE_MODEL_VALUES['terraform-version'],
+ filterType: 'radio',
+ },
+ {
+ label: 'State terraform version',
+ key: 'state-terraform-version',
+ isSortable: true,
+ width: 'max-content',
+ filterOptions: SAMPLE_MODEL_VALUES['state-terraform-version'],
+ filterType: 'radio',
+ },
+ {
+ label: 'Created',
+ key: 'created',
+ isSortable: true,
+ width: 'max-content',
+ },
+ {
+ label: 'Updated',
+ key: 'updated',
+ isSortable: true,
+ width: 'max-content',
+ },
+];
+
const updateModelWithSelectAllState = (
modelData: HdsAdvancedTableSignature['Args']['model'],
selectAllState: boolean,
@@ -499,6 +532,8 @@ export default class MockAppMainGenericAdvancedTable extends Component {
+ const filter = filters[name];
+ if (!filter) return;
+
+ if (Array.isArray(filter)) {
+ if (filter.length === 1) return filter[0]?.value;
+ return filter.map((f: HdsAdvancedTableSignature['Args']['filters'][]) => f.value);
+ }
+ return filter.value;
+ };
+
+ @action
+ onFilter(filters: HdsAdvancedTableSignature['Args']['filters']) {
+ this.filters = filters;
+ }
+
+ get demoModelFilteredData() {
+ const filterItem = (item: HdsAdvancedTableSignature['Args']['filters']): boolean => {
+ if (Object.keys(this.filters).length === 0) return true;
+ let match = true;
+ Object.keys(this.filters).forEach((key) => {
+ const keyFilters = this.valuesFromFilter(this.filters, key);
+ if (Array.isArray(keyFilters)) {
+ if (!keyFilters.includes(item[key])) {
+ match = false;
+ }
+ } else if (item[key] !== keyFilters) {
+ match = false;
+ }
+ });
+ return match;
+ };
+
+ return this.demoModel.filter(filterItem);
+ }
+
+ @action
+ onLiveFilterToggle(event: Event) {
+ const target = event.target as HTMLInputElement;
+ this.isLiveFilter = target.checked;
+ }
+
+
+
+ Live filtering
+
+
<:body as |B|>
{{! @glint-expect-error }}