Skip to content

Commit

Permalink
Add Drag Across Axis Functionality to Vis Builder
Browse files Browse the repository at this point in the history
Signed-off-by: Suchit Sahoo <suchsah@amazon.com>
  • Loading branch information
LDrago27 committed Jun 25, 2024
1 parent e74ed2c commit 6e1483e
Show file tree
Hide file tree
Showing 11 changed files with 567 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,15 @@

import { EuiForm } from '@elastic/eui';
import React from 'react';
import { useVisualizationType } from '../../utils/use';
import { useTypedSelector } from '../../utils/state_management';

import './config_panel.scss';
import { mapSchemaToAggPanel } from './schema_to_dropbox';
import { SecondaryPanel } from './secondary_panel';

export function ConfigPanel() {
const vizType = useVisualizationType();
const editingState = useTypedSelector(
(state) => state.visualization.activeVisualization?.draftAgg
);
const schemas = vizType.ui.containerConfig.data.schemas;

export function ConfigPanel({ schemas, editingState, aggProps, configStates }) {
if (!schemas) return null;

const mainPanel = mapSchemaToAggPanel(schemas);
const mainPanel = mapSchemaToAggPanel(schemas, aggProps, configStates);

Check warning on line 16 in src/plugins/vis_builder/public/application/components/data_tab/config_panel.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/vis_builder/public/application/components/data_tab/config_panel.tsx#L16

Added line #L16 was not covered by tests

return (
<EuiForm className={`vbConfig ${editingState ? 'showSecondary' : ''}`}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
border-bottom: none;
}

&__droppable {
min-height: 1px;
}

&__container {
display: grid;
grid-gap: calc($euiSizeXS / 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
DropResult,
} from '@elastic/eui';
import React, { useCallback, useState } from 'react';
import { IDropAttributes, IDropState } from '../../utils/drag_drop';
import { IDropAttributes, IDropState, useDrag } from '../../utils/drag_drop';
import './dropbox.scss';
import { useDropbox } from './use';
import { UseDropboxProps } from './use/use_dropbox';
Expand Down Expand Up @@ -59,17 +59,6 @@ const DropboxComponent = ({
}: DropboxProps) => {
const prefersReducedMotion = usePrefersReducedMotion();
const [closing, setClosing] = useState<boolean | string>(false);
const handleDragEnd = useCallback(
({ source, destination }: DropResult) => {
if (!destination) return;

onReorderField({
sourceAggId: fields[source.index].id,
destinationAggId: fields[destination.index].id,
});
},
[fields, onReorderField]
);

const animateDelete = useCallback(
(id: string) => {
Expand All @@ -86,71 +75,72 @@ const DropboxComponent = ({
);

return (
<EuiDragDropContext onDragEnd={handleDragEnd}>
<EuiFormRow label={boxLabel} className="dropBox" fullWidth>
<div className="dropBox__container">
<EuiDroppable droppableId={dropboxId}>
{fields.map(({ id, label }, index) => (
<EuiDraggable
className={`dropBox__draggable ${id === closing && 'closing'}`}
key={id}
draggableId={id}
index={index}
>
<EuiPanel
key={index}
paddingSize="s"
className="dropBox__field"
data-test-subj={`dropBoxField-${dropboxId}-${index}`}
>
<EuiText size="s" className="dropBox__field_text" onClick={() => onEditField(id)}>
<a role="button" tabIndex={0}>
{label}
</a>
</EuiText>
<EuiButtonIcon
color="subdued"
iconType="cross"
aria-label="clear-field"
iconSize="s"
onClick={() => animateDelete(id)}
data-test-subj="dropBoxRemoveBtn"
/>
</EuiPanel>
</EuiDraggable>
))}
</EuiDroppable>
{fields.length < limit && (
<EuiPanel
data-test-subj={`dropBoxAddField-${dropboxId}`}
className={`dropBox__field dropBox__dropTarget ${
isValidDropTarget ? 'validField' : ''
} ${canDrop ? 'canDrop' : ''}`}
{...(isValidDropTarget && dropProps)}
<EuiFormRow label={boxLabel} className="dropBox" fullWidth>
<div className="dropBox__container">
<EuiDroppable
className="dropBox__droppable"
droppableId={dropboxId}
isCombineEnabled={true}
>
{fields.map(({ id, label }, index) => (
<EuiDraggable

Check warning on line 86 in src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx#L86

Added line #L86 was not covered by tests
className={`dropBox__draggable ${id === closing && 'closing'}`}
key={id}
draggableId={id}
index={index}
>
<EuiText size="s">
{i18n.translate('visBuilder.dropbox.addField.title', {
defaultMessage: 'Click or drop to add',
})}
</EuiText>
<EuiButtonIcon
iconType="plusInCircle"
aria-label="clear-field"
iconSize="s"
onClick={() => onAddField()}
data-test-subj="dropBoxAddBtn"
/>
</EuiPanel>
)}
</div>
</EuiFormRow>
</EuiDragDropContext>
<EuiPanel
key={index}
paddingSize="s"
className="dropBox__field"
data-test-subj={`dropBoxField-${dropboxId}-${index}`}
>
<EuiText size="s" className="dropBox__field_text" onClick={() => onEditField(id)}>

Check warning on line 98 in src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx#L98

Added line #L98 was not covered by tests
<a role="button" tabIndex={0}>
{label}
</a>
</EuiText>
<EuiButtonIcon
color="subdued"
iconType="cross"
aria-label="clear-field"
iconSize="s"
onClick={() => animateDelete(id)}

Check warning on line 108 in src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx#L108

Added line #L108 was not covered by tests
data-test-subj="dropBoxRemoveBtn"
/>
</EuiPanel>
</EuiDraggable>
))}
</EuiDroppable>
{fields.length < limit && (
<EuiPanel
data-test-subj={`dropBoxAddField-${dropboxId}`}
className={`dropBox__field dropBox__dropTarget ${
isValidDropTarget ? 'validField' : ''
} ${canDrop ? 'canDrop' : ''}`}
{...(isValidDropTarget && dropProps)}
>
<EuiText size="s">
{i18n.translate('visBuilder.dropbox.addField.title', {
defaultMessage: 'Click or drop to add',
})}
</EuiText>
<EuiButtonIcon
iconType="plusInCircle"
aria-label="clear-field"
iconSize="s"
onClick={() => onAddField()}

Check warning on line 132 in src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx

View check run for this annotation

Codecov / codecov/patch

src/plugins/vis_builder/public/application/components/data_tab/dropbox.tsx#L132

Added line #L132 was not covered by tests
data-test-subj="dropBoxAddBtn"
/>
</EuiPanel>
)}
</div>
</EuiFormRow>
);
};

const Dropbox = React.memo((dropBox: UseDropboxProps) => {
const props = useDropbox(dropBox);

return <DropboxComponent {...props} />;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
*/

import React, { useState } from 'react';
import { EuiPopover } from '@elastic/eui';
import { EuiDraggable, EuiPopover } from '@elastic/eui';

import { IndexPatternField } from '../../../../../data/public';
import {
Expand All @@ -46,10 +46,11 @@ import './field.scss';
export interface FieldProps {
field: IndexPatternField;
getDetails: (field) => FieldDetails;
id: number;
}

// TODO: Add field sections (Available fields, popular fields from src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx)
export const Field = ({ field, getDetails }: FieldProps) => {
export const Field = ({ field, getDetails, id }: FieldProps) => {
const [infoIsOpen, setOpen] = useState(false);

function togglePopover() {
Expand All @@ -60,7 +61,14 @@ export const Field = ({ field, getDetails }: FieldProps) => {
<EuiPopover
ownFocus
display="block"
button={<DraggableFieldButton isActive={infoIsOpen} onClick={togglePopover} field={field} />}
button={
<DraggableFieldButton
isActive={infoIsOpen}
onClick={togglePopover}
field={field}
index={id}
/>
}
isOpen={infoIsOpen}
closePopover={() => setOpen(false)}
anchorPosition="rightUp"
Expand All @@ -77,9 +85,15 @@ export const Field = ({ field, getDetails }: FieldProps) => {
export interface DraggableFieldButtonProps extends Partial<FieldButtonProps> {
dragValue?: IndexPatternField['name'] | null | typeof COUNT_FIELD;
field: Partial<IndexPatternField> & Pick<IndexPatternField, 'displayName' | 'name' | 'type'>;
index: number;
}

export const DraggableFieldButton = ({ dragValue, field, ...rest }: DraggableFieldButtonProps) => {
export const DraggableFieldButton = ({
dragValue,
field,
index,
...rest
}: DraggableFieldButtonProps) => {
const { name, displayName, type, scripted = false } = field;
const [dragProps] = useDrag({
namespace: 'field-data',
Expand Down Expand Up @@ -109,5 +123,14 @@ export const DraggableFieldButton = ({ dragValue, field, ...rest }: DraggableFie
onClick: () => {},
};

return <FieldButton {...defaultProps} {...rest} {...dragProps} />;
return (
<EuiDraggable
draggableId={name}
index={index}
disableInteractiveElementBlocking={true}
shouldRespectForcePress
>
<FieldButton {...defaultProps} {...rest} {...dragProps} />
</EuiDraggable>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
padding: $euiSizeS;

&__fieldGroups {
@include euiYScrollWithShadows;

overflow-y: auto;
margin-right: -$euiSizeS;
Expand Down
Loading

0 comments on commit 6e1483e

Please sign in to comment.