Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import React, { useEffect, useRef, FC } from 'react';
import d3 from 'd3';

import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui';
import { EuiText } from '@elastic/eui';

const COLOR_RANGE_RESOLUTION = 10;

Expand Down Expand Up @@ -134,15 +134,11 @@ export const ColorRangeLegend: FC<ColorRangeLegendProps> = ({
}

return (
<EuiFlexGroup gutterSize="s">
<EuiFlexItem grow={false}>
<EuiText size="xs">
<strong>{title}</strong>
</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<svg ref={d3Container} />
</EuiFlexItem>
</EuiFlexGroup>
<>
<EuiText size="xs" color="subdued">
<p>{title}</p>
</EuiText>
<svg ref={d3Container} />
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export const EXTENDED_NUMERICAL_TYPES = new Set([

// eslint-disable-next-line @typescript-eslint/naming-convention
export const ML__ID_COPY = 'ml__id_copy';
// eslint-disable-next-line @typescript-eslint/naming-convention
export const ML__INCREMENTAL_ID = 'ml__incremental_id';

export const isKeywordAndTextType = (fieldName: string): boolean => {
const { fields } = newJobCapsService;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.mlExpandableSection {
padding: 0 $euiSizeS $euiSizeS $euiSizeS;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* 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 './expandable_section.scss';

import React, { useState, FC, ReactNode } from 'react';

import {
EuiBadge,
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiLoadingContent,
EuiPanel,
EuiText,
} from '@elastic/eui';

interface HeaderItem {
// id is used as the React key and to construct a data-test-subj
id: string;
label?: ReactNode;
value: ReactNode;
}

const isHeaderItems = (arg: any): arg is HeaderItem[] => {
return Array.isArray(arg);
};

export interface ExpandableSectionProps {
content: ReactNode;
headerItems?: HeaderItem[] | 'loading';
isExpanded?: boolean;
dataTestId: string;
title: ReactNode;
}

export const ExpandableSection: FC<ExpandableSectionProps> = ({
headerItems,
// For now we don't have a need for complete external control
// and just want to pass in a default value. If we wanted
// full external control we'd also need to add a onToggleExpanded()
// callback.
isExpanded: isExpandedDefault = true,
content,
dataTestId,
title,
}) => {
const [isExpanded, setIsExpanded] = useState(isExpandedDefault);
const toggleExpanded = () => {
setIsExpanded(!isExpanded);
};

return (
<EuiPanel paddingSize="none" data-test-subj={`mlDFExpandableSection-${dataTestId}`}>
<div className="mlExpandableSection">
<EuiButtonEmpty
onClick={toggleExpanded}
iconType={isExpanded ? 'arrowUp' : 'arrowDown'}
size="l"
iconSide="right"
flush="left"
>
{title}
</EuiButtonEmpty>
{headerItems === 'loading' && <EuiLoadingContent lines={1} />}
{isHeaderItems(headerItems) && (
<EuiFlexGroup>
{headerItems.map(({ label, value, id }) => (
<EuiFlexItem
grow={false}
key={id}
data-test-subj={`mlDFExpandableSectionItem-${dataTestId}-${id}`}
>
{label !== undefined && value !== undefined && (
<>
<EuiText size="xs" color="subdued">
<p>{label}</p>
</EuiText>
<EuiBadge>{value}</EuiBadge>
</>
)}
{label === undefined && value}
</EuiFlexItem>
))}
</EuiFlexGroup>
)}
</div>
{isExpanded && content}
</EuiPanel>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export { ExpandableSection, ExpandableSectionProps } from './expandable_section';
Loading