mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Discover] Truncate table header to 3 lines (#171013)
Truncates table headers to 3 lines:
<img width="1146" alt="Screenshot 2023-11-29 at 13 51 18"
src="900f649a
-75a6-437c-9df2-6e7791149038">
---------
Co-authored-by: Davis McPhee <davis.mcphee@elastic.co>
This commit is contained in:
parent
daa980fe73
commit
4842e42502
9 changed files with 756 additions and 144 deletions
|
@ -43,35 +43,250 @@ Array [
|
|||
[Function],
|
||||
[Function],
|
||||
],
|
||||
"display": <div
|
||||
aria-label="timestamp - this field represents the time that events occurred."
|
||||
css={
|
||||
"display": <Memo(DataTableTimeColumnHeader)
|
||||
dataView={
|
||||
Object {
|
||||
"map": undefined,
|
||||
"name": "1sxf1pk",
|
||||
"next": undefined,
|
||||
"styles": "
|
||||
text-align: left;
|
||||
",
|
||||
"toString": [Function],
|
||||
"docvalueFields": Array [],
|
||||
"fields": Array [
|
||||
Object {
|
||||
"filterable": true,
|
||||
"name": "_index",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "bytes",
|
||||
"filterable": true,
|
||||
"name": "bytes",
|
||||
"scripted": false,
|
||||
"type": "number",
|
||||
},
|
||||
Object {
|
||||
"displayName": "scripted",
|
||||
"filterable": false,
|
||||
"name": "scripted",
|
||||
"scripted": true,
|
||||
"type": "number",
|
||||
},
|
||||
],
|
||||
"getComputedFields": [Function],
|
||||
"getFieldByName": [MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
Array [
|
||||
"timestamp",
|
||||
],
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
Array [
|
||||
"timestamp",
|
||||
],
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
Array [
|
||||
"timestamp",
|
||||
],
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"getFormatterForField": [MockFunction],
|
||||
"getIndexPattern": [Function],
|
||||
"getName": [Function],
|
||||
"getSourceFiltering": [Function],
|
||||
"getTimeField": [Function],
|
||||
"id": "index-pattern-with-timefield-id",
|
||||
"isPersisted": [Function],
|
||||
"isTimeBased": [Function],
|
||||
"isTimeNanosBased": [Function],
|
||||
"metaFields": Array [
|
||||
"_index",
|
||||
"_score",
|
||||
],
|
||||
"name": "index-pattern-with-timefield",
|
||||
"timeFieldName": "timestamp",
|
||||
"title": "index-pattern-with-timefield-title",
|
||||
"toMinimalSpec": [Function],
|
||||
"toSpec": [Function],
|
||||
"type": "default",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="This field represents the time that events occurred."
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
>
|
||||
<React.Fragment>
|
||||
timestamp
|
||||
|
||||
<EuiIcon
|
||||
type="clock"
|
||||
/>
|
||||
</React.Fragment>
|
||||
</EuiToolTip>
|
||||
</div>,
|
||||
dataViewField={
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
}
|
||||
}
|
||||
/>,
|
||||
"displayAsText": "timestamp",
|
||||
"id": "timestamp",
|
||||
"initialWidth": 212,
|
||||
|
@ -357,6 +572,7 @@ Array [
|
|||
"type": "default",
|
||||
}
|
||||
}
|
||||
showColumnTokens={true}
|
||||
/>,
|
||||
"displayAsText": "extension",
|
||||
"id": "extension",
|
||||
|
@ -640,6 +856,7 @@ Array [
|
|||
"type": "default",
|
||||
}
|
||||
}
|
||||
showColumnTokens={true}
|
||||
/>,
|
||||
"displayAsText": "message",
|
||||
"id": "message",
|
||||
|
@ -963,6 +1180,7 @@ Array [
|
|||
"type": "default",
|
||||
}
|
||||
}
|
||||
showColumnTokens={true}
|
||||
/>,
|
||||
"displayAsText": "extension",
|
||||
"id": "extension",
|
||||
|
@ -1279,6 +1497,7 @@ Array [
|
|||
"type": "default",
|
||||
}
|
||||
}
|
||||
showColumnTokens={true}
|
||||
/>,
|
||||
"displayAsText": "message",
|
||||
"id": "message",
|
||||
|
@ -1431,35 +1650,166 @@ Array [
|
|||
[Function],
|
||||
[Function],
|
||||
],
|
||||
"display": <div
|
||||
aria-label="timestamp - this field represents the time that events occurred."
|
||||
css={
|
||||
"display": <Memo(DataTableTimeColumnHeader)
|
||||
dataView={
|
||||
Object {
|
||||
"map": undefined,
|
||||
"name": "1sxf1pk",
|
||||
"next": undefined,
|
||||
"styles": "
|
||||
text-align: left;
|
||||
",
|
||||
"toString": [Function],
|
||||
"docvalueFields": Array [],
|
||||
"fields": Array [
|
||||
Object {
|
||||
"filterable": true,
|
||||
"name": "_index",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "bytes",
|
||||
"filterable": true,
|
||||
"name": "bytes",
|
||||
"scripted": false,
|
||||
"type": "number",
|
||||
},
|
||||
Object {
|
||||
"displayName": "scripted",
|
||||
"filterable": false,
|
||||
"name": "scripted",
|
||||
"scripted": true,
|
||||
"type": "number",
|
||||
},
|
||||
],
|
||||
"getComputedFields": [Function],
|
||||
"getFieldByName": [MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
Array [
|
||||
"timestamp",
|
||||
],
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"getFormatterForField": [MockFunction],
|
||||
"getIndexPattern": [Function],
|
||||
"getName": [Function],
|
||||
"getSourceFiltering": [Function],
|
||||
"getTimeField": [Function],
|
||||
"id": "index-pattern-with-timefield-id",
|
||||
"isPersisted": [Function],
|
||||
"isTimeBased": [Function],
|
||||
"isTimeNanosBased": [Function],
|
||||
"metaFields": Array [
|
||||
"_index",
|
||||
"_score",
|
||||
],
|
||||
"name": "index-pattern-with-timefield",
|
||||
"timeFieldName": "timestamp",
|
||||
"title": "index-pattern-with-timefield-title",
|
||||
"toMinimalSpec": [Function],
|
||||
"toSpec": [Function],
|
||||
"type": "default",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="This field represents the time that events occurred."
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
>
|
||||
<React.Fragment>
|
||||
timestamp
|
||||
|
||||
<EuiIcon
|
||||
type="clock"
|
||||
/>
|
||||
</React.Fragment>
|
||||
</EuiToolTip>
|
||||
</div>,
|
||||
dataViewField={
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
}
|
||||
}
|
||||
/>,
|
||||
"displayAsText": "timestamp",
|
||||
"id": "timestamp",
|
||||
"initialWidth": 212,
|
||||
|
@ -1613,35 +1963,208 @@ Array [
|
|||
[Function],
|
||||
[Function],
|
||||
],
|
||||
"display": <div
|
||||
aria-label="timestamp - this field represents the time that events occurred."
|
||||
css={
|
||||
"display": <Memo(DataTableTimeColumnHeader)
|
||||
dataView={
|
||||
Object {
|
||||
"map": undefined,
|
||||
"name": "1sxf1pk",
|
||||
"next": undefined,
|
||||
"styles": "
|
||||
text-align: left;
|
||||
",
|
||||
"toString": [Function],
|
||||
"docvalueFields": Array [],
|
||||
"fields": Array [
|
||||
Object {
|
||||
"filterable": true,
|
||||
"name": "_index",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "bytes",
|
||||
"filterable": true,
|
||||
"name": "bytes",
|
||||
"scripted": false,
|
||||
"type": "number",
|
||||
},
|
||||
Object {
|
||||
"displayName": "scripted",
|
||||
"filterable": false,
|
||||
"name": "scripted",
|
||||
"scripted": true,
|
||||
"type": "number",
|
||||
},
|
||||
],
|
||||
"getComputedFields": [Function],
|
||||
"getFieldByName": [MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
Array [
|
||||
"timestamp",
|
||||
],
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
Array [
|
||||
"timestamp",
|
||||
],
|
||||
Array [
|
||||
"extension",
|
||||
],
|
||||
Array [
|
||||
"message",
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "extension",
|
||||
"filterable": true,
|
||||
"name": "extension",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": Object {
|
||||
"displayName": "message",
|
||||
"filterable": false,
|
||||
"name": "message",
|
||||
"scripted": false,
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
"getFormatterForField": [MockFunction],
|
||||
"getIndexPattern": [Function],
|
||||
"getName": [Function],
|
||||
"getSourceFiltering": [Function],
|
||||
"getTimeField": [Function],
|
||||
"id": "index-pattern-with-timefield-id",
|
||||
"isPersisted": [Function],
|
||||
"isTimeBased": [Function],
|
||||
"isTimeNanosBased": [Function],
|
||||
"metaFields": Array [
|
||||
"_index",
|
||||
"_score",
|
||||
],
|
||||
"name": "index-pattern-with-timefield",
|
||||
"timeFieldName": "timestamp",
|
||||
"title": "index-pattern-with-timefield-title",
|
||||
"toMinimalSpec": [Function],
|
||||
"toSpec": [Function],
|
||||
"type": "default",
|
||||
}
|
||||
}
|
||||
>
|
||||
<EuiToolTip
|
||||
content="This field represents the time that events occurred."
|
||||
delay="regular"
|
||||
display="inlineBlock"
|
||||
position="top"
|
||||
>
|
||||
<React.Fragment>
|
||||
timestamp
|
||||
|
||||
<EuiIcon
|
||||
type="clock"
|
||||
/>
|
||||
</React.Fragment>
|
||||
</EuiToolTip>
|
||||
</div>,
|
||||
dataViewField={
|
||||
Object {
|
||||
"aggregatable": true,
|
||||
"displayName": "timestamp",
|
||||
"filterable": true,
|
||||
"name": "timestamp",
|
||||
"scripted": false,
|
||||
"sortable": true,
|
||||
"type": "date",
|
||||
}
|
||||
}
|
||||
/>,
|
||||
"displayAsText": "timestamp",
|
||||
"id": "timestamp",
|
||||
"initialWidth": 212,
|
||||
|
|
|
@ -36,6 +36,10 @@
|
|||
border-top: $euiBorderThin;
|
||||
}
|
||||
|
||||
.euiDataGridHeaderCell {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.euiDataGrid--headerUnderline .euiDataGridHeaderCell {
|
||||
border-bottom: $euiBorderThin;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,10 @@ export interface UnifiedDataTableProps {
|
|||
* Field tokens could be rendered in column header next to the field name.
|
||||
*/
|
||||
showColumnTokens?: boolean;
|
||||
/**
|
||||
* Determines number of rows of a column header
|
||||
*/
|
||||
headerRowHeight?: number;
|
||||
/**
|
||||
* If set, the given document is displayed in a flyout
|
||||
*/
|
||||
|
@ -352,6 +356,7 @@ export const UnifiedDataTable = ({
|
|||
columns,
|
||||
columnTypes,
|
||||
showColumnTokens,
|
||||
headerRowHeight,
|
||||
controlColumnIds = CONTROL_COLUMN_IDS_DEFAULT,
|
||||
dataView,
|
||||
loadingState,
|
||||
|
@ -662,6 +667,7 @@ export const UnifiedDataTable = ({
|
|||
visibleCellActions,
|
||||
columnTypes,
|
||||
showColumnTokens,
|
||||
headerRowHeight,
|
||||
}),
|
||||
[
|
||||
onFilter,
|
||||
|
@ -681,6 +687,7 @@ export const UnifiedDataTable = ({
|
|||
visibleCellActions,
|
||||
columnTypes,
|
||||
showColumnTokens,
|
||||
headerRowHeight,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ describe('DataTableColumnHeader', function () {
|
|||
columnName="bytes"
|
||||
columnDisplayName="bytesDisplayName"
|
||||
dataView={stubLogstashDataView}
|
||||
showColumnTokens
|
||||
/>
|
||||
);
|
||||
expect(component.text()).toBe('NumberbytesDisplayName');
|
||||
|
@ -81,6 +82,7 @@ describe('DataTableColumnHeader', function () {
|
|||
bytes: 'keyword',
|
||||
}}
|
||||
dataView={stubLogstashDataView}
|
||||
showColumnTokens
|
||||
/>
|
||||
);
|
||||
expect(component.text()).toBe('KeywordbytesDisplayName');
|
||||
|
@ -93,6 +95,7 @@ describe('DataTableColumnHeader', function () {
|
|||
columnName="_source"
|
||||
columnDisplayName="Document"
|
||||
dataView={stubLogstashDataView}
|
||||
showColumnTokens
|
||||
/>
|
||||
);
|
||||
expect(component.text()).toBe('Document');
|
||||
|
@ -105,6 +108,7 @@ describe('DataTableColumnHeader', function () {
|
|||
columnName="nested_user"
|
||||
columnDisplayName="Nested User"
|
||||
dataView={stubDataViewWithNested}
|
||||
showColumnTokens
|
||||
/>
|
||||
);
|
||||
expect(component.text()).toBe('NestedNested User');
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { css } from '@emotion/react';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { css, CSSObject } from '@emotion/react';
|
||||
import { EuiIcon, EuiTextBlockTruncate, EuiToolTip } from '@elastic/eui';
|
||||
import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import { FieldIcon, getFieldIconProps } from '@kbn/field-utils';
|
||||
import { isNestedFieldParent } from '@kbn/discover-utils';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { euiThemeVars } from '@kbn/ui-theme';
|
||||
import type { DataTableColumnTypes } from '../types';
|
||||
|
||||
interface DataTableColumnHeaderProps {
|
||||
|
@ -19,40 +21,56 @@ interface DataTableColumnHeaderProps {
|
|||
columnName: string | null;
|
||||
columnDisplayName: string;
|
||||
columnTypes?: DataTableColumnTypes;
|
||||
headerRowHeight?: number;
|
||||
showColumnTokens?: boolean;
|
||||
}
|
||||
|
||||
export const DataTableColumnHeader: React.FC<DataTableColumnHeaderProps> = (props) => {
|
||||
const { columnDisplayName, columnName, columnTypes, dataView } = props;
|
||||
const {
|
||||
columnDisplayName,
|
||||
showColumnTokens,
|
||||
columnName,
|
||||
columnTypes,
|
||||
dataView,
|
||||
headerRowHeight = 1,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<ColumnHeaderTruncateContainer headerRowHeight={headerRowHeight}>
|
||||
{showColumnTokens && (
|
||||
<DataTableColumnToken
|
||||
columnName={columnName}
|
||||
columnTypes={columnTypes}
|
||||
dataView={dataView}
|
||||
/>
|
||||
)}
|
||||
<DataTableColumnTitle columnDisplayName={columnDisplayName} />
|
||||
</ColumnHeaderTruncateContainer>
|
||||
);
|
||||
};
|
||||
|
||||
const DataTableColumnToken: React.FC<
|
||||
Pick<DataTableColumnHeaderProps, 'columnName' | 'columnTypes' | 'dataView'>
|
||||
> = (props) => {
|
||||
const { columnName, columnTypes, dataView } = props;
|
||||
const columnToken = useMemo(
|
||||
() => getRenderedToken({ columnName, columnTypes, dataView }),
|
||||
[columnName, columnTypes, dataView]
|
||||
);
|
||||
|
||||
return (
|
||||
<EuiFlexGroup
|
||||
direction="row"
|
||||
wrap={false}
|
||||
responsive={false}
|
||||
alignItems="center"
|
||||
gutterSize="xs"
|
||||
css={css`
|
||||
.euiDataGridHeaderCell--numeric & {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
`}
|
||||
>
|
||||
{columnToken && <EuiFlexItem grow={false}>{columnToken}</EuiFlexItem>}
|
||||
<EuiFlexItem
|
||||
grow={false}
|
||||
className="eui-displayInline eui-textTruncate"
|
||||
data-test-subj="unifiedDataTableColumnTitle"
|
||||
>
|
||||
{columnDisplayName}
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
return columnToken ? (
|
||||
<span css={{ paddingRight: euiThemeVars.euiSizeXS }}>{columnToken}</span>
|
||||
) : null;
|
||||
};
|
||||
|
||||
const DataTableColumnTitle: React.FC<Pick<DataTableColumnHeaderProps, 'columnDisplayName'>> = ({
|
||||
columnDisplayName,
|
||||
}) => {
|
||||
return <span data-test-subj="unifiedDataTableColumnTitle">{columnDisplayName}</span>;
|
||||
};
|
||||
|
||||
const fieldIconCss: CSSObject = { verticalAlign: 'bottom' };
|
||||
|
||||
function getRenderedToken({
|
||||
dataView,
|
||||
columnName,
|
||||
|
@ -65,19 +83,83 @@ function getRenderedToken({
|
|||
// for text-based searches
|
||||
if (columnTypes) {
|
||||
return columnTypes[columnName] && columnTypes[columnName] !== 'unknown' ? ( // renders an icon or nothing
|
||||
<FieldIcon type={columnTypes[columnName]} />
|
||||
<FieldIcon type={columnTypes[columnName]} css={fieldIconCss} />
|
||||
) : null;
|
||||
}
|
||||
|
||||
const dataViewField = dataView.getFieldByName(columnName);
|
||||
|
||||
if (dataViewField) {
|
||||
return <FieldIcon {...getFieldIconProps(dataViewField)} />;
|
||||
return <FieldIcon {...getFieldIconProps(dataViewField)} css={fieldIconCss} />;
|
||||
}
|
||||
|
||||
if (isNestedFieldParent(columnName, dataView)) {
|
||||
return <FieldIcon type="nested" />;
|
||||
return <FieldIcon type="nested" css={fieldIconCss} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const ColumnHeaderTruncateContainer = ({
|
||||
headerRowHeight = 1,
|
||||
children,
|
||||
}: {
|
||||
headerRowHeight: number;
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<EuiTextBlockTruncate
|
||||
lines={headerRowHeight}
|
||||
css={css`
|
||||
overflow-wrap: anywhere;
|
||||
overflow: auto;
|
||||
white-space: normal;
|
||||
word-break: break-all;
|
||||
line-height: ${euiThemeVars.euiSize};
|
||||
text-align: left;
|
||||
.euiDataGridHeaderCell--numeric & {
|
||||
float: right;
|
||||
}
|
||||
`}
|
||||
>
|
||||
{children}
|
||||
</EuiTextBlockTruncate>
|
||||
);
|
||||
};
|
||||
|
||||
export const DataTableTimeColumnHeader = ({
|
||||
dataView,
|
||||
dataViewField,
|
||||
headerRowHeight = 1,
|
||||
}: {
|
||||
dataView: DataView;
|
||||
dataViewField?: DataViewField;
|
||||
headerRowHeight?: number;
|
||||
}) => {
|
||||
const timeFieldName = dataViewField?.customLabel ?? dataView.timeFieldName;
|
||||
const primaryTimeAriaLabel = i18n.translate(
|
||||
'unifiedDataTable.tableHeader.timeFieldIconTooltipAriaLabel',
|
||||
{
|
||||
defaultMessage: '{timeFieldName} - this field represents the time that events occurred.',
|
||||
values: { timeFieldName },
|
||||
}
|
||||
);
|
||||
const primaryTimeTooltip = i18n.translate('unifiedDataTable.tableHeader.timeFieldIconTooltip', {
|
||||
defaultMessage: 'This field represents the time that events occurred.',
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-label={primaryTimeAriaLabel}
|
||||
css={css`
|
||||
text-align: left;
|
||||
`}
|
||||
>
|
||||
<EuiToolTip content={primaryTimeTooltip}>
|
||||
<ColumnHeaderTruncateContainer headerRowHeight={headerRowHeight}>
|
||||
{timeFieldName} <EuiIcon type="clock" />
|
||||
</ColumnHeaderTruncateContainer>
|
||||
</EuiToolTip>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -11,11 +11,8 @@ import { i18n } from '@kbn/i18n';
|
|||
import {
|
||||
type EuiDataGridColumn,
|
||||
type EuiDataGridColumnCellAction,
|
||||
EuiIcon,
|
||||
EuiScreenReaderOnly,
|
||||
EuiToolTip,
|
||||
} from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { ToastsStart, IUiSettingsClient } from '@kbn/core/public';
|
||||
import { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
|
@ -28,9 +25,10 @@ import { SelectButton } from './data_table_document_selection';
|
|||
import { defaultTimeColumnWidth } from '../constants';
|
||||
import { buildCopyColumnNameButton, buildCopyColumnValuesButton } from './build_copy_column_button';
|
||||
import { buildEditFieldButton } from './build_edit_field_button';
|
||||
import { DataTableColumnHeader } from './data_table_column_header';
|
||||
import { DataTableColumnHeader, DataTableTimeColumnHeader } from './data_table_column_header';
|
||||
|
||||
const DataTableColumnHeaderMemoized = React.memo(DataTableColumnHeader);
|
||||
const DataTableTimeColumnHeaderMemoized = React.memo(DataTableTimeColumnHeader);
|
||||
|
||||
const openDetails = {
|
||||
id: 'openDetails',
|
||||
|
@ -86,6 +84,7 @@ function buildEuiGridColumn({
|
|||
visibleCellActions,
|
||||
columnTypes,
|
||||
showColumnTokens,
|
||||
headerRowHeight,
|
||||
}: {
|
||||
columnName: string;
|
||||
columnWidth: number | undefined;
|
||||
|
@ -103,6 +102,7 @@ function buildEuiGridColumn({
|
|||
visibleCellActions?: number;
|
||||
columnTypes?: DataTableColumnTypes;
|
||||
showColumnTokens?: boolean;
|
||||
headerRowHeight?: number;
|
||||
}) {
|
||||
const dataViewField = dataView.getFieldByName(columnName);
|
||||
const editFieldButton =
|
||||
|
@ -132,14 +132,17 @@ function buildEuiGridColumn({
|
|||
id: columnName,
|
||||
schema: getSchemaByKbnType(columnType),
|
||||
isSortable: isSortEnabled && (isPlainRecord || dataViewField?.sortable === true),
|
||||
display: showColumnTokens ? (
|
||||
<DataTableColumnHeaderMemoized
|
||||
dataView={dataView}
|
||||
columnName={columnName}
|
||||
columnDisplayName={columnDisplayName}
|
||||
columnTypes={columnTypes}
|
||||
/>
|
||||
) : undefined,
|
||||
display:
|
||||
showColumnTokens || (headerRowHeight && headerRowHeight !== 1) ? (
|
||||
<DataTableColumnHeaderMemoized
|
||||
dataView={dataView}
|
||||
columnName={columnName}
|
||||
columnDisplayName={columnDisplayName}
|
||||
columnTypes={columnTypes}
|
||||
showColumnTokens={showColumnTokens}
|
||||
headerRowHeight={headerRowHeight}
|
||||
/>
|
||||
) : undefined,
|
||||
displayAsText: columnDisplayName,
|
||||
actions: {
|
||||
showHide:
|
||||
|
@ -177,34 +180,16 @@ function buildEuiGridColumn({
|
|||
};
|
||||
|
||||
if (column.id === dataView.timeFieldName) {
|
||||
const timeFieldName = dataViewField?.customLabel ?? dataView.timeFieldName;
|
||||
const primaryTimeAriaLabel = i18n.translate(
|
||||
'unifiedDataTable.tableHeader.timeFieldIconTooltipAriaLabel',
|
||||
{
|
||||
defaultMessage: '{timeFieldName} - this field represents the time that events occurred.',
|
||||
values: { timeFieldName },
|
||||
}
|
||||
);
|
||||
const primaryTimeTooltip = i18n.translate('unifiedDataTable.tableHeader.timeFieldIconTooltip', {
|
||||
defaultMessage: 'This field represents the time that events occurred.',
|
||||
});
|
||||
|
||||
column.display = (
|
||||
<div
|
||||
aria-label={primaryTimeAriaLabel}
|
||||
css={css`
|
||||
text-align: left;
|
||||
`}
|
||||
>
|
||||
<EuiToolTip content={primaryTimeTooltip}>
|
||||
<>
|
||||
{timeFieldName} <EuiIcon type="clock" />
|
||||
</>
|
||||
</EuiToolTip>
|
||||
</div>
|
||||
<DataTableTimeColumnHeaderMemoized
|
||||
dataView={dataView}
|
||||
dataViewField={dataViewField}
|
||||
headerRowHeight={headerRowHeight}
|
||||
/>
|
||||
);
|
||||
column.initialWidth = defaultTimeColumnWidth;
|
||||
}
|
||||
|
||||
if (columnWidth > 0) {
|
||||
column.initialWidth = Number(columnWidth);
|
||||
}
|
||||
|
@ -228,6 +213,7 @@ export function getEuiGridColumns({
|
|||
visibleCellActions,
|
||||
columnTypes,
|
||||
showColumnTokens,
|
||||
headerRowHeight,
|
||||
}: {
|
||||
columns: string[];
|
||||
columnsCellActions?: EuiDataGridColumnCellAction[][];
|
||||
|
@ -248,6 +234,7 @@ export function getEuiGridColumns({
|
|||
visibleCellActions?: number;
|
||||
columnTypes?: DataTableColumnTypes;
|
||||
showColumnTokens?: boolean;
|
||||
headerRowHeight?: number;
|
||||
}) {
|
||||
const getColWidth = (column: string) => settings?.columns?.[column]?.width ?? 0;
|
||||
|
||||
|
@ -269,6 +256,7 @@ export function getEuiGridColumns({
|
|||
visibleCellActions,
|
||||
columnTypes,
|
||||
showColumnTokens,
|
||||
headerRowHeight,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ export function ContextAppContent({
|
|||
maxDocFieldsDisplayed={services.uiSettings.get(MAX_DOC_FIELDS_DISPLAYED)}
|
||||
renderDocumentView={renderDocumentView}
|
||||
services={services}
|
||||
headerRowHeight={3}
|
||||
/>
|
||||
</CellActionsProvider>
|
||||
</div>
|
||||
|
|
|
@ -422,6 +422,7 @@ function DiscoverDocumentsComponent({
|
|||
totalHits={totalHits}
|
||||
onFetchMoreRecords={onFetchMoreRecords}
|
||||
componentsTourSteps={TOUR_STEPS}
|
||||
headerRowHeight={3}
|
||||
externalCustomRenderers={externalCustomRenderers}
|
||||
/>
|
||||
</CellActionsProvider>
|
||||
|
|
|
@ -100,6 +100,8 @@ export function DiscoverGridEmbeddable(props: DiscoverGridEmbeddableProps) {
|
|||
maxDocFieldsDisplayed={props.services.uiSettings.get(MAX_DOC_FIELDS_DISPLAYED)}
|
||||
renderDocumentView={renderDocumentView}
|
||||
renderCustomToolbar={renderCustomToolbar}
|
||||
showColumnTokens
|
||||
headerRowHeight={3}
|
||||
/>
|
||||
</SavedSearchEmbeddableBase>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue