Skip to content

Commit 7e82c6d

Browse files
committed
[Discover][UnifiedDataTable] Enable drag&drop for grid columns (#197832)
- Closes #195769 ## Summary Eui now supports reordering of grid columns by dra&drop elastic/eui#8015 The PR enables this functionality for UnifiedDataTable. ![Nov-01-2024 10-21-49](https://github.com/user-attachments/assets/bc47507c-7b9e-44c2-88d7-5f48f37924cb) ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios (cherry picked from commit 436405f)
1 parent 197256b commit 7e82c6d

8 files changed

Lines changed: 154 additions & 12 deletions

File tree

packages/kbn-unified-data-table/src/components/__snapshots__/data_table_columns.test.tsx.snap

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/kbn-unified-data-table/src/components/data_table.scss

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@
4040
background: transparent;
4141
}
4242

43-
.euiDataGridHeaderCell {
44-
align-items: start;
45-
46-
.euiPopover[class*='euiDataGridHeaderCell__popover'] {
47-
align-self: center;
48-
}
49-
}
50-
5143
.euiDataGrid--bordersHorizontal .euiDataGridHeader {
5244
border-top: none;
5345
}
@@ -101,6 +93,20 @@
10193
}
10294
}
10395

96+
// Custom styles for data grid header cell.
97+
// It can also be inside a portal (outside of `unifiedDataTable__inner`) when dragged.
98+
.unifiedDataTable__headerCell {
99+
align-items: start;
100+
101+
.euiDataGridHeaderCell__draggableIcon {
102+
padding-block: $euiSizeXS / 2; // to align with a token height
103+
}
104+
105+
.euiDataGridHeaderCell__button {
106+
margin-block: -$euiSizeXS; // to override Eui value for Density "Expanded"
107+
}
108+
}
109+
104110
.unifiedDataTable__table {
105111
flex-grow: 1;
106112
flex-shrink: 1;

packages/kbn-unified-data-table/src/components/data_table.test.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,5 +1354,49 @@ describe('UnifiedDataTable', () => {
13541354
},
13551355
EXTENDED_JEST_TIMEOUT
13561356
);
1357+
1358+
it(
1359+
'should have columnVisibility configuration',
1360+
async () => {
1361+
const component = await getComponent({
1362+
...getProps(),
1363+
columns: ['message'],
1364+
canDragAndDropColumns: true,
1365+
});
1366+
expect(component.find(EuiDataGrid).last().prop('columnVisibility')).toMatchInlineSnapshot(`
1367+
Object {
1368+
"canDragAndDropColumns": true,
1369+
"setVisibleColumns": [Function],
1370+
"visibleColumns": Array [
1371+
"@timestamp",
1372+
"message",
1373+
],
1374+
}
1375+
`);
1376+
},
1377+
EXTENDED_JEST_TIMEOUT
1378+
);
1379+
1380+
it(
1381+
'should disable drag&drop if Summary is present',
1382+
async () => {
1383+
const component = await getComponent({
1384+
...getProps(),
1385+
columns: [],
1386+
canDragAndDropColumns: true,
1387+
});
1388+
expect(component.find(EuiDataGrid).last().prop('columnVisibility')).toMatchInlineSnapshot(`
1389+
Object {
1390+
"canDragAndDropColumns": false,
1391+
"setVisibleColumns": [Function],
1392+
"visibleColumns": Array [
1393+
"@timestamp",
1394+
"_source",
1395+
],
1396+
}
1397+
`);
1398+
},
1399+
EXTENDED_JEST_TIMEOUT
1400+
);
13571401
});
13581402
});

packages/kbn-unified-data-table/src/components/data_table.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ export interface UnifiedDataTableProps {
137137
* Field tokens could be rendered in column header next to the field name.
138138
*/
139139
showColumnTokens?: boolean;
140+
/**
141+
* Set to true to allow users to drag and drop columns for reordering
142+
*/
143+
canDragAndDropColumns?: boolean;
140144
/**
141145
* Optional value for providing configuration setting for UnifiedDataTable header row height
142146
*/
@@ -425,6 +429,7 @@ export const UnifiedDataTable = ({
425429
columns,
426430
columnsMeta,
427431
showColumnTokens,
432+
canDragAndDropColumns,
428433
configHeaderRowHeight,
429434
headerRowHeightState,
430435
onUpdateHeaderRowHeight,
@@ -870,13 +875,20 @@ export const UnifiedDataTable = ({
870875
const schemaDetectors = useMemo(() => getSchemaDetectors(), []);
871876
const columnsVisibility = useMemo(
872877
() => ({
878+
canDragAndDropColumns: defaultColumns ? false : canDragAndDropColumns,
873879
visibleColumns,
874880
setVisibleColumns: (newColumns: string[]) => {
875881
const dontModifyColumns = !shouldPrependTimeFieldColumn(newColumns);
876882
onSetColumns(newColumns, dontModifyColumns);
877883
},
878884
}),
879-
[visibleColumns, onSetColumns, shouldPrependTimeFieldColumn]
885+
[
886+
visibleColumns,
887+
onSetColumns,
888+
shouldPrependTimeFieldColumn,
889+
canDragAndDropColumns,
890+
defaultColumns,
891+
]
880892
);
881893

882894
const canSetExpandedDoc = Boolean(setExpandedDoc && !!renderDocumentView);

packages/kbn-unified-data-table/src/components/data_table_columns.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ function buildEuiGridColumn({
258258
},
259259
cellActions,
260260
visibleCellActions,
261+
displayHeaderCellProps: { className: 'unifiedDataTable__headerCell' },
261262
};
262263

263264
if (column.id === dataView.timeFieldName) {

src/plugins/discover/public/components/discover_grid/discover_grid.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export const DiscoverGrid: React.FC<DiscoverGridProps> = ({
5858
return (
5959
<UnifiedDataTable
6060
showColumnTokens
61+
canDragAndDropColumns
6162
enableComparisonMode
6263
renderCustomToolbar={renderCustomToolbar}
6364
getRowIndicator={getRowIndicator}

test/functional/apps/discover/group2_data_grid3/_data_grid_column_widths.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,15 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
5656

5757
it('should not show reset width button for auto width column', async () => {
5858
await unifiedFieldList.clickFieldListItemAdd('@message');
59+
await header.waitUntilLoadingHasFinished();
60+
await discover.waitUntilSearchingHasFinished();
5961
expect(await dataGrid.resetColumnWidthExists('@message')).to.be(false);
6062
});
6163

6264
it('should show reset width button for absolute width column, and allow resetting to auto width', async () => {
6365
await unifiedFieldList.clickFieldListItemAdd('@message');
66+
await header.waitUntilLoadingHasFinished();
67+
await discover.waitUntilSearchingHasFinished();
6468
await testResizeColumn('@message');
6569
});
6670

test/functional/services/data_grid.ts

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,38 @@ export class DataGridService extends FtrService {
102102
public async resizeColumn(field: string, delta: number) {
103103
const header = await this.getHeaderElement(field);
104104
const originalWidth = (await header.getSize()).width;
105-
const resizer = await header.findByCssSelector(
106-
this.testSubjects.getCssSelector('dataGridColumnResizer')
107-
);
105+
106+
let resizer: WebElementWrapper | undefined;
107+
108+
if (await this.testSubjects.exists('euiDataGridHeaderDroppable')) {
109+
// if drag & drop is enabled for data grid columns
110+
const headerDraggableColumns = await this.find.allByCssSelector(
111+
'[data-test-subj="euiDataGridHeaderDroppable"] > div'
112+
);
113+
// searching for a common parent of the field column header and its resizer
114+
const fieldHeader: WebElementWrapper | null | undefined = (
115+
await Promise.all(
116+
headerDraggableColumns.map(async (column) => {
117+
const hasFieldColumn =
118+
(await column.findAllByCssSelector(`[data-gridcell-column-id="${field}"]`)).length >
119+
0;
120+
return hasFieldColumn ? column : null;
121+
})
122+
)
123+
).find(Boolean);
124+
125+
resizer = await fieldHeader?.findByTestSubject('dataGridColumnResizer');
126+
} else {
127+
// if drag & drop is not enabled for data grid columns
128+
resizer = await header.findByCssSelector(
129+
this.testSubjects.getCssSelector('dataGridColumnResizer')
130+
);
131+
}
132+
133+
if (!resizer) {
134+
throw new Error(`Unable to find column resizer for field ${field}`);
135+
}
136+
108137
await this.browser.dragAndDrop({ location: resizer }, { location: { x: delta, y: 0 } });
109138
return { originalWidth, newWidth: (await header.getSize()).width };
110139
}

0 commit comments

Comments
 (0)