;
@@ -28,6 +29,7 @@ export default class PageComponentsAdvancedTableRoute extends Route {
userDataShort: structuredClone(users.slice(0, 5)),
clusters,
spanningManualData: spanningCells,
+ infrastructureResources,
selectableData: selectableItems,
selectableDataDemo1: structuredClone(selectableItems),
selectableDataDemo2: structuredClone(selectableItems),
diff --git a/showcase/app/styles/showcase-pages/advanced-table.scss b/showcase/app/styles/showcase-pages/advanced-table.scss
index 69557896650..9f6bbef0307 100644
--- a/showcase/app/styles/showcase-pages/advanced-table.scss
+++ b/showcase/app/styles/showcase-pages/advanced-table.scss
@@ -41,6 +41,10 @@ body.page-components-advanced-table {
width: 400px;
}
+ .shw-component-advanced-table-fixed-width-wrapper--wide {
+ width: 600px;
+ }
+
.shw-component-advanced-table-with-pagination-demo-wrapper {
.hds-table + .hds-pagination {
margin-top: 16px;
@@ -83,4 +87,10 @@ body.page-components-advanced-table {
white-space: nowrap;
text-overflow: ellipsis;
}
+
+ .shw-component-advanced-table-reorder-handle-container
+ .hds-advanced-table__th-reorder-handle {
+ visibility: visible;
+ opacity: 1;
+ }
}
diff --git a/showcase/app/templates/page-components/advanced-table.hbs b/showcase/app/templates/page-components/advanced-table.hbs
index d473e2d70f8..f8f3bedf4bb 100644
--- a/showcase/app/templates/page-components/advanced-table.hbs
+++ b/showcase/app/templates/page-components/advanced-table.hbs
@@ -621,6 +621,240 @@
+ Reorderable columns
+
+
+ <:body as |B|>
+ {{! @glint-expect-error - this argument shouldn't be required, will be fixed by https://hashicorp.atlassian.net/browse/HDS-5167}}
+
+ {{#each R.orderedCells as |C|}}
+ {{#if (eq C.columnKey "artist")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.artist}}
+ {{else}}
+
+ {{#if (eq C.columnKey "album")}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.album}}
+
+ {{else if (eq C.columnKey "year")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{else}}
+
+
+
+
+
+ {{/if}}
+
+ {{/if}}
+ {{/each}}
+
+
+
+
+ Reorderable columns with sorting
+
+
+ <:body as |B|>
+
+ {{#each R.orderedCells as |C|}}
+ {{#if (eq C.columnKey "artist")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.artist}}
+ {{else}}
+
+ {{#if (eq C.columnKey "album")}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.album}}
+
+ {{else if (eq C.columnKey "year")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{else}}
+
+
+
+
+
+ {{/if}}
+
+ {{/if}}
+ {{/each}}
+
+
+
+
+ Reorderable columns with sticky header
+
+
+ <:body as |B|>
+
+ {{#each R.orderedCells as |C|}}
+ {{#if (eq C.columnKey "artist")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.artist}}
+ {{else}}
+
+ {{#if (eq C.columnKey "album")}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.album}}
+
+ {{else if (eq C.columnKey "year")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{else}}
+
+
+
+
+
+ {{/if}}
+
+ {{/if}}
+ {{/each}}
+
+
+
+
+ Reorderable columns with horizontal overflow
+
+
+
+ <:body as |B|>
+
+ {{#each R.orderedCells as |C|}}
+
+ {{#if (eq C.columnKey "status")}}
+ {{#if (eq (get B.data "status") "failing")}}
+
+ {{else if (eq (get B.data "status") "active")}}
+
+ {{else if (eq (get B.data "status") "pending")}}
+
+ {{else if (eq (get B.data "status") "establishing")}}
+
+ {{/if}}
+ {{else if (or (eq C.columnKey "created_at") (eq C.columnKey "last_run_time"))}}
+ {{#if (eq C.columnKey "created_at")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{format-date (get B.data "created_at")}}
+ {{else}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{format-date (get B.data "last_run_time")}}
+ {{/if}}
+ {{else if (or (eq C.columnKey "attached_policies") (eq C.columnKey "tags"))}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{#each C.content as |content|}}
+
+ {{/each}}
+
+ {{else}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{C.content}}
+ {{/if}}
+
+ {{/each}}
+
+
+
+
+
+ Reorderable columns with selectable rows
+
+
+
+ <:body as |B|>
+
+ {{#each R.orderedCells as |C|}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{C.content}}
+
+ {{/each}}
+
+
+
+
+
+
+
Resizable columns
{{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
@@ -721,6 +955,48 @@
+ Resizable and reorderable columns
+
+
+ <:body as |B|>
+ {{! @glint-expect-error - this argument shouldn't be required, will be fixed by https://hashicorp.atlassian.net/browse/HDS-5167}}
+
+ {{#each R.orderedCells as |C|}}
+ {{#if (eq C.columnKey "artist")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.artist}}
+ {{else}}
+
+ {{#if (eq C.columnKey "album")}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+ {{B.data.album}}
+
+ {{else if (eq C.columnKey "year")}}
+ {{! @glint-expect-error - will be fixed by https://hashicorp.atlassian.net/browse/HDS-5090}}
+
+ {{else}}
+
+
+
+
+
+ {{/if}}
+
+ {{/if}}
+ {{/each}}
+
+
+
+
Pinnable first column
@@ -2396,7 +2672,7 @@
@@ -2410,4 +2686,22 @@
+
+
+ ThReorderHandle
+
+
+ {{#each @model.STATES as |state|}}
+
+
+
+ {{/each}}
+
+
\ No newline at end of file
diff --git a/showcase/tests/integration/components/hds/advanced-table/index-test.js b/showcase/tests/integration/components/hds/advanced-table/index-test.js
index 74ed755e9b9..193505bc8c8 100644
--- a/showcase/tests/integration/components/hds/advanced-table/index-test.js
+++ b/showcase/tests/integration/components/hds/advanced-table/index-test.js
@@ -11,6 +11,7 @@ import {
focus,
setupOnerror,
find,
+ findAll,
settled,
triggerEvent,
triggerKeyEvent,
@@ -54,6 +55,90 @@ async function simulateRightPointerDrag(handle) {
await triggerEvent(window, 'pointerup', { button: 0 });
}
+function getColumnByLabel(columns, label) {
+ return columns.find((col) => col.label === label);
+}
+
+async function getColumnOrder(columns) {
+ const thElements = await findAll('.hds-advanced-table__th');
+
+ return thElements.map((th) => {
+ const column = getColumnByLabel(columns, th.textContent.trim());
+
+ return column ? column.key : null;
+ });
+}
+
+async function startReorderDrag(handleElement) {
+ return triggerEvent(handleElement, 'dragstart');
+}
+
+function getTargetElementFromColumnIndex(index) {
+ const dropTargets = findAll('.hds-advanced-table__th-reorder-drop-target');
+ const target = dropTargets[index];
+
+ if (target === null) {
+ throw new Error(
+ `Target column at index ${index} not found after drag started.`,
+ );
+ }
+
+ return target;
+}
+
+function getDragTargetPosition(targetElement, targetPosition) {
+ const targetRect = targetElement.getBoundingClientRect();
+ let clientX;
+
+ switch (targetPosition) {
+ case 'left':
+ clientX = targetRect.left + 1;
+ break;
+ case 'right':
+ clientX = targetRect.right - 1;
+ break;
+ default:
+ throw new Error(
+ `Invalid targetPosition: ${targetPosition}. Use 'left' or 'right'.`,
+ );
+ }
+
+ return { clientX, clientY: targetRect.top + targetRect.height / 2 };
+}
+
+async function dragOverTarget(target, { clientX, clientY }) {
+ await triggerEvent(target, 'dragenter', { clientX, clientY });
+ await triggerEvent(target, 'dragover', { clientX, clientY });
+}
+
+async function simulateColumnReorderDrag({
+ handleElement,
+ targetElement,
+ targetIndex,
+ targetPosition = 'left',
+}) {
+ await startReorderDrag(handleElement);
+
+ const target = targetElement ?? getTargetElementFromColumnIndex(targetIndex);
+ const { clientX, clientY } = getDragTargetPosition(target, targetPosition);
+
+ const eventOptions = { clientX, clientY };
+
+ await dragOverTarget(target, eventOptions);
+
+ // return the target event options for further use, if needed
+ return { target, eventOptions };
+}
+
+async function simulateColumnReorderDrop({
+ target,
+ handleElement,
+ eventOptions,
+}) {
+ await triggerEvent(target, 'drop', eventOptions);
+ await triggerEvent(handleElement, 'dragend');
+}
+
// we're using this for multiple tests so we'll declare context once and use it when we need it.
const setTableData = (context) => {
context.set('model', [
@@ -178,6 +263,19 @@ const setNestedTableData = (context) => {
]);
};
+const setReorderableColumnsTableData = (context) => {
+ context.set('model', [
+ { id: '1', artist: 'Nick Drake', album: 'Pink Moon', year: '1972' },
+ { id: '2', artist: 'The Beatles', album: 'Abbey Road', year: '1969' },
+ { id: '3', artist: 'Melanie', album: 'Candles in the Rain', year: '1971' },
+ ]);
+ context.set('columns', [
+ { key: 'artist', label: 'Artist' },
+ { key: 'album', label: 'Album' },
+ { key: 'year', label: 'Year' },
+ ]);
+};
+
const setResizableColumnsTableData = (context) => {
context.set('model', [
{ id: '1', col1: 'A', col2: 'B' },
@@ -282,6 +380,444 @@ const hbsResizableColumnsAdvancedTable = hbs`
module('Integration | Component | hds/advanced-table/index', function (hooks) {
setupRenderingTest(hooks);
+ module('column reordering', function (hooks) {
+ hooks.beforeEach(function () {
+ setReorderableColumnsTableData(this);
+ });
+
+ test('it renders reorder handles when reordering is enabled', async function (assert) {
+ this.set('hasReorderableColumns', false);
+
+ await render(
+ hbs``,
+ );
+
+ assert
+ .dom('.hds-advanced-table__th-reorder-handle')
+ .doesNotExist(
+ 'No reorder handles are rendered when reordering is disabled',
+ );
+
+ this.set('hasReorderableColumns', true);
+
+ assert
+ .dom('.hds-advanced-table__th-reorder-handle')
+ .exists({ count: 3 }, 'All columns have a reorder handle');
+ });
+
+ test('it does not render a reorder handle on the row selection column', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const selectAllThSelector =
+ '[role="columnheader"].hds-advanced-table__th--is-selectable';
+ const reorderHandleSelector = '.hds-advanced-table__th-reorder-handle';
+
+ assert
+ .dom(`${selectAllThSelector} ${reorderHandleSelector}`)
+ .doesNotExist(
+ 'No reorder handle is rendered on the row selection column',
+ );
+ });
+
+ test('columns can be reordered by dragging and dropping', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ let columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ this.columns.map((col) => col.key),
+ 'Initial column order is correct',
+ );
+
+ const expectedDropTargetIndex = 2;
+ const expectedDropTargetDropSide = 'right';
+
+ // get the first reorder handle
+ const reorderHandle = find('.hds-advanced-table__th-reorder-handle');
+
+ // drag to the right side of the last column
+ const { target, eventOptions } = await simulateColumnReorderDrag({
+ handleElement: reorderHandle,
+ targetIndex: expectedDropTargetIndex,
+ targetPosition: expectedDropTargetDropSide,
+ });
+
+ // get all drop targets for test reference
+ const dropTargets = findAll(
+ '.hds-advanced-table__th-reorder-drop-target',
+ );
+ const originDropTarget = dropTargets[0];
+ const destinationDropTarget = dropTargets[expectedDropTargetIndex];
+
+ assert
+ .dom(originDropTarget)
+ .hasClass(
+ 'hds-advanced-table__th-reorder-drop-target--is-being-dragged',
+ 'First column is being dragged',
+ );
+ assert
+ .dom(destinationDropTarget)
+ .hasClass(
+ 'hds-advanced-table__th-reorder-drop-target--is-dragging-over',
+ )
+ .hasClass(
+ `hds-advanced-table__th-reorder-drop-target--is-dragging-over--${expectedDropTargetDropSide}`,
+ );
+
+ await simulateColumnReorderDrop({
+ target,
+ handleElement: reorderHandle,
+ eventOptions,
+ });
+
+ columnOrder = await getColumnOrder(this.columns);
+
+ assert
+ .dom('.hds-advanced-table__th-reorder-drop-target')
+ .doesNotExist('Drop targets are removed after drop');
+ assert.deepEqual(
+ columnOrder,
+ [this.columns[1].key, this.columns[2].key, this.columns[0].key],
+ 'Columns are reordered correctly after drag and drop',
+ );
+ });
+
+ test('dropping a target on the nearest side of the next sibling does not reorder columns', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const initialColumnOrder = this.columns.map((col) => col.key);
+
+ let columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ initialColumnOrder,
+ 'Initial column order is correct',
+ );
+
+ const reorderHandle = find('.hds-advanced-table__th-reorder-handle');
+
+ const { target, eventOptions } = await simulateColumnReorderDrag({
+ handleElement: reorderHandle,
+ targetIndex: 1,
+ targetPosition: 'left',
+ });
+
+ const dropTargets = findAll(
+ '.hds-advanced-table__th-reorder-drop-target',
+ );
+ const originDropTarget = dropTargets[0];
+ const destinationDropTarget = dropTargets[1];
+
+ assert
+ .dom(originDropTarget)
+ .hasClass(
+ 'hds-advanced-table__th-reorder-drop-target--is-being-dragged',
+ 'First column is being dragged',
+ );
+ assert
+ .dom(destinationDropTarget)
+ .doesNotHaveClass(
+ 'hds-advanced-table__th-reorder-drop-target--is-dragging-over',
+ )
+ .doesNotHaveClass(
+ 'hds-advanced-table__th-reorder-drop-target--is-dragging-over--left',
+ );
+
+ await simulateColumnReorderDrop({
+ target,
+ handleElement: reorderHandle,
+ eventOptions,
+ });
+
+ columnOrder = await getColumnOrder(this.columns);
+
+ assert
+ .dom('.hds-advanced-table__th-reorder-drop-target')
+ .doesNotExist('Drop targets are removed after drop');
+ assert.deepEqual(
+ columnOrder,
+ initialColumnOrder,
+ 'Columns order is unchanged after drop on the nearest side',
+ );
+ });
+
+ test('it should show the context menu with the correct options when reordering is enabled', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const thElements = findAll('.hds-advanced-table__th'); // find all header cells
+
+ assert.ok(
+ thElements[0].querySelector('.hds-advanced-table__th-context-menu'),
+ 'context menu exists',
+ );
+
+ const firstContextMenuToggle = thElements[0].querySelector(
+ '.hds-dropdown-toggle-icon',
+ );
+ await click(firstContextMenuToggle);
+ assert.dom('[data-test-context-option-key="reorder-column"]').exists();
+ assert
+ .dom('[data-test-context-option-key="move-column-to-start"]')
+ .doesNotExist();
+ assert
+ .dom('[data-test-context-option-key="move-column-to-end"]')
+ .exists();
+
+ const secondContextMenuToggle = thElements[1].querySelector(
+ '.hds-dropdown-toggle-icon',
+ );
+ await click(secondContextMenuToggle);
+ assert.dom('[data-test-context-option-key="reorder-column"]').exists();
+ assert
+ .dom('[data-test-context-option-key="move-column-to-start"]')
+ .exists();
+ assert
+ .dom('[data-test-context-option-key="move-column-to-end"]')
+ .exists();
+
+ const lastContextMenuToggle = thElements[
+ thElements.length - 1
+ ].querySelector('.hds-dropdown-toggle-icon');
+ await click(lastContextMenuToggle);
+ assert.dom('[data-test-context-option-key="reorder-column"]').exists();
+ assert
+ .dom('[data-test-context-option-key="move-column-to-start"]')
+ .exists();
+ assert
+ .dom('[data-test-context-option-key="move-column-to-end"]')
+ .doesNotExist();
+ });
+
+ test('clicking the "Move column" context menu option focuses the reorder handle', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const thElements = findAll('.hds-advanced-table__th');
+
+ const firstContextMenuToggle = thElements[0].querySelector(
+ '.hds-dropdown-toggle-icon',
+ );
+ await click(firstContextMenuToggle);
+ await click('[data-test-context-option-key="reorder-column"]');
+
+ const firstReorderHandle = thElements[0].querySelector(
+ '.hds-advanced-table__th-reorder-handle',
+ );
+
+ assert.dom(firstReorderHandle).isFocused();
+ });
+
+ test('clicking the "Move column to start" context menu option moves the column to the start', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const thElements = findAll('.hds-advanced-table__th');
+
+ const secondContextMenuToggle = thElements[1].querySelector(
+ '.hds-dropdown-toggle-icon',
+ );
+ await click(secondContextMenuToggle);
+ await click('[data-test-context-option-key="move-column-to-start"]');
+
+ const columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ [this.columns[1].key, this.columns[0].key, this.columns[2].key],
+ 'The second column is moved to the start',
+ );
+ });
+
+ test('clicking the "Move column to end" context menu option moves the column to the end', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const thElements = findAll('.hds-advanced-table__th');
+
+ const secondContextMenuToggle = thElements[1].querySelector(
+ '.hds-dropdown-toggle-icon',
+ );
+ await click(secondContextMenuToggle);
+ await click('[data-test-context-option-key="move-column-to-end"]');
+
+ const columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ [this.columns[0].key, this.columns[2].key, this.columns[1].key],
+ 'The second column is moved to the end',
+ );
+ });
+
+ test('pressing "Left Arrow" and "Right Arrow" keys when the reorder handle is focused moves the column', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const thElements = findAll('.hds-advanced-table__th');
+ const firstThElement = thElements[0];
+ const firstReorderHandle = thElements[0].querySelector(
+ '.hds-advanced-table__th-reorder-handle',
+ );
+ await focus(firstThElement);
+ await focus(firstReorderHandle);
+ assert.dom(firstReorderHandle).isFocused();
+
+ await triggerKeyEvent(firstReorderHandle, 'keydown', 'ArrowRight');
+ let columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ [this.columns[1].key, this.columns[0].key, this.columns[2].key],
+ 'The first column is moved to the right',
+ );
+ assert.dom(firstReorderHandle).isFocused();
+
+ await triggerKeyEvent(firstReorderHandle, 'keydown', 'ArrowRight');
+ columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ [this.columns[1].key, this.columns[2].key, this.columns[0].key],
+ 'The second column is moved to the right',
+ );
+ assert.dom(firstReorderHandle).isFocused();
+
+ await triggerKeyEvent(firstReorderHandle, 'keydown', 'ArrowLeft');
+ columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ [this.columns[1].key, this.columns[0].key, this.columns[2].key],
+ 'The third column is moved back to the left',
+ );
+ assert.dom(firstReorderHandle).isFocused();
+ });
+
+ test('passing in columnOrder sets the initial order of the table columns', async function (assert) {
+ await render(
+ hbs``,
+ );
+
+ const columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ ['album', 'year', 'artist'],
+ 'The initial column order is set correctly',
+ );
+ });
+
+ test('updating columnOrder externally changes the order of the table columns', async function (assert) {
+ this.set('columnOrder', ['artist', 'album', 'year']);
+
+ await render(
+ hbs``,
+ );
+
+ let columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ ['artist', 'album', 'year'],
+ 'The initial column order is set correctly',
+ );
+
+ this.set('columnOrder', ['year', 'album', 'artist']);
+ columnOrder = await getColumnOrder(this.columns);
+ assert.deepEqual(
+ columnOrder,
+ ['year', 'album', 'artist'],
+ 'The column order is updated correctly',
+ );
+ });
+
+ test('it throws an assertion if @hasStickyFirstColumn is true and @hasReorderableColumns is true', async function (assert) {
+ const errorMessage =
+ 'Cannot have both reorderable columns and a sticky first column.';
+
+ setupOnerror(function (error) {
+ assert.strictEqual(error.message, `Assertion Failed: ${errorMessage}`);
+ });
+
+ await render(
+ hbs``,
+ );
+
+ assert.throws(function () {
+ throw new Error(errorMessage);
+ });
+ });
+ });
+
test('it should render the component with a CSS class that matches the component name', async function (assert) {
setSortableTableData(this);
@@ -379,6 +915,34 @@ module('Integration | Component | hds/advanced-table/index', function (hooks) {
.hasClass('hds-advanced-table--valign-top');
});
+ test('it throws an assertion if @hasReorderableColumns and has nested rows', async function (assert) {
+ const errorMessage =
+ 'Cannot have reorderable columns if there are nested rows.';
+
+ setNestedTableData(this);
+ assert.expect(2);
+ setupOnerror(function (error) {
+ assert.strictEqual(error.message, `Assertion Failed: ${errorMessage}`);
+ });
+ await render(hbs`
+ <:body as |B|>
+
+ {{B.data.name}}
+ {{B.data.age}}
+
+
+ `);
+
+ assert.throws(function () {
+ throw new Error(errorMessage);
+ });
+ });
+
test('it throws an assertion if @isStriped and has nested rows', async function (assert) {
const errorMessage =
'@isStriped must not be true if there are nested rows.';
diff --git a/showcase/tests/unit/components/hds/advanced-table/models/column-test.js b/showcase/tests/unit/components/hds/advanced-table/models/column-test.js
index f867437a7a6..5854adfd993 100644
--- a/showcase/tests/unit/components/hds/advanced-table/models/column-test.js
+++ b/showcase/tests/unit/components/hds/advanced-table/models/column-test.js
@@ -260,22 +260,24 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('index getter returns correct column position', function (assert) {
+ const mockColumns = [
+ new HdsAdvancedTableColumn({
+ column: { label: 'First', key: 'first' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Second', key: 'second' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Third', key: 'third' },
+ table: null,
+ }),
+ ];
// Create mock table with multiple columns
const mockTable = {
- columns: [
- new HdsAdvancedTableColumn({
- column: { label: 'First', key: 'first' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Second', key: 'second' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Third', key: 'third' },
- table: null,
- }),
- ],
+ columns: mockColumns,
+ orderedColumns: mockColumns,
};
// Set table reference for each column
@@ -299,7 +301,7 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('index getter returns -1 when table has no columns', function (assert) {
- const mockTable = { columns: [] };
+ const mockTable = { columns: [], orderedColumns: [] };
const column = new HdsAdvancedTableColumn({
column: { label: 'Test', key: 'test' },
table: mockTable,
@@ -309,13 +311,15 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('index getter returns -1 when column key does not exist in table', function (assert) {
+ const columns = [
+ new HdsAdvancedTableColumn({
+ column: { label: 'Other', key: 'other' },
+ table: null,
+ }),
+ ];
const mockTable = {
- columns: [
- new HdsAdvancedTableColumn({
- column: { label: 'Other', key: 'other' },
- table: null,
- }),
- ],
+ columns,
+ orderedColumns: columns,
};
mockTable.columns[0].table = mockTable;
@@ -332,17 +336,19 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('isFirst getter identifies first column correctly', function (assert) {
+ const columns = [
+ new HdsAdvancedTableColumn({
+ column: { label: 'First', key: 'first' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Second', key: 'second' },
+ table: null,
+ }),
+ ];
const mockTable = {
- columns: [
- new HdsAdvancedTableColumn({
- column: { label: 'First', key: 'first' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Second', key: 'second' },
- table: null,
- }),
- ],
+ columns,
+ orderedColumns: columns,
};
mockTable.columns.forEach((col) => (col.table = mockTable));
@@ -358,7 +364,7 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('isFirst getter returns false when index is -1', function (assert) {
- const mockTable = { columns: [] };
+ const mockTable = { columns: [], orderedColumns: [] };
const column = new HdsAdvancedTableColumn({
column: { label: 'Test', key: 'test' },
table: mockTable,
@@ -368,21 +374,23 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('isLast getter identifies last column correctly', function (assert) {
+ const columns = [
+ new HdsAdvancedTableColumn({
+ column: { label: 'First', key: 'first' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Second', key: 'second' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Third', key: 'third' },
+ table: null,
+ }),
+ ];
const mockTable = {
- columns: [
- new HdsAdvancedTableColumn({
- column: { label: 'First', key: 'first' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Second', key: 'second' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Third', key: 'third' },
- table: null,
- }),
- ],
+ columns,
+ orderedColumns: columns,
};
mockTable.columns.forEach((col) => (col.table = mockTable));
@@ -402,7 +410,7 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('isLast getter returns false when index is -1', function (assert) {
- const mockTable = { columns: [] };
+ const mockTable = { columns: [], orderedColumns: [] };
const column = new HdsAdvancedTableColumn({
column: { label: 'Test', key: 'test' },
table: mockTable,
@@ -412,21 +420,23 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('siblings getter returns correct previous and next columns', function (assert) {
+ const columns = [
+ new HdsAdvancedTableColumn({
+ column: { label: 'First', key: 'first' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Second', key: 'second' },
+ table: null,
+ }),
+ new HdsAdvancedTableColumn({
+ column: { label: 'Third', key: 'third' },
+ table: null,
+ }),
+ ];
const mockTable = {
- columns: [
- new HdsAdvancedTableColumn({
- column: { label: 'First', key: 'first' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Second', key: 'second' },
- table: null,
- }),
- new HdsAdvancedTableColumn({
- column: { label: 'Third', key: 'third' },
- table: null,
- }),
- ],
+ columns,
+ orderedColumns: columns,
};
mockTable.columns.forEach((col) => (col.table = mockTable));
@@ -472,7 +482,7 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('siblings getter returns empty object when index is -1', function (assert) {
- const mockTable = { columns: [] };
+ const mockTable = { columns: [], orderedColumns: [] };
const column = new HdsAdvancedTableColumn({
column: { label: 'Test', key: 'test' },
table: mockTable,
@@ -483,13 +493,15 @@ module('Unit | Component | hds/advanced-table/models/column', function () {
});
test('siblings getter works with single column', function (assert) {
+ const columns = [
+ new HdsAdvancedTableColumn({
+ column: { label: 'Only', key: 'only' },
+ table: null,
+ }),
+ ];
const mockTable = {
- columns: [
- new HdsAdvancedTableColumn({
- column: { label: 'Only', key: 'only' },
- table: null,
- }),
- ],
+ columns,
+ orderedColumns: columns,
};
mockTable.columns[0].table = mockTable;