kibana/src/plugins/index_pattern_management/public/components/index_pattern_table/index_pattern_table.tsx
2021-11-10 18:34:50 -07:00

206 lines
5.5 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
EuiBadge,
EuiButton,
EuiBadgeGroup,
EuiButtonEmpty,
EuiInMemoryTable,
EuiPageHeader,
EuiSpacer,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { RouteComponentProps, withRouter, useLocation } from 'react-router-dom';
import React, { useEffect, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { reactRouterNavigate, useKibana } from '../../../../../plugins/kibana_react/public';
import { IndexPatternManagmentContext } from '../../types';
import { IndexPatternTableItem } from '../types';
import { getIndexPatterns } from '../utils';
import { getListBreadcrumbs } from '../breadcrumbs';
const pagination = {
initialPageSize: 10,
pageSizeOptions: [5, 10, 25, 50],
};
const sorting = {
sort: {
field: 'title',
direction: 'asc' as const,
},
};
const search = {
box: {
incremental: true,
schema: {
fields: { title: { type: 'string' } },
},
},
};
const title = i18n.translate('indexPatternManagement.dataViewTable.title', {
defaultMessage: 'Data views',
});
const securityDataView = i18n.translate(
'indexPatternManagement.indexPatternTable.badge.securityDataViewTitle',
{
defaultMessage: 'Security Data View',
}
);
interface Props extends RouteComponentProps {
canSave: boolean;
showCreateDialog?: boolean;
}
export const IndexPatternTable = ({
history,
canSave,
showCreateDialog: showCreateDialogProp = false,
}: Props) => {
const {
setBreadcrumbs,
uiSettings,
indexPatternManagementStart,
chrome,
data,
IndexPatternEditor,
} = useKibana<IndexPatternManagmentContext>().services;
const [indexPatterns, setIndexPatterns] = useState<IndexPatternTableItem[]>([]);
const [isLoadingIndexPatterns, setIsLoadingIndexPatterns] = useState<boolean>(true);
const [showCreateDialog, setShowCreateDialog] = useState<boolean>(showCreateDialogProp);
setBreadcrumbs(getListBreadcrumbs());
useEffect(() => {
(async function () {
const gettedIndexPatterns: IndexPatternTableItem[] = await getIndexPatterns(
uiSettings.get('defaultIndex'),
data.dataViews
);
setIndexPatterns(gettedIndexPatterns);
setIsLoadingIndexPatterns(false);
if (
gettedIndexPatterns.length === 0 ||
!(await data.dataViews.hasUserDataView().catch(() => false))
) {
setShowCreateDialog(true);
}
})();
}, [indexPatternManagementStart, uiSettings, data]);
chrome.docTitle.change(title);
const isRollup = new URLSearchParams(useLocation().search).get('type') === 'rollup';
const columns = [
{
field: 'title',
name: i18n.translate('indexPatternManagement.dataViewTable.nameColumn', {
defaultMessage: 'Name',
}),
render: (
name: string,
index: {
id: string;
tags?: Array<{
key: string;
name: string;
}>;
}
) => (
<>
<EuiButtonEmpty size="s" {...reactRouterNavigate(history, `patterns/${index.id}`)}>
{name}
</EuiButtonEmpty>
&emsp;
<EuiBadgeGroup gutterSize="s">
{index.id && index.id === 'security-solution' && (
<EuiBadge key="security-solution">{securityDataView}</EuiBadge>
)}
{index.tags &&
index.tags.map(({ key: tagKey, name: tagName }) => (
<EuiBadge key={tagKey}>{tagName}</EuiBadge>
))}
</EuiBadgeGroup>
</>
),
dataType: 'string' as const,
sortable: ({ sort }: { sort: string }) => sort,
},
];
const createButton = canSave ? (
<EuiButton
fill={true}
iconType="plusInCircle"
onClick={() => setShowCreateDialog(true)}
data-test-subj="createIndexPatternButton"
>
<FormattedMessage
id="indexPatternManagement.dataViewTable.createBtn"
defaultMessage="Create data view"
/>
</EuiButton>
) : (
<></>
);
if (isLoadingIndexPatterns) {
return <></>;
}
const displayIndexPatternEditor = showCreateDialog ? (
<IndexPatternEditor
onSave={(indexPattern) => {
history.push(`patterns/${indexPattern.id}`);
}}
onCancel={() => setShowCreateDialog(false)}
defaultTypeIsRollup={isRollup}
/>
) : (
<></>
);
return (
<div data-test-subj="indexPatternTable" role="region" aria-label={title}>
<EuiPageHeader
pageTitle={title}
description={
<FormattedMessage
id="indexPatternManagement.dataViewTable.indexPatternExplanation"
defaultMessage="Create and manage the data views that help you retrieve your data from Elasticsearch."
/>
}
bottomBorder
rightSideItems={[createButton]}
/>
<EuiSpacer size="l" />
<EuiInMemoryTable
allowNeutralSort={false}
itemId="id"
isSelectable={false}
items={indexPatterns}
columns={columns}
pagination={pagination}
sorting={sorting}
search={search}
/>
{displayIndexPatternEditor}
</div>
);
};
export const IndexPatternTableWithRouter = withRouter(IndexPatternTable);