Skip to content

Commit

Permalink
Revert plugins/main/public/components/common/data-grid/use-data-grid.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
guidomodarelli committed Sep 27, 2024
1 parent e92c395 commit 1c4fe66
Showing 1 changed file with 240 additions and 0 deletions.
240 changes: 240 additions & 0 deletions plugins/main/public/components/common/data-grid/use-data-grid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
import {
EuiDataGridCellValueElementProps,
EuiDataGridColumn,
EuiDataGridProps,
EuiDataGridSorting,
} from '@elastic/eui';
import React, { useEffect, useMemo, useState } from 'react';
import { SearchResponse } from '@opensearch-project/opensearch/api/types';
// ToDo: check how create this methods
import {
parseData,
getFieldFormatted,
parseColumns,
} from './data-grid-service';
import {
Filter,
IndexPattern,
} from '../../../../../../src/plugins/data/common';
import { EuiDataGridPaginationProps } from '@opensearch-project/oui';

export interface PaginationOptions
extends Pick<
EuiDataGridPaginationProps,
'pageIndex' | 'pageSize' | 'pageSizeOptions'
> {}

type SortingColumns = EuiDataGridSorting['columns'];

const MAX_ENTRIES_PER_QUERY = 10000;
const DEFAULT_PAGE_INDEX = 0;
const DEFAULT_PAGE_SIZE = 15;
const DEFAULT_PAGE_SIZE_OPTIONS = [DEFAULT_PAGE_SIZE, 25, 50, 100];
const DEFAULT_PAGINATION_OPTIONS: PaginationOptions = {
pageIndex: DEFAULT_PAGE_INDEX,
pageSize: DEFAULT_PAGE_SIZE,
pageSizeOptions: DEFAULT_PAGE_SIZE_OPTIONS,
};

export interface RenderColumn {
render: (value: any, rowItem: object) => string | React.ReactNode;
}

export type tDataGridColumn = Partial<RenderColumn> & EuiDataGridColumn;

export type tDataGridRenderColumn = RenderColumn & EuiDataGridColumn;

export type tDataGridProps = {
indexPattern: IndexPattern;
results: SearchResponse;
defaultColumns: tDataGridColumn[];
renderColumns?: tDataGridRenderColumn[];
DocViewInspectButton: ({
rowIndex,
}: EuiDataGridCellValueElementProps) => React.JSX.Element;
ariaLabelledBy: string;
useDefaultPagination?: boolean;
pagination?: typeof DEFAULT_PAGINATION_OPTIONS;
filters?: Filter[];
setFilters?: (filters: Filter[]) => void;
};

export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => {
const {
indexPattern,
DocViewInspectButton,
results,
defaultColumns: columns,
renderColumns,
useDefaultPagination = false,
pagination: paginationProps = {},
filters = [],
setFilters = () => {},
} = props;
const [columnVisibility, setVisibility] = useState(() =>
columns.map(({ id }) => id),
);
/** Rows */
const [rows, setRows] = useState<any[]>([]);
const rowCount = results ? (results?.hits?.total as number) : 0;
/** Sorting **/
// get default sorting from default columns
const getDefaultSorting = () => {
const defaultSort = columns.find(
column => column.isSortable || column.defaultSortDirection,
);
return defaultSort
? [
{
id: defaultSort.id,
direction: defaultSort.defaultSortDirection || 'desc',
},
]
: [];
};
const defaultSorting: SortingColumns = getDefaultSorting();
const [sortingColumns, setSortingColumns] = useState(defaultSorting);
const onSort = (sortingColumns: SortingColumns) => {
setSortingColumns(sortingColumns);
};
/** Pagination **/
const [pagination, setPagination] = useState<
typeof DEFAULT_PAGINATION_OPTIONS
>(
useDefaultPagination
? DEFAULT_PAGINATION_OPTIONS
: {
...DEFAULT_PAGINATION_OPTIONS,
...paginationProps,
},
);

const onChangeItemsPerPage = useMemo(
() => (pageSize: number) =>
setPagination(pagination => ({
...pagination,
pageSize,
pageIndex: 0,
})),
[rows, rowCount],
);
const onChangePage = (pageIndex: number) =>
setPagination(pagination => ({ ...pagination, pageIndex }));

useEffect(() => {
setRows(results?.hits?.hits || []);
}, [results, results?.hits, results?.hits?.total]);

useEffect(() => {
setPagination(pagination => ({ ...pagination, pageIndex: 0 }));
}, [rowCount]);

const renderCellValue = ({
rowIndex,
columnId,
}: {
rowIndex: number;
columnId: string;
}) => {
const rowsParsed = parseData(rows);
// On the context data always is stored the current page data (pagination)
// then the rowIndex is relative to the current page
const relativeRowIndex = rowIndex % pagination.pageSize;
if (rowsParsed.hasOwnProperty(relativeRowIndex)) {
const fieldFormatted = getFieldFormatted(
relativeRowIndex,
columnId,
indexPattern,
rowsParsed,
);
// check if column have render method initialized
const column = columns.find(column => column.id === columnId);
if (column && column.render) {
return column.render(fieldFormatted, rowsParsed[relativeRowIndex]);
}
// check if column have render method in renderColumns prop
const renderColumn = renderColumns?.find(
column => column.id === columnId,
);
if (renderColumn) {
return renderColumn.render(
fieldFormatted,
rowsParsed[relativeRowIndex],
);
}

return fieldFormatted;
}
return null;
};

const leadingControlColumns = useMemo(() => {
return [
{
id: 'inspectCollapseColumn',
headerCellRender: () => null,
rowCellRender: (props: EuiDataGridCellValueElementProps) =>
DocViewInspectButton({
...props,
rowIndex: props.rowIndex % pagination.pageSize,
}),
width: 40,
},
];
}, [results]);

const filterColumns = () => {
const allColumns = parseColumns(
indexPattern?.fields || [],
columns,
indexPattern,
rows,
pagination.pageSize,
filters,
setFilters,
);
const columnMatch = [];
const columnNonMatch = [];

for (const item of allColumns) {
if (columnVisibility.includes(item.name)) {
columnMatch.push(item);
} else {
columnNonMatch.push(item);
}
}

return [...columnMatch, ...columnNonMatch];
};

const defaultColumnsPosition = (columnsVisibility, defaultColumns) => {
const defaults = defaultColumns
.map(item => item.id)
.filter(id => columnsVisibility.includes(id));

const nonDefaults = columnsVisibility.filter(
item => !defaultColumns.map(item => item.id).includes(item),
);

return [...defaults, ...nonDefaults];
};

return {
'aria-labelledby': props.ariaLabelledBy,
columns: filterColumns(),
columnVisibility: {
visibleColumns: defaultColumnsPosition(columnVisibility, columns),
setVisibleColumns: setVisibility,
},
renderCellValue: renderCellValue,
leadingControlColumns: leadingControlColumns,
rowCount:
rowCount < MAX_ENTRIES_PER_QUERY ? rowCount : MAX_ENTRIES_PER_QUERY,
sorting: { columns: sortingColumns, onSort },
pagination: {
...pagination,
onChangeItemsPerPage: onChangeItemsPerPage,
onChangePage: onChangePage,
},
} as EuiDataGridProps;
};

0 comments on commit 1c4fe66

Please sign in to comment.