148 lines
4.1 KiB
TypeScript
148 lines
4.1 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;
|
|
* you may not use this file except in compliance with the Elastic License.
|
|
*/
|
|
|
|
import './datapanel.scss';
|
|
import React, { memo, useCallback } from 'react';
|
|
import { i18n } from '@kbn/i18n';
|
|
import {
|
|
EuiText,
|
|
EuiNotificationBadge,
|
|
EuiSpacer,
|
|
EuiAccordion,
|
|
EuiLoadingSpinner,
|
|
EuiIconTip,
|
|
} from '@elastic/eui';
|
|
import classNames from 'classnames';
|
|
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
|
import { IndexPatternField } from './types';
|
|
import { FieldItem } from './field_item';
|
|
import { Query, Filter } from '../../../../../src/plugins/data/public';
|
|
import { DatasourceDataPanelProps } from '../types';
|
|
import { IndexPattern } from './types';
|
|
import { ChartsPluginSetup } from '../../../../../src/plugins/charts/public';
|
|
|
|
export interface FieldItemSharedProps {
|
|
core: DatasourceDataPanelProps['core'];
|
|
data: DataPublicPluginStart;
|
|
chartsThemeService: ChartsPluginSetup['theme'];
|
|
indexPattern: IndexPattern;
|
|
highlight?: string;
|
|
query: Query;
|
|
dateRange: DatasourceDataPanelProps['dateRange'];
|
|
filters: Filter[];
|
|
}
|
|
|
|
export interface FieldsAccordionProps {
|
|
initialIsOpen: boolean;
|
|
onToggle: (open: boolean) => void;
|
|
id: string;
|
|
label: string;
|
|
helpTooltip?: string;
|
|
hasLoaded: boolean;
|
|
fieldsCount: number;
|
|
isFiltered: boolean;
|
|
paginatedFields: IndexPatternField[];
|
|
fieldProps: FieldItemSharedProps;
|
|
renderCallout: JSX.Element;
|
|
exists: (field: IndexPatternField) => boolean;
|
|
showExistenceFetchError?: boolean;
|
|
hideDetails?: boolean;
|
|
}
|
|
|
|
export const InnerFieldsAccordion = function InnerFieldsAccordion({
|
|
initialIsOpen,
|
|
onToggle,
|
|
id,
|
|
label,
|
|
helpTooltip,
|
|
hasLoaded,
|
|
fieldsCount,
|
|
isFiltered,
|
|
paginatedFields,
|
|
fieldProps,
|
|
renderCallout,
|
|
exists,
|
|
hideDetails,
|
|
showExistenceFetchError,
|
|
}: FieldsAccordionProps) {
|
|
const renderField = useCallback(
|
|
(field: IndexPatternField) => (
|
|
<FieldItem
|
|
{...fieldProps}
|
|
key={field.name}
|
|
field={field}
|
|
exists={exists(field)}
|
|
hideDetails={hideDetails}
|
|
/>
|
|
),
|
|
[fieldProps, exists, hideDetails]
|
|
);
|
|
|
|
const titleClassname = classNames({
|
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
lnsInnerIndexPatternDataPanel__titleTooltip: !!helpTooltip,
|
|
});
|
|
|
|
return (
|
|
<EuiAccordion
|
|
initialIsOpen={initialIsOpen}
|
|
onToggle={onToggle}
|
|
data-test-subj={id}
|
|
id={id}
|
|
buttonContent={
|
|
<EuiText size="xs">
|
|
<strong className={titleClassname}>{label}</strong>
|
|
{!!helpTooltip && (
|
|
<EuiIconTip
|
|
aria-label={helpTooltip}
|
|
type="questionInCircle"
|
|
color="subdued"
|
|
size="s"
|
|
position="right"
|
|
content={helpTooltip}
|
|
iconProps={{
|
|
className: 'eui-alignTop',
|
|
}}
|
|
/>
|
|
)}
|
|
</EuiText>
|
|
}
|
|
extraAction={
|
|
showExistenceFetchError ? (
|
|
<EuiIconTip
|
|
aria-label={i18n.translate('xpack.lens.indexPattern.existenceErrorAriaLabel', {
|
|
defaultMessage: 'Existence fetch failed',
|
|
})}
|
|
type="alert"
|
|
color="warning"
|
|
content={i18n.translate('xpack.lens.indexPattern.existenceErrorLabel', {
|
|
defaultMessage: "Field information can't be loaded",
|
|
})}
|
|
/>
|
|
) : hasLoaded ? (
|
|
<EuiNotificationBadge size="m" color={isFiltered ? 'accent' : 'subdued'}>
|
|
{fieldsCount}
|
|
</EuiNotificationBadge>
|
|
) : (
|
|
<EuiLoadingSpinner size="m" />
|
|
)
|
|
}
|
|
>
|
|
<EuiSpacer size="s" />
|
|
{hasLoaded &&
|
|
(!!fieldsCount ? (
|
|
<ul className="lnsInnerIndexPatternDataPanel__fieldItems">
|
|
{paginatedFields && paginatedFields.map(renderField)}
|
|
</ul>
|
|
) : (
|
|
renderCallout
|
|
))}
|
|
</EuiAccordion>
|
|
);
|
|
};
|
|
|
|
export const FieldsAccordion = memo(InnerFieldsAccordion);
|