Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] use reusable component for drag and drop #1

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ export const FilterList = ({
removeTitle={i18n.translate('xpack.lens.indexPattern.filters.removeCustomQuery', {
defaultMessage: 'Remove custom query',
})}
isNotRemovable={localFilters.length === 1}
>
<FilterPopover
data-test-subj="indexPattern-filters-existingFilterContainer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { keys } from '@elastic/eui';
import { IFieldFormat } from '../../../../../../../../src/plugins/data/common';
import { RangeTypeLens, isValidRange, isValidNumber } from './ranges';
import { FROM_PLACEHOLDER, TO_PLACEHOLDER, TYPING_DEBOUNCE_TIME } from './constants';
import { NewBucketButton, DragDropBuckets, DraggableBucketContainer } from '../shared_components';

const generateId = htmlIdGenerator();

Expand Down Expand Up @@ -219,19 +220,6 @@ export const AdvancedRangeEditor = ({
]);
};

const onDragEnd = ({
source,
destination,
}: {
source?: DraggableLocation;
destination?: DraggableLocation;
}) => {
if (source && destination) {
const items = euiDragDropReorder(localRanges, source.index, destination.index);
setLocalRanges(items);
}
};

return (
<EuiFormRow
label={i18n.translate('xpack.lens.indexPattern.ranges.intervals', {
Expand All @@ -249,110 +237,73 @@ export const AdvancedRangeEditor = ({
}
>
<>
<EuiDragDropContext onDragEnd={onDragEnd}>
<EuiDroppable
droppableId="RANGES_DROPPABLE_AREA"
spacing="s"
data-test-subj="indexPattern-ranges-container"
>
{localRanges.map((range: LocalRangeType, idx: number) => {
return (
<EuiDraggable
spacing="m"
key={range.id}
index={idx}
draggableId={range.id}
disableInteractiveElementBlocking
>
{() => {
return (
<EuiPanel paddingSize="s">
<EuiFlexGroup gutterSize="xs" alignItems="center" responsive={false}>
<EuiFlexItem grow={false}>
<div className="lnsLayerPanel_dndGrab">
<EuiIcon
type="grab"
aria-label={i18n.translate(
'xpack.lens.indexPattern.ranges.grabIcon',
{
defaultMessage: 'Grab Icon',
}
)}
/>
</div>
</EuiFlexItem>
<EuiFlexItem grow>
<RangePopover
range={range}
isOpenByCreation={idx === lastIndex && isOpenByCreation}
setIsOpenByCreation={setIsOpenByCreation}
setRange={(newRange: LocalRangeType) => {
const newRanges = [...localRanges];
if (newRange.id === newRanges[idx].id) {
newRanges[idx] = newRange;
} else {
newRanges.push(newRange);
}
setLocalRanges(newRanges);
}}
formatter={formatter}
Button={({ onClick }: { onClick: MouseEventHandler }) => (
<EuiLink
color="text"
onClick={onClick}
className="lnsRangesOperation__popoverButton"
data-test-subj="indexPattern-ranges-popover-trigger"
>
<EuiText
size="s"
textAlign="left"
color={isValidRange(range) ? 'default' : 'danger'}
>
{getBetterLabel(range, formatter)}
</EuiText>
</EuiLink>
)}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonIcon
size="m"
iconType="cross"
color="danger"
onClick={() => {
const newRanges = localRanges.filter((_, i) => i !== idx);
setLocalRanges(newRanges);
}}
disabled={localRanges.length === 1}
aria-label={i18n.translate(
'xpack.lens.indexPattern.ranges.deleteRange',
{
defaultMessage: 'Delete range',
}
)}
/>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
);
}}
</EuiDraggable>
);
})}
</EuiDroppable>
</EuiDragDropContext>
<EuiButtonEmpty
size="xs"
iconType="plusInCircle"
<DragDropBuckets
onDragEnd={setLocalRanges}
onDragStart={() => setIsOpenByCreation(false)}
droppableId="RANGES_DROPPABLE_AREA"
items={localRanges}
>
{localRanges.map((range: LocalRangeType, idx: number) => (
<DraggableBucketContainer
key={range.id}
idx={idx}
id={range.id}
isInvalid={!isValidRange(range)}
invalidMessage={i18n.translate('xpack.lens.indexPattern.range.isInvalid', {
defaultMessage: 'This range is invalid',
})}
onRemoveClick={() => {
const newRanges = localRanges.filter((_, i) => i !== idx);
setLocalRanges(newRanges);
}}
removeTitle={i18n.translate('xpack.lens.indexPattern.ranges.deleteRange', {
defaultMessage: 'Delete range',
})}
isNotRemovable={localRanges.length === 1}
>
<RangePopover
range={range}
isOpenByCreation={idx === lastIndex && isOpenByCreation}
setIsOpenByCreation={setIsOpenByCreation}
setRange={(newRange: LocalRangeType) => {
const newRanges = [...localRanges];
if (newRange.id === newRanges[idx].id) {
newRanges[idx] = newRange;
} else {
newRanges.push(newRange);
}
setLocalRanges(newRanges);
}}
formatter={formatter}
Button={({ onClick }: { onClick: MouseEventHandler }) => (
<EuiLink
color="text"
onClick={onClick}
className="lnsRangesOperation__popoverButton"
data-test-subj="indexPattern-ranges-popover-trigger"
>
<EuiText
size="s"
textAlign="left"
color={isValidRange(range) ? 'default' : 'danger'}
>
{getBetterLabel(range, formatter)}
</EuiText>
</EuiLink>
)}
/>
</DraggableBucketContainer>
))}
</DragDropBuckets>
<NewBucketButton
onClick={() => {
addNewRange();
setIsOpenByCreation(true);
}}
>
{i18n.translate('xpack.lens.indexPattern.ranges.addInterval', {
label={i18n.translate('xpack.lens.indexPattern.ranges.addInterval', {
defaultMessage: 'Add interval',
})}
</EuiButtonEmpty>
/>
</>
</EuiFormRow>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { autoInterval } from 'src/plugins/data/common';
import { MODES, DEFAULT_INTERVAL, TYPING_DEBOUNCE_TIME } from './constants';
import { RangePopover } from './advanced_editor';
import { EuiButtonIcon } from '@elastic/eui';
import { DragDropBuckets } from '../shared_components';

const dataPluginMockValue = dataPluginMock.createStartContract();
// need to overwrite the formatter field first
Expand Down Expand Up @@ -399,9 +400,7 @@ describe('ranges', () => {
/>
);

expect(
instance.find('[data-test-subj="indexPattern-ranges-container"]').children
).toHaveLength(1);
expect(instance.find(DragDropBuckets).children).toHaveLength(1);
});

it('should add a new range', () => {
Expand Down Expand Up @@ -577,11 +576,10 @@ describe('ranges', () => {

expect(instance.find(RangePopover)).toHaveLength(2);

// This series of act clojures are made to make it work properly the update flush
// This series of act closures are made to make it work properly the update flush
act(() => {
instance
.find('[data-test-subj="indexPattern-ranges-container"]')
.find(EuiButtonIcon)
.find('[data-test-subj="lns-customBucketContainer-remove"]')
.last()
.prop('onClick')!({} as ReactMouseEvent);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface BucketContainerProps {
invalidMessage: string;
onRemoveClick: () => void;
removeTitle: string;
isNotRemovable: boolean;
children: React.ReactNode;
dataTestSubj?: string;
}
Expand All @@ -41,6 +42,7 @@ const BucketContainer = ({
removeTitle,
children,
dataTestSubj,
isNotRemovable,
}: BucketContainerProps) => {
return (
<EuiPanel paddingSize="none" data-test-subj={dataTestSubj}>
Expand Down Expand Up @@ -70,6 +72,7 @@ const BucketContainer = ({
onClick={onRemoveClick}
aria-label={removeTitle}
title={removeTitle}
disabled={isNotRemovable}
/>
</EuiFlexItem>
</EuiFlexGroup>
Expand Down