forked from opensearch-project/OpenSearch-Dashboards
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement table using table gird and remove doc_viewer_link
Issue Resolve opensearch-project#4442 Signed-off-by: ananzh <ananzh@amazon.com>
- Loading branch information
Showing
19 changed files
with
860 additions
and
225 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
src/plugins/discover/public/application/components/data_grid/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
export const toolbarVisibility = { | ||
showColumnSelector: { | ||
allowHide: false, | ||
allowReorder: true, | ||
}, | ||
showStyleSelector: false, | ||
}; |
9 changes: 9 additions & 0 deletions
9
src/plugins/discover/public/application/components/data_grid/data_grid_table.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.dscDiscoverGrid { | ||
height: 100%; | ||
width: 100%; | ||
overflow: hidden; | ||
|
||
.euiDataGrid__controls { | ||
border: $euiBorderThin; | ||
} | ||
} |
135 changes: 135 additions & 0 deletions
135
src/plugins/discover/public/application/components/data_grid/data_grid_table.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import './data_grid_table.scss'; | ||
import React, { useState, useMemo, useCallback } from 'react'; | ||
import { EuiDataGrid } from '@elastic/eui'; | ||
import { IndexPattern } from '../../../opensearch_dashboards_services'; | ||
import { fetchTableDataCell } from './data_grid_table_cell_value'; | ||
import { buildDataGridColumns, computeVisibleColumns } from './data_grid_table_columns'; | ||
import { DocViewExpandButton } from './data_grid_table_docview_expand_button'; | ||
import { DataGridFlyout } from './data_grid_table_flyout'; | ||
import { DataGridContext } from './data_grid_table_context'; | ||
import { toolbarVisibility } from './constants'; | ||
import { DocViewFilterFn } from '../../doc_views/doc_views_types'; | ||
import { DiscoverServices } from '../../../build_services'; | ||
import { OpenSearchSearchHit } from '../../doc_views/doc_views_types'; | ||
import { usePagination } from '../utils/use_pagination'; | ||
|
||
export interface DataGridTableProps { | ||
columns: string[]; | ||
indexPattern: IndexPattern; | ||
onAddColumn: (column: string) => void; | ||
onFilter: DocViewFilterFn; | ||
onRemoveColumn: (column: string) => void; | ||
onSort: (sort: string[][]) => void; | ||
rows: OpenSearchSearchHit[]; | ||
onSetColumns: (columns: string[]) => void; | ||
sort: Array<[string, string]>; | ||
displayTimeColumn: boolean; | ||
services: DiscoverServices; | ||
} | ||
|
||
export const DataGridTable = ({ | ||
columns, | ||
indexPattern, | ||
onAddColumn, | ||
onFilter, | ||
onRemoveColumn, | ||
onSetColumns, | ||
onSort, | ||
sort, | ||
rows, | ||
displayTimeColumn, | ||
services, | ||
}: DataGridTableProps) => { | ||
const [docViewExpand, setDocViewExpand] = useState(undefined); | ||
const rowCount = useMemo(() => (rows ? rows.length : 0), [rows]); | ||
const pagination = usePagination(rowCount); | ||
|
||
const sortingColumns = useMemo(() => sort.map(([id, direction]) => ({ id, direction })), [sort]); | ||
|
||
const onColumnSort = useCallback( | ||
(cols) => { | ||
onSort(cols.map(({ id, direction }: any) => [id, direction])); | ||
}, | ||
[onSort] | ||
); | ||
|
||
const renderCellValue = useMemo(() => fetchTableDataCell(indexPattern, rows), [ | ||
indexPattern, | ||
rows, | ||
]); | ||
|
||
const dataGridTableColumns = useMemo( | ||
() => buildDataGridColumns(columns, indexPattern, displayTimeColumn), | ||
[columns, indexPattern, displayTimeColumn] | ||
); | ||
|
||
const dataGridTableColumnsVisibility = useMemo( | ||
() => ({ | ||
visibleColumns: computeVisibleColumns(columns, indexPattern, displayTimeColumn) as string[], | ||
setVisibleColumns: (newColumns: string[]) => { | ||
onSetColumns(newColumns); | ||
}, | ||
}), | ||
[columns, indexPattern, displayTimeColumn, onSetColumns] | ||
); | ||
|
||
const sorting = useMemo(() => ({ columns: sortingColumns, onSort: onColumnSort }), [ | ||
sortingColumns, | ||
onColumnSort, | ||
]); | ||
|
||
const leadingControlColumns = useMemo(() => { | ||
return [ | ||
{ | ||
id: 'expandCollapseColumn', | ||
headerCellRender: () => null, | ||
rowCellRender: DocViewExpandButton, | ||
width: 40, | ||
}, | ||
]; | ||
}, []); | ||
|
||
return ( | ||
<DataGridContext.Provider | ||
value={{ | ||
docViewExpand, | ||
onFilter, | ||
setDocViewExpand, | ||
rows: rows || [], | ||
indexPattern, | ||
}} | ||
> | ||
<> | ||
<EuiDataGrid | ||
aria-labelledby="aria-labelledby" | ||
columns={dataGridTableColumns} | ||
columnVisibility={dataGridTableColumnsVisibility} | ||
leadingControlColumns={leadingControlColumns} | ||
data-test-subj="docTable" | ||
pagination={pagination} | ||
renderCellValue={renderCellValue} | ||
rowCount={rowCount} | ||
sorting={sorting} | ||
toolbarVisibility={toolbarVisibility} | ||
/> | ||
{docViewExpand && ( | ||
<DataGridFlyout | ||
indexPattern={indexPattern} | ||
hit={docViewExpand} | ||
columns={columns} | ||
onRemoveColumn={onRemoveColumn} | ||
onAddColumn={onAddColumn} | ||
onFilter={onFilter} | ||
onClose={() => setDocViewExpand(undefined)} | ||
services={services} | ||
/> | ||
)} | ||
</> | ||
</DataGridContext.Provider> | ||
); | ||
}; |
80 changes: 80 additions & 0 deletions
80
src/plugins/discover/public/application/components/data_grid/data_grid_table_cell_value.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React, { Fragment } from 'react'; | ||
import dompurify from 'dompurify'; | ||
|
||
import { | ||
EuiDataGridCellValueElementProps, | ||
EuiDescriptionList, | ||
EuiDescriptionListTitle, | ||
EuiDescriptionListDescription, | ||
} from '@elastic/eui'; | ||
import { IndexPattern } from '../../../opensearch_dashboards_services'; | ||
import { OpenSearchSearchHit } from '../../doc_views/doc_views_types'; | ||
|
||
function fetchSourceTypeDataCell( | ||
idxPattern: IndexPattern, | ||
row: Record<string, unknown>, | ||
columnId: string, | ||
isDetails: boolean | ||
) { | ||
if (isDetails) { | ||
return <span>{JSON.stringify(row[columnId], null, 2)}</span>; | ||
} | ||
const formattedRow = idxPattern.formatHit(row); | ||
|
||
return ( | ||
<EuiDescriptionList type="inline" compressed> | ||
{Object.keys(formattedRow).map((key) => ( | ||
<Fragment key={key}> | ||
<EuiDescriptionListTitle>{key}</EuiDescriptionListTitle> | ||
<EuiDescriptionListDescription | ||
dangerouslySetInnerHTML={{ __html: dompurify.sanitize(formattedRow[key]) }} | ||
/> | ||
</Fragment> | ||
))} | ||
</EuiDescriptionList> | ||
); | ||
} | ||
|
||
export const fetchTableDataCell = ( | ||
idxPattern: IndexPattern, | ||
dataRows: OpenSearchSearchHit[] | undefined | ||
) => ({ rowIndex, columnId, isDetails }: EuiDataGridCellValueElementProps) => { | ||
const singleRow = dataRows ? (dataRows[rowIndex] as Record<string, unknown>) : undefined; | ||
const flattenedRows = dataRows ? dataRows.map((hit) => idxPattern.flattenHit(hit)) : []; | ||
const flattenedRow = flattenedRows | ||
? (flattenedRows[rowIndex] as Record<string, unknown>) | ||
: undefined; | ||
const fieldInfo = idxPattern.fields.getByName(columnId); | ||
|
||
if (typeof singleRow === 'undefined' || typeof flattenedRow === 'undefined') { | ||
return <span>-</span>; | ||
} | ||
|
||
if (!fieldInfo?.type && flattenedRow && typeof flattenedRow[columnId] === 'object') { | ||
if (isDetails) { | ||
return <span>{JSON.stringify(flattenedRow[columnId], null, 2)}</span>; | ||
} | ||
|
||
return <span>{JSON.stringify(flattenedRow[columnId])}</span>; | ||
} | ||
|
||
if (fieldInfo?.type === '_source') { | ||
return fetchSourceTypeDataCell(idxPattern, singleRow, columnId, isDetails); | ||
} | ||
|
||
const formattedValue = idxPattern.formatField(singleRow, columnId); | ||
if (typeof formattedValue === 'undefined') { | ||
return <span>-</span>; | ||
} else { | ||
const sanitizedCellValue = dompurify.sanitize(idxPattern.formatField(singleRow, columnId)); | ||
return ( | ||
// eslint-disable-next-line react/no-danger | ||
<span dangerouslySetInnerHTML={{ __html: sanitizedCellValue }} /> | ||
); | ||
} | ||
}; |
68 changes: 68 additions & 0 deletions
68
src/plugins/discover/public/application/components/data_grid/data_grid_table_columns.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { EuiDataGridColumn } from '@elastic/eui'; | ||
import { i18n } from '@osd/i18n'; | ||
import { IndexPattern } from '../../../opensearch_dashboards_services'; | ||
|
||
export function buildDataGridColumns( | ||
columnNames: string[], | ||
idxPattern: IndexPattern, | ||
displayTimeColumn: boolean | ||
) { | ||
const timeFieldName = idxPattern.timeFieldName; | ||
let columnsToUse = columnNames; | ||
|
||
if (displayTimeColumn && idxPattern.timeFieldName && !columnNames.includes(timeFieldName)) { | ||
columnsToUse = [idxPattern.timeFieldName, ...columnNames]; | ||
} | ||
|
||
return columnsToUse.map((colName) => generateDataGridTableColumn(colName, idxPattern)); | ||
} | ||
|
||
export function generateDataGridTableColumn(colName: string, idxPattern: IndexPattern) { | ||
const timeLabel = i18n.translate('discover.timeLabel', { | ||
defaultMessage: 'Time', | ||
}); | ||
const idxPatternField = idxPattern.getFieldByName(colName); | ||
const dataGridCol: EuiDataGridColumn = { | ||
id: colName, | ||
schema: idxPatternField?.type, | ||
isSortable: idxPatternField?.sortable, | ||
display: idxPatternField?.displayName, | ||
actions: { | ||
showHide: true, | ||
showMoveLeft: false, | ||
showMoveRight: false, | ||
}, | ||
cellActions: [], | ||
}; | ||
|
||
if (dataGridCol.id === idxPattern.timeFieldName) { | ||
dataGridCol.display = `${timeLabel} (${idxPattern.timeFieldName})`; | ||
dataGridCol.initialWidth = 200; | ||
} | ||
if (dataGridCol.id === '_source') { | ||
dataGridCol.display = i18n.translate('discover.sourceLabel', { | ||
defaultMessage: 'Source', | ||
}); | ||
} | ||
return dataGridCol; | ||
} | ||
|
||
export function computeVisibleColumns( | ||
columnNames: string[], | ||
idxPattern: IndexPattern, | ||
displayTimeColumn: boolean | ||
) { | ||
const timeFieldName = idxPattern.timeFieldName; | ||
let visibleColumnNames = columnNames; | ||
|
||
if (displayTimeColumn && !columnNames.includes(timeFieldName)) { | ||
visibleColumnNames = [timeFieldName, ...columnNames]; | ||
} | ||
|
||
return visibleColumnNames; | ||
} |
20 changes: 20 additions & 0 deletions
20
src/plugins/discover/public/application/components/data_grid/data_grid_table_context.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React from 'react'; | ||
import { IndexPattern } from '../../../opensearch_dashboards_services'; | ||
import { DocViewFilterFn } from '../../doc_views/doc_views_types'; | ||
|
||
export interface DataGridContextProps { | ||
docViewExpand: any; | ||
onFilter: DocViewFilterFn; | ||
setDocViewExpand: (hit: any) => void; | ||
rows: any[]; | ||
indexPattern: IndexPattern; | ||
} | ||
|
||
export const DataGridContext = React.createContext<DataGridContextProps>( | ||
({} as unknown) as DataGridContextProps | ||
); |
27 changes: 27 additions & 0 deletions
27
...iscover/public/application/components/data_grid/data_grid_table_docview_expand_button.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright OpenSearch Contributors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import React, { useContext } from 'react'; | ||
import { EuiToolTip, EuiButtonIcon, EuiDataGridCellValueElementProps } from '@elastic/eui'; | ||
import { DataGridContext } from './data_grid_table_context'; | ||
|
||
export const DocViewExpandButton = ({ | ||
rowIndex, | ||
setCellProps, | ||
}: EuiDataGridCellValueElementProps) => { | ||
const { docViewExpand, setDocViewExpand, rows } = useContext(DataGridContext); | ||
const currentExpanded = rows[rowIndex]; | ||
const isCurrentExpanded = currentExpanded === docViewExpand; | ||
|
||
return ( | ||
<EuiToolTip content={`Expand row ${rowIndex}`}> | ||
<EuiButtonIcon | ||
onClick={() => setDocViewExpand(isCurrentExpanded ? undefined : currentExpanded)} | ||
iconType={isCurrentExpanded ? 'minimize' : 'expand'} | ||
aria-label={`Expand row ${rowIndex}`} | ||
/> | ||
</EuiToolTip> | ||
); | ||
}; |
Oops, something went wrong.