Skip to content

Commit

Permalink
[VisBuilder] Update naming of summary field components
Browse files Browse the repository at this point in the history
Signed-off-by: Josh Romero <rmerqg@amazon.com>
  • Loading branch information
joshuarrrr committed Nov 3, 2022
1 parent bf85518 commit ebc16a3
Show file tree
Hide file tree
Showing 10 changed files with 57 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
.vbFieldSelectorField {
.vbFieldButton {
@include euiBottomShadowSmall;

background-color: $euiColorEmptyShade;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { render, screen } from '@testing-library/react';

import { IndexPatternField } from '../../../../../data/public';

import { SelectorFieldButton } from './field_selector_field';
import { DraggableFieldButton } from './field';

describe('visBuilder sidebar field selector field', function () {
describe('SelectorFieldButton', () => {
describe('visBuilder field', function () {
describe('DraggableFieldButton', () => {
it('should render normal fields without a dragValue specified', async () => {
const props = {
field: new IndexPatternField(
Expand All @@ -28,19 +28,19 @@ describe('visBuilder sidebar field selector field', function () {
'bytes'
),
};
render(<SelectorFieldButton {...props} />);
render(<DraggableFieldButton {...props} />);

expect(screen.getByTestId('field-bytes-showDetails')).toBeDefined();
const button = screen.getByTestId('field-bytes-showDetails');

expect(button).toBeDefined();
});

// it('should allow specified dragValue to override the field name');
// TODO: it('should allow specified dragValue to override the field name');

// it('should make dots wrappable');
// TODO: it('should make dots wrappable');

// it('should use a non-scripted FieldIcon by default');
// TODO: it('should use a non-scripted FieldIcon by default');
});

// describe('FieldSelectorField', function () {

// });
// TODO: describe('Field', function () { });
});
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,19 @@ import {
} from '../../../../../opensearch_dashboards_react/public';

import { COUNT_FIELD, useDrag } from '../../utils/drag_drop';
import { VisBuilderFieldDetails } from './field_details';
import { FieldDetailsView } from './field_details';
import { FieldDetails } from './types';
import './field_selector_field.scss';
import './field.scss';

export interface FieldSelectorFieldProps {
export interface FieldProps {
field: IndexPatternField;
filterManager: FilterManager;
indexPattern?: IndexPattern;
getDetails: (field) => FieldDetails;
}

// TODO: Add field sections (Available fields, popular fields from src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx)
export const FieldSelectorField = ({
field,
filterManager,
indexPattern,
getDetails,
}: FieldSelectorFieldProps) => {
export const Field = ({ field, filterManager, indexPattern, getDetails }: FieldProps) => {
const { id: indexPatternId = '', metaFields = [] } = indexPattern ?? {};
const isMetaField = metaFields.includes(field.name);
const [infoIsOpen, setOpen] = useState(false);
Expand All @@ -88,16 +83,16 @@ export const FieldSelectorField = ({
<EuiPopover
ownFocus
display="block"
button={<SelectorFieldButton isActive={infoIsOpen} onClick={togglePopover} field={field} />}
button={<DraggableFieldButton isActive={infoIsOpen} onClick={togglePopover} field={field} />}
isOpen={infoIsOpen}
closePopover={() => setOpen(false)}
anchorPosition="rightUp"
panelClassName="vbItem__fieldPopoverPanel"
repositionOnScroll
data-test-subj="field-selector-field"
data-test-subj="field-popover"
>
{infoIsOpen && (
<VisBuilderFieldDetails
<FieldDetailsView
field={field}
isMetaField={isMetaField}
details={getDetails(field)}
Expand All @@ -108,12 +103,12 @@ export const FieldSelectorField = ({
);
};

export interface SelectorFieldButtonProps extends Partial<FieldButtonProps> {
export interface DraggableFieldButtonProps extends Partial<FieldButtonProps> {
dragValue?: IndexPatternField['name'] | null | typeof COUNT_FIELD;
field: Partial<IndexPatternField> & Pick<IndexPatternField, 'displayName' | 'name' | 'type'>;
}

export const SelectorFieldButton = ({ dragValue, field, ...rest }: SelectorFieldButtonProps) => {
export const DraggableFieldButton = ({ dragValue, field, ...rest }: DraggableFieldButtonProps) => {
const { name, displayName, type, scripted = false } = field;
const [dragProps] = useDrag({
namespace: 'field-data',
Expand All @@ -130,13 +125,13 @@ export const SelectorFieldButton = ({ dragValue, field, ...rest }: SelectorField
const defaultIcon = <FieldIcon type={type} scripted={scripted} size="l" />;

const defaultFieldName = (
<span data-test-subj={`field-${name}`} title={name} className="vbFieldSelectorField__name">
<span data-test-subj={`field-${name}`} title={name} className="vbFieldButton__name">
{wrapOnDot(displayName)}
</span>
);

const defaultProps = {
className: 'vbFieldSelectorField',
className: 'vbFieldButton',
dataTestSubj: `field-${name}-showDetails`,
fieldIcon: defaultIcon,
fieldName: defaultFieldName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,36 @@ import { IndexPatternField } from '../../../../../data/public';
import { Bucket } from './types';
import './field_bucket.scss';

interface Props {
interface FieldBucketProps {
bucket: Bucket;
field: IndexPatternField;
onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
}

export function VisBuilderFieldBucket({ bucket, field, onAddFilter }: Props) {
export function FieldBucket({ bucket, field, onAddFilter }: FieldBucketProps) {
const { count, display, percent, value } = bucket;
const { filterable: isFilterableField, name: fieldName } = field;

const emptyTxt = i18n.translate('visBuilder.fieldChooser.detailViews.emptyStringText', {
const emptyText = i18n.translate('visBuilder.fieldSelector.detailsView.emptyStringText', {
// We need this to communicate to users when a top value is actually an empty string
defaultMessage: 'Empty string',
});
const addLabel = i18n.translate(
'visBuilder.fieldChooser.detailViews.filterValueButtonAriaLabel',
'visBuilder.fieldSelector.detailsView.filterValueButtonAriaLabel',
{
defaultMessage: 'Filter for {fieldName}: "{value}"',
values: { fieldName, value },
}
);
const removeLabel = i18n.translate(
'visBuilder.fieldChooser.detailViews.filterOutValueButtonAriaLabel',
'visBuilder.fieldSelector.detailsView.filterOutValueButtonAriaLabel',
{
defaultMessage: 'Filter out {fieldName}: "{value}"',
values: { fieldName, value },
}
);

const displayValue = display || emptyTxt;
const displayValue = display || emptyText;

return (
<>
Expand All @@ -70,7 +70,13 @@ export function VisBuilderFieldBucket({ bucket, field, onAddFilter }: Props) {
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<StringFieldProgressBar value={value} percent={percent} count={count} />
<EuiProgress
value={percent}
max={100}
color="secondary"
aria-label={`${value}: ${count} (${percent}%)`}
size="s"
/>
</EuiFlexItem>
{/* TODO: Should we have any explanation for non-filterable fields? */}
{isFilterableField && (
Expand Down Expand Up @@ -100,15 +106,3 @@ export function VisBuilderFieldBucket({ bucket, field, onAddFilter }: Props) {
</>
);
}

export function StringFieldProgressBar({
value,
percent,
count,
}: Pick<Bucket, 'count' | 'percent' | 'value'>) {
const ariaLabel = `${value}: ${count} (${percent}%)`;

return (
<EuiProgress value={percent} max={100} color="secondary" aria-label={ariaLabel} size="s" />
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ import { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers';

import { IndexPatternField } from '../../../../../data/public';

import { VisBuilderFieldDetails } from './field_details';
import { FieldDetailsView } from './field_details';

const mockOnAddFilter = jest.fn();

describe('visBuilder sidebar field details', function () {
describe('visBuilder field details', function () {
const defaultProps = {
isMetaField: false,
details: { buckets: [], error: '', exists: 1, total: 1 },
Expand All @@ -51,7 +51,7 @@ describe('visBuilder sidebar field details', function () {

function mountComponent(field: IndexPatternField, props?: Record<string, any>) {
const compProps = { ...defaultProps, ...props, field };
return mountWithIntl(<VisBuilderFieldDetails {...compProps} />);
return mountWithIntl(<FieldDetailsView {...compProps} />);
}

it('should render buckets if they exist', async function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { i18n } from '@osd/i18n';

import { IndexPatternField } from '../../../../../data/public';

import { VisBuilderFieldBucket } from './field_bucket';
import { FieldBucket } from './field_bucket';
import { Bucket, FieldDetails } from './types';

interface FieldDetailsProps {
Expand All @@ -19,31 +19,26 @@ interface FieldDetailsProps {
onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
}

export function VisBuilderFieldDetails({
field,
isMetaField,
details,
onAddFilter,
}: FieldDetailsProps) {
export function FieldDetailsView({ field, isMetaField, details, onAddFilter }: FieldDetailsProps) {
const { buckets, error, exists, total } = details;

const bucketsTitle =
buckets.length > 1
? i18n.translate('visBuilder.fieldChooser.detailViews.fieldTopValuesLabel', {
? i18n.translate('visBuilder.fieldSelector.detailsView.fieldTopValuesLabel', {
defaultMessage: 'Top {n} values',
values: { n: buckets.length },
})
: i18n.translate('visBuilder.fieldChooser.detailViews.fieldTopValueLabel', {
: i18n.translate('visBuilder.fieldSelector.detailsView.fieldTopValueLabel', {
defaultMessage: 'Top value',
});
const errorTitle = i18n.translate('visBuilder.fieldChooser.detailViews.fieldNoValuesLabel', {
const errorTitle = i18n.translate('visBuilder.fieldSelector.detailsView.fieldNoValuesLabel', {
defaultMessage: 'No values found',
});
const existsIn = i18n.translate('visBuilder.fieldChooser.detailViews.fieldExistsIn', {
const existsIn = i18n.translate('visBuilder.fieldSelector.detailsView.fieldExistsIn', {
defaultMessage: 'Exists in {exists}',
values: { exists },
});
const totalRecords = i18n.translate('visBuilder.fieldChooser.detailViews.fieldTotalRecords', {
const totalRecords = i18n.translate('visBuilder.fieldSelector.detailsView.fieldTotalRecords', {
defaultMessage: '/ {total} records',
values: { total },
});
Expand All @@ -66,7 +61,7 @@ export function VisBuilderFieldDetails({
data-test-subj="fieldDetailsBucketsContainer"
>
{buckets.map((bucket: Bucket, idx: number) => (
<VisBuilderFieldBucket
<FieldBucket
key={`bucket${idx}`}
bucket={bucket}
field={field}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ describe('visBuilder sidebar field selector', function () {

expect(container).toHaveTextContent(defaultProps.header);
expect(container).toHaveTextContent('0');
expect(screen.queryAllByTestId('field-selector-field').length).toBeFalsy();
expect(screen.queryAllByTestId('field-popover').length).toBeFalsy();

await fireEvent.click(screen.getByText(defaultProps.header));

expect(mockGetDetails).not.toHaveBeenCalled();
});

it('renders an accordion with FieldSelectorFields if fields provided', async () => {
it('renders an accordion with Fields if fields provided', async () => {
const props = {
...defaultProps,
fields: ['bytes', 'machine.ram', 'memory', 'phpmemory'].map(getFields),
Expand All @@ -65,7 +65,7 @@ describe('visBuilder sidebar field selector', function () {

expect(container).toHaveTextContent(props.header);
expect(container).toHaveTextContent(props.fields.length.toString());
expect(screen.queryAllByTestId('field-selector-field').length).toBe(props.fields.length);
expect(screen.queryAllByTestId('field-popover').length).toBe(props.fields.length);

await fireEvent.click(screen.getByText('memory'));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { COUNT_FIELD } from '../../utils/drag_drop';
import { useTypedSelector } from '../../utils/state_management';
import { useIndexPatterns } from '../../utils/use';
import { FieldSearch } from './field_search';
import { FieldSelectorField, SelectorFieldButton } from './field_selector_field';
import { Field, DraggableFieldButton } from './field';
import { FieldDetails } from './types';
import { getAvailableFields, getDetails } from './utils';
import './field_selector.scss';
Expand Down Expand Up @@ -159,7 +159,7 @@ export const FieldSelector = () => {
</div>
<div className="vbFieldSelector__fieldGroups">
{/* Count Field */}
<SelectorFieldButton
<DraggableFieldButton
field={{ name: 'count', displayName: 'Count', type: 'number' }}
dragValue={COUNT_FIELD}
/>
Expand Down Expand Up @@ -214,7 +214,7 @@ export const FieldGroup = ({ fields, header, id, ...rest }: FieldGroupProps) =>
>
{fields?.map((field, i) => (
<EuiFlexItem key={i}>
<FieldSelectorField field={field} {...rest} />
<Field field={field} {...rest} />
</EuiFlexItem>
))}
</EuiAccordion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { FieldDetails } from '../types';

import { getFieldValueCounts } from './field_calculator';

export function getDetails(
export function getFieldDetails(
field: IndexPatternField,
hits: Array<Record<string, unknown>>,
indexPattern?: IndexPattern
Expand All @@ -24,15 +24,15 @@ export function getDetails(
if (!indexPattern) {
return {
...defaultDetails,
error: i18n.translate('visBuilder.fieldChooser.noIndexPatternSelectedErrorMessage', {
error: i18n.translate('visBuilder.fieldSelector.noIndexPatternSelectedErrorMessage', {
defaultMessage: 'Index pattern not specified.',
}),
};
}
if (!hits.length) {
return {
...defaultDetails,
error: i18n.translate('visBuilder.fieldChooser.noHits', {
error: i18n.translate('visBuilder.fieldSelector.noHits', {
defaultMessage:
'No documents match the selected query and filters. Try increasing time range or removing filters.',
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
*/

export { getAvailableFields } from './get_available_fields';
export { getDetails } from './get_details';
export { getFieldDetails as getDetails } from './get_field_details';

0 comments on commit ebc16a3

Please sign in to comment.