Migrate drag and drop logic from Lens plugin to its own package (#151836)

Closes https://github.com/elastic/kibana/issues/151702

## Summary

This PR migrates drag and drop logic from Lens plugin to a new package
so we can reuse it on Discover page later. At this point there should be
no visual changes. If you notice something, please comment on the PR.

- [x] Migrate drag&drop code to its own package `@kbn/dom-drag-drop`
- [x] Clean up i18n strings
- [x] Clean up styles
- [x] Adjust tests 
- [x] Make telemetry optional  
- [x] Configurable `data-test-subj`

Please test by using your mouse and also by using keyword shortcuts.

# Next steps

- Redesign for field list item (smaller button, a separate handle icon,
pill styles)
- Redesign for draggable buttons in the Lens layer panels (smaller
buttons)
-
[Figma](https://www.figma.com/file/SvpfCqaZPb2iAYnPtd0Gnr/KUI-Library?node-id=674%3A198901&t=OnQH2EQ4fdBjsRLp-0)
- https://github.com/elastic/kibana/issues/151703

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Stratoula Kalafateli <efstratia.kalafateli@elastic.co>
This commit is contained in:
Julia Rechkunova 2023-03-23 11:09:17 +01:00 committed by GitHub
parent 04c4c0632b
commit ecd2b914f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 934 additions and 771 deletions

1
.github/CODEOWNERS vendored
View file

@ -312,6 +312,7 @@ x-pack/plugins/discover_enhanced @elastic/kibana-data-discovery
src/plugins/discover @elastic/kibana-data-discovery
packages/kbn-doc-links @elastic/kibana-docs
packages/kbn-docs-utils @elastic/kibana-operations
packages/kbn-dom-drag-drop @elastic/kibana-visualizations @elastic/kibana-data-discovery
packages/kbn-ebt-tools @elastic/kibana-core
packages/kbn-ecs @elastic/kibana-core @elastic/security-threat-hunting-investigations
x-pack/packages/kbn-ecs-data-quality-dashboard @elastic/security-threat-hunting-investigations

View file

@ -14,6 +14,7 @@
"core": ["src/core", "packages/core"],
"customIntegrations": "src/plugins/custom_integrations",
"dashboard": "src/plugins/dashboard",
"domDragDrop": "packages/kbn-dom-drag-drop",
"controls": "src/plugins/controls",
"data": "src/plugins/data",
"ecsDataQualityDashboard": "x-pack/packages/kbn-ecs-data-quality-dashboard",

View file

@ -351,6 +351,7 @@
"@kbn/discover-enhanced-plugin": "link:x-pack/plugins/discover_enhanced",
"@kbn/discover-plugin": "link:src/plugins/discover",
"@kbn/doc-links": "link:packages/kbn-doc-links",
"@kbn/dom-drag-drop": "link:packages/kbn-dom-drag-drop",
"@kbn/ebt-tools": "link:packages/kbn-ebt-tools",
"@kbn/ecs": "link:packages/kbn-ecs",
"@kbn/ecs-data-quality-dashboard": "link:x-pack/packages/kbn-ecs-data-quality-dashboard",

View file

@ -1,4 +1,4 @@
# Drag / Drop
# DOM Drag & Drop
This is a simple drag / drop mechanism that plays nice with React.
@ -9,7 +9,7 @@ We aren't using EUI or another library, due to the fact that Lens visualizations
First, place a RootDragDropProvider at the root of your application.
```js
<RootDragDropProvider>
<RootDragDropProvider onTrackUICounterEvent={...}>
... your app here ...
</RootDragDropProvider>
```

View file

@ -0,0 +1,21 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export {
type DragDropIdentifier,
type DragContextState,
type DropType,
type DraggingIdentifier,
DragDrop,
DragContext,
RootDragDropProvider,
ChildDragDropProvider,
ReorderProvider,
} from './src';
export { DropTargetSwapDuplicateCombine } from './src/drop_targets';

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-dom-drag-drop'],
};

View file

@ -0,0 +1,8 @@
{
"type": "shared-browser",
"id": "@kbn/dom-drag-drop",
"owner": [
"@elastic/kibana-visualizations",
"@elastic/kibana-data-discovery"
]
}

View file

@ -0,0 +1,6 @@
{
"name": "@kbn/dom-drag-drop",
"private": true,
"version": "1.0.0",
"license": "SSPL-1.0 OR Elastic License 2.0"
}

View file

@ -2,12 +2,12 @@
exports[`DragDrop defined dropTypes is reflected in the className 1`] = `
<div
class="lnsDragDrop__container"
data-test-subj="lnsDragDropContainer"
class="domDragDrop__container"
data-test-subj="domDragDropContainer"
>
<button
class="lnsDragDrop lnsDragDrop-isDroppable lnsDragDrop-isDropTarget"
data-test-subj="lnsDragDrop"
class="domDragDrop domDragDrop-isDroppable domDragDrop-isDropTarget"
data-test-subj="domDragDrop"
>
Hello!
</button>
@ -16,16 +16,16 @@ exports[`DragDrop defined dropTypes is reflected in the className 1`] = `
exports[`DragDrop items that has dropTypes=undefined get special styling when another item is dragged 1`] = `
<SingleDropInner
className="lnsDragDrop lnsDragDrop-isDroppable lnsDragDrop-isNotDroppable"
data-test-subj="lnsDragDrop"
className="domDragDrop domDragDrop-isDroppable domDragDrop-isNotDroppable"
data-test-subj="testDragDrop"
onDragEnter={[Function]}
onDragLeave={[Function]}
onDragOver={[Function]}
onDrop={[Function]}
>
<button
className="lnsDragDrop lnsDragDrop-isDroppable lnsDragDrop-isNotDroppable"
data-test-subj="lnsDragDrop"
className="domDragDrop domDragDrop-isDroppable domDragDrop-isNotDroppable"
data-test-subj="testDragDrop"
onDragEnter={[Function]}
onDragLeave={[Function]}
onDragOver={[Function]}
@ -39,17 +39,17 @@ exports[`DragDrop items that has dropTypes=undefined get special styling when an
exports[`DragDrop renders if nothing is being dragged 1`] = `
<div
class=""
data-test-subj="lnsDragDrop_draggable-hello"
data-test-subj="domDragDrop_draggable-hello"
>
<button
aria-describedby="lnsDragDrop-keyboardInstructions"
aria-describedby="domDragDrop-keyboardInstructions"
aria-label="hello"
class="lnsDragDrop__keyboardHandler emotion-euiScreenReaderOnly"
data-test-subj="lnsDragDrop-keyboardHandler"
class="domDragDrop__keyboardHandler emotion-euiScreenReaderOnly"
data-test-subj="domDragDrop-keyboardHandler"
/>
<button
class="lnsDragDrop lnsDragDrop-isDraggable"
data-test-subj="lnsDragDrop"
class="domDragDrop domDragDrop-isDraggable"
data-test-subj="domDragDrop"
draggable="true"
>
Hello!

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export const DEFAULT_DATA_TEST_SUBJ = 'domDragDrop';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
@ -17,7 +18,7 @@ import {
DropIdentifier,
} from './providers';
import { act } from 'react-dom/test-utils';
import { DropType } from '../types';
import { DropType } from './types';
jest.useFakeTimers({ legacyFakeTimers: true });
@ -28,6 +29,7 @@ const dataTransfer = {
describe('DragDrop', () => {
const defaultContext = {
dataTestSubjPrefix: 'testDragDrop',
dragging: undefined,
setDragging: jest.fn(),
setActiveDropTarget: jest.fn(),
@ -69,7 +71,7 @@ describe('DragDrop', () => {
</DragDrop>
);
component.find('[data-test-subj="lnsDragDrop"]').at(0).simulate('dragover', { preventDefault });
component.find('[data-test-subj="domDragDrop"]').at(0).simulate('dragover', { preventDefault });
expect(preventDefault).toBeCalled();
});
@ -82,7 +84,7 @@ describe('DragDrop', () => {
</DragDrop>
);
component.find('[data-test-subj="lnsDragDrop"]').at(0).simulate('dragover', { preventDefault });
component.find('[data-test-subj="domDragDrop"]').at(0).simulate('dragover', { preventDefault });
expect(preventDefault).not.toBeCalled();
});
@ -96,7 +98,7 @@ describe('DragDrop', () => {
</DragDrop>
);
component.find('[data-test-subj="lnsDragDrop"]').at(0).simulate('mousedown');
component.find('[data-test-subj="domDragDrop"]').at(0).simulate('mousedown');
expect(global.getSelection).toBeCalled();
expect(removeAllRanges).toBeCalled();
});
@ -118,7 +120,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
component.find('[data-test-subj="lnsDragDrop"]').at(0).simulate('dragstart', { dataTransfer });
component.find('[data-test-subj="testDragDrop"]').at(0).simulate('dragstart', { dataTransfer });
act(() => {
jest.runAllTimers();
@ -147,7 +149,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
const dragDrop = component.find('[data-test-subj="lnsDragDrop"]').at(0);
const dragDrop = component.find('[data-test-subj="testDragDrop"]').at(0);
dragDrop.simulate('dragOver');
dragDrop.simulate('drop', { preventDefault, stopPropagation });
@ -175,7 +177,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
const dragDrop = component.find('[data-test-subj="lnsDragDrop"]').at(0);
const dragDrop = component.find('[data-test-subj="testDragDrop"]').at(0);
dragDrop.simulate('dragover');
dragDrop.simulate('drop', { preventDefault, stopPropagation });
@ -219,7 +221,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
expect(component.find('[data-test-subj="lnsDragDrop"]').at(1)).toMatchSnapshot();
expect(component.find('[data-test-subj="testDragDrop"]').at(1)).toMatchSnapshot();
});
test('additional styles are reflected in the className until drop', () => {
@ -258,7 +260,7 @@ describe('DragDrop', () => {
);
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
act(() => {
@ -266,7 +268,7 @@ describe('DragDrop', () => {
});
expect(setA11yMessage).toBeCalledWith('Lifted ignored');
const dragDrop = component.find('[data-test-subj="lnsDragDrop"]').at(1);
const dragDrop = component.find('[data-test-subj="testDragDrop"]').at(1);
dragDrop.simulate('dragOver');
dragDrop.simulate('drop');
expect(component.find('.additional')).toHaveLength(0);
@ -280,6 +282,7 @@ describe('DragDrop', () => {
const component = mount(
<ChildDragDropProvider
dataTestSubjPrefix={defaultContext.dataTestSubjPrefix}
setA11yMessage={jest.fn()}
dragging={dragging}
setDragging={() => {
@ -313,16 +316,16 @@ describe('DragDrop', () => {
);
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
act(() => {
jest.runAllTimers();
});
component.find('[data-test-subj="lnsDragDrop"]').at(1).simulate('dragover');
component.find('[data-test-subj="testDragDrop"]').at(1).simulate('dragover');
expect(component.find('.additional')).toHaveLength(2);
component.find('[data-test-subj="lnsDragDrop"]').at(1).simulate('dragleave');
component.find('[data-test-subj="testDragDrop"]').at(1).simulate('dragleave');
expect(setActiveDropTarget).toBeCalledWith(undefined);
});
@ -411,7 +414,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('focus');
@ -451,7 +454,7 @@ describe('DragDrop', () => {
);
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('focus');
@ -523,7 +526,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
expect(component.find(DragDrop).at(1).find('.lnsDragDrop_ghost').text()).toEqual('Hello');
expect(component.find(DragDrop).at(1).find('.domDragDrop_ghost').text()).toEqual('Hello');
});
});
@ -540,6 +543,7 @@ describe('DragDrop', () => {
});
component = mount(
<ChildDragDropProvider
dataTestSubjPrefix={defaultContext.dataTestSubjPrefix}
setA11yMessage={jest.fn()}
dragging={{ id: '1', humanData: { label: 'Label1', layerNumber: 0 } }}
setDragging={jest.fn()}
@ -574,18 +578,18 @@ describe('DragDrop', () => {
});
test('extra drop targets appear when dragging over and disappear when activeDropTarget changes', () => {
component.find('[data-test-subj="lnsDragDropContainer"]').first().simulate('dragenter');
component.find('[data-test-subj="testDragDropContainer"]').first().simulate('dragenter');
// customDropTargets are visible
expect(component.find('[data-test-subj="lnsDragDropContainer"]').prop('className')).toEqual(
'lnsDragDrop__container lnsDragDrop__container-active'
expect(component.find('[data-test-subj="testDragDropContainer"]').prop('className')).toEqual(
'domDragDrop__container domDragDrop__container-active'
);
expect(
component.find('[data-test-subj="lnsDragDropExtraDrops"]').first().prop('className')
).toEqual('lnsDragDrop__extraDrops lnsDragDrop__extraDrops-visible');
component.find('[data-test-subj="testDragDropExtraDrops"]').first().prop('className')
).toEqual('domDragDrop__extraDrops domDragDrop__extraDrops-visible');
// set activeDropTarget as undefined
component.find('[data-test-subj="lnsDragDrop"]').at(1).simulate('dragleave');
component.find('[data-test-subj="testDragDrop"]').at(1).simulate('dragleave');
act(() => {
jest.runAllTimers();
});
@ -593,13 +597,13 @@ describe('DragDrop', () => {
// customDropTargets are invisible
expect(
component.find('[data-test-subj="lnsDragDropExtraDrops"]').first().prop('className')
).toEqual('lnsDragDrop__extraDrops');
component.find('[data-test-subj="testDragDropExtraDrops"]').first().prop('className')
).toEqual('domDragDrop__extraDrops');
});
test('dragging over different drop types of the same value assigns correct activeDropTarget', () => {
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
@ -631,7 +635,7 @@ describe('DragDrop', () => {
test('drop on extra drop target passes correct dropType to onDrop', () => {
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
@ -659,7 +663,7 @@ describe('DragDrop', () => {
test('pressing Alt or Shift when dragging over the main drop target sets extra drop target as active', () => {
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
@ -689,7 +693,7 @@ describe('DragDrop', () => {
test('pressing Alt or Shift when dragging over the extra drop target does nothing', () => {
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
@ -805,7 +809,7 @@ describe('DragDrop', () => {
))}
</ChildDragDropProvider>
);
component.find('[data-test-subj="lnsDragDrop-keyboardHandler"]').at(1).simulate('focus');
component.find('[data-test-subj="testDragDrop-keyboardHandler"]').at(1).simulate('focus');
act(() => {
jest.runAllTimers();
});
@ -837,7 +841,7 @@ describe('DragDrop', () => {
);
act(() => {
component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('keydown', { key: 'ArrowRight', altKey: true });
});
@ -848,7 +852,7 @@ describe('DragDrop', () => {
});
act(() => {
component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('keydown', { key: 'ArrowRight', shiftKey: true });
});
@ -883,7 +887,7 @@ describe('DragDrop', () => {
);
act(() => {
component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('keydown', { key: 'Alt' });
});
@ -894,7 +898,7 @@ describe('DragDrop', () => {
});
act(() => {
component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('keyup', { key: 'Alt' });
});
@ -929,7 +933,7 @@ describe('DragDrop', () => {
);
act(() => {
component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('keydown', { key: 'Shift' });
});
@ -941,7 +945,7 @@ describe('DragDrop', () => {
});
act(() => {
component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('keyup', { key: 'Shift' });
});
@ -985,6 +989,7 @@ describe('DragDrop', () => {
const setA11yMessage = jest.fn();
const registerDropTarget = jest.fn();
const baseContext = {
dataTestSubjPrefix: defaultContext.dataTestSubjPrefix,
dragging,
setDragging: (val?: DraggingIdentifier) => {
dragging = val;
@ -1011,7 +1016,7 @@ describe('DragDrop', () => {
return mount(
<ChildDragDropProvider {...baseContext} {...dragContext}>
<ReorderProvider id="groupId">
<ReorderProvider id="groupId" dataTestSubj="testDragDrop">
<DragDrop
{...dragDropSharedProps}
value={items[0]}
@ -1045,7 +1050,7 @@ describe('DragDrop', () => {
act(() => {
jest.runAllTimers();
});
expect(component.find('[data-test-subj="lnsDragDrop"]')).toHaveLength(5);
expect(component.find('[data-test-subj="testDragDrop"]')).toHaveLength(5);
});
test(`Reorderable group with lifted element renders properly`, () => {
@ -1061,7 +1066,7 @@ describe('DragDrop', () => {
jest.runAllTimers();
});
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
@ -1077,7 +1082,7 @@ describe('DragDrop', () => {
const component = mountComponent({ dragging: { ...items[0] } });
component
.find('[data-test-subj="lnsDragDrop"]')
.find('[data-test-subj="testDragDrop"]')
.first()
.simulate('dragstart', { dataTransfer });
@ -1086,32 +1091,32 @@ describe('DragDrop', () => {
});
component
.find('[data-test-subj="lnsDragDrop-reorderableDropLayer"]')
.find('[data-test-subj="testDragDrop-reorderableDropLayer"]')
.at(1)
.simulate('dragover');
expect(
component.find('[data-test-subj="lnsDragDrop-reorderableDrag"]').at(0).prop('style')
component.find('[data-test-subj="testDragDrop-reorderableDrag"]').at(0).prop('style')
).toEqual(undefined);
expect(
component.find('[data-test-subj="lnsDragDrop-translatableDrop"]').at(0).prop('style')
component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(0).prop('style')
).toEqual({
transform: 'translateY(-8px)',
});
expect(
component.find('[data-test-subj="lnsDragDrop-translatableDrop"]').at(1).prop('style')
component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(1).prop('style')
).toEqual({
transform: 'translateY(-8px)',
});
component
.find('[data-test-subj="lnsDragDrop-reorderableDropLayer"]')
.find('[data-test-subj="testDragDrop-reorderableDropLayer"]')
.at(1)
.simulate('dragleave');
expect(
component.find('[data-test-subj="lnsDragDrop-reorderableDrag"]').at(0).prop('style')
component.find('[data-test-subj="testDragDrop-reorderableDrag"]').at(0).prop('style')
).toEqual(undefined);
expect(
component.find('[data-test-subj="lnsDragDrop-translatableDrop"]').at(1).prop('style')
component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(1).prop('style')
).toEqual(undefined);
});
@ -1128,7 +1133,7 @@ describe('DragDrop', () => {
setA11yMessage,
});
const dragDrop = component.find('[data-test-subj="lnsDragDrop-reorderableDropLayer"]').at(1);
const dragDrop = component.find('[data-test-subj="testDragDrop-reorderableDropLayer"]').at(1);
dragDrop.simulate('dragOver');
dragDrop.simulate('drop', { preventDefault, stopPropagation });
@ -1160,7 +1165,7 @@ describe('DragDrop', () => {
setA11yMessage,
});
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1);
keyboardHandler.simulate('keydown', { key: 'Space' });
@ -1188,7 +1193,7 @@ describe('DragDrop', () => {
keyboardMode: true,
});
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1)
.simulate('focus');
@ -1208,7 +1213,7 @@ describe('DragDrop', () => {
onDropHandler
);
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1);
keyboardHandler.simulate('keydown', { key: 'Space' });
keyboardHandler.simulate('keydown', { key: 'Escape' });
@ -1245,37 +1250,37 @@ describe('DragDrop', () => {
});
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1);
keyboardHandler.simulate('keydown', { key: 'Space' });
keyboardHandler.simulate('keydown', { key: 'ArrowDown' });
expect(
component.find('[data-test-subj="lnsDragDrop-reorderableDrag"]').at(0).prop('style')
component.find('[data-test-subj="testDragDrop-reorderableDrag"]').at(0).prop('style')
).toEqual({
transform: 'translateY(+8px)',
});
expect(
component.find('[data-test-subj="lnsDragDrop-translatableDrop"]').at(0).prop('style')
component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(0).prop('style')
).toEqual({
transform: 'translateY(-40px)',
});
expect(
component.find('[data-test-subj="lnsDragDrop-translatableDrop"]').at(1).prop('style')
component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(1).prop('style')
).toEqual(undefined);
expect(setA11yMessage).toBeCalledWith(
'Reorder Label1 in X group from position 1 to position 2. Press space or enter to reorder'
);
component
.find('[data-test-subj="lnsDragDrop-reorderableDropLayer"]')
.find('[data-test-subj="testDragDrop-reorderableDropLayer"]')
.at(1)
.simulate('dragleave');
expect(
component.find('[data-test-subj="lnsDragDrop-reorderableDrag"]').at(0).prop('style')
component.find('[data-test-subj="testDragDrop-reorderableDrag"]').at(0).prop('style')
).toEqual(undefined);
expect(
component.find('[data-test-subj="lnsDragDrop-translatableDrop"]').at(1).prop('style')
component.find('[data-test-subj="testDragDrop-translatableDrop"]').at(1).prop('style')
).toEqual(undefined);
});
@ -1299,7 +1304,7 @@ describe('DragDrop', () => {
setActiveDropTarget={setActiveDropTarget}
setA11yMessage={setA11yMessage}
>
<ReorderProvider id="groupId">
<ReorderProvider id="groupId" dataTestSubj="testDragDrop">
<DragDrop
draggable
dragType="move"
@ -1323,7 +1328,7 @@ describe('DragDrop', () => {
</ChildDragDropProvider>
);
const keyboardHandler = component
.find('[data-test-subj="lnsDragDrop-keyboardHandler"]')
.find('[data-test-subj="testDragDrop-keyboardHandler"]')
.at(1);
keyboardHandler.simulate('keydown', { key: 'Space' });

View file

@ -1,17 +1,16 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import './drag_drop.scss';
import React, { useContext, useCallback, useEffect, memo, useMemo, useState, useRef } from 'react';
import type { KeyboardEvent, ReactElement } from 'react';
import classNames from 'classnames';
import { keys, EuiScreenReaderOnly, EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
import useShallowCompareEffect from 'react-use/lib/useShallowCompareEffect';
import { trackUiCounterEvents } from '../lens_ui_telemetry';
import {
DragDropIdentifier,
DropIdentifier,
@ -24,8 +23,12 @@ import {
announce,
Ghost,
} from './providers';
import { DropType } from '../types';
import { DropType } from './types';
import './sass/drag_drop.scss';
/**
* Droppable event
*/
export type DroppableEvent = React.DragEvent<HTMLElement>;
const noop = () => {};
@ -126,6 +129,8 @@ interface DragInnerProps extends BaseProps {
activeDropTarget: DragContextState['activeDropTarget'];
dropTargetsByOrder: DragContextState['dropTargetsByOrder'];
};
dataTestSubjPrefix: DragContextState['dataTestSubjPrefix'];
onTrackUICounterEvent: DragContextState['onTrackUICounterEvent'] | undefined;
extraKeyboardHandler?: (e: KeyboardEvent<HTMLButtonElement>) => void;
ariaDescribedBy?: string;
}
@ -142,11 +147,18 @@ interface DropsInnerProps extends BaseProps {
setA11yMessage: DragContextState['setA11yMessage'];
registerDropTarget: DragContextState['registerDropTarget'];
activeDropTarget: DragContextState['activeDropTarget'];
dataTestSubjPrefix: DragContextState['dataTestSubjPrefix'];
onTrackUICounterEvent: DragContextState['onTrackUICounterEvent'] | undefined;
isNotDroppable: boolean;
}
const lnsLayerPanelDimensionMargin = 8;
/**
* DragDrop component
* @param props
* @constructor
*/
export const DragDrop = (props: BaseProps) => {
const {
dragging,
@ -158,6 +170,8 @@ export const DragDrop = (props: BaseProps) => {
activeDropTarget,
setActiveDropTarget,
setA11yMessage,
dataTestSubjPrefix,
onTrackUICounterEvent,
} = useContext(DragContext);
const { value, draggable, dropTypes, reorderableGroup } = props;
@ -179,6 +193,8 @@ export const DragDrop = (props: BaseProps) => {
setDragging,
setActiveDropTarget,
setA11yMessage,
dataTestSubjPrefix,
onTrackUICounterEvent,
};
if (reorderableGroup && reorderableGroup.length > 1) {
return <ReorderableDrag {...dragProps} reorderableGroup={reorderableGroup} />;
@ -197,6 +213,8 @@ export const DragDrop = (props: BaseProps) => {
setActiveDropTarget,
registerDropTarget,
setA11yMessage,
dataTestSubjPrefix,
onTrackUICounterEvent,
isNotDroppable:
// If the configuration has provided a droppable flag, but this particular item is not
// droppable, then it should be less prominent. Ignores items that are both
@ -237,6 +255,8 @@ const DragInner = memo(function DragInner({
extraKeyboardHandler,
ariaDescribedBy,
setA11yMessage,
dataTestSubjPrefix,
onTrackUICounterEvent,
}: DragInnerProps) {
const keyboardMode = activeDraggingProps?.keyboardMode;
const activeDropTarget = activeDraggingProps?.activeDropTarget;
@ -385,7 +405,7 @@ const DragInner = memo(function DragInner({
const dropToActiveDropTarget = () => {
if (activeDropTarget) {
trackUiCounterEvents('drop_total');
onTrackUICounterEvent?.('drop_total');
const { dropType, humanData, onDrop: onTargetDrop } = activeDropTarget;
setTimeout(() => setA11yMessage(announce.dropped(value.humanData, humanData, dropType)));
onTargetDrop(value, dropType);
@ -400,18 +420,18 @@ const DragInner = memo(function DragInner({
return (
<div
className={classNames(className, {
'lnsDragDrop-isHidden':
'domDragDrop-isHidden':
(activeDraggingProps && dragType === 'move' && !keyboardMode) ||
shouldShowGhostImageInstead,
})}
data-test-subj={`lnsDragDrop_draggable-${value.humanData.label}`}
data-test-subj={`${dataTestSubjPrefix}_draggable-${value.humanData.label}`}
>
<EuiScreenReaderOnly showOnFocus>
<button
aria-label={value.humanData.label}
aria-describedby={ariaDescribedBy || `lnsDragDrop-keyboardInstructions`}
className="lnsDragDrop__keyboardHandler"
data-test-subj="lnsDragDrop-keyboardHandler"
aria-describedby={ariaDescribedBy || `${dataTestSubjPrefix}-keyboardInstructions`}
className="domDragDrop__keyboardHandler"
data-test-subj={`${dataTestSubjPrefix}-keyboardHandler`}
onBlur={(e) => {
if (activeDraggingProps) {
dragEnd();
@ -451,8 +471,8 @@ const DragInner = memo(function DragInner({
</EuiScreenReaderOnly>
{React.cloneElement(children, {
'data-test-subj': dataTestSubj || 'lnsDragDrop',
className: classNames(children.props.className, 'lnsDragDrop', 'lnsDragDrop-isDraggable'),
'data-test-subj': dataTestSubj || dataTestSubjPrefix,
className: classNames(children.props.className, 'domDragDrop', 'domDragDrop-isDraggable'),
draggable: true,
onDragEnd: dragEnd,
onDragStart: dragStart,
@ -484,6 +504,7 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) {
setDragging,
setA11yMessage,
getCustomDropTarget,
dataTestSubjPrefix,
} = props;
const [isInZone, setIsInZone] = useState(false);
@ -587,7 +608,7 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) {
activeDropTarget?.id === value.id && dropType === activeDropTarget?.dropType
);
return {
'data-test-subj': dataTestSubj || 'lnsDragDrop',
'data-test-subj': dataTestSubj || dataTestSubjPrefix,
className: getClasses(dropType, dropChildren),
onDragEnter: dragEnter,
onDragLeave: dragLeave,
@ -607,13 +628,13 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) {
const classesOnDroppable = getAdditionalClassesOnDroppable?.(dropType);
const classes = classNames(
'lnsDragDrop',
'domDragDrop',
{
'lnsDragDrop-isDraggable': draggable,
'lnsDragDrop-isDroppable': !draggable,
'lnsDragDrop-isDropTarget': dropType,
'lnsDragDrop-isActiveDropTarget': dropType && isActiveDropTarget,
'lnsDragDrop-isNotDroppable': isNotDroppable,
'domDragDrop-isDraggable': draggable,
'domDragDrop-isDroppable': !draggable,
'domDragDrop-isDropTarget': dropType,
'domDragDrop-isActiveDropTarget': dropType && isActiveDropTarget,
'domDragDrop-isNotDroppable': isNotDroppable,
},
classesOnDroppable && { [classesOnDroppable]: dropType }
);
@ -644,9 +665,9 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) {
return (
<div
data-test-subj="lnsDragDropContainer"
className={classNames('lnsDragDrop__container', {
'lnsDragDrop__container-active': isInZone || activeDropTarget?.id === value.id,
data-test-subj={`${dataTestSubjPrefix}Container`}
className={classNames('domDragDrop__container', {
'domDragDrop__container-active': isInZone || activeDropTarget?.id === value.id,
})}
onDragEnter={dragEnter}
ref={mainTargetRef}
@ -659,22 +680,22 @@ const DropsInner = memo(function DropsInner(props: DropsInnerProps) {
{dropTypes && dropTypes.length > 1 && (
<>
<div
className="lnsDragDrop__diamondPath"
className="domDragDrop__diamondPath"
style={extraDropStyles}
onDragEnter={dragEnter}
/>
<EuiFlexGroup
gutterSize="none"
direction="column"
data-test-subj="lnsDragDropExtraDrops"
className={classNames('lnsDragDrop__extraDrops', {
'lnsDragDrop__extraDrops-visible': isInZone || activeDropTarget?.id === value.id,
data-test-subj={`${dataTestSubjPrefix}ExtraDrops`}
className={classNames('domDragDrop__extraDrops', {
'domDragDrop__extraDrops-visible': isInZone || activeDropTarget?.id === value.id,
})}
>
{dropTypes.slice(1).map((dropType) => {
const dropChildren = getCustomDropTarget?.(dropType);
return dropChildren ? (
<EuiFlexItem key={dropType} className="lnsDragDrop__extraDropWrapper">
<EuiFlexItem key={dropType} className="domDragDrop__extraDropWrapper">
<SingleDropInner {...getProps(dropType, dropChildren)}>
{dropChildren}
</SingleDropInner>
@ -703,7 +724,7 @@ const SingleDropInner = ({
{React.cloneElement(children, rest)}
{ghost
? React.cloneElement(ghost.children, {
className: classNames(ghost.children.props.className, 'lnsDragDrop_ghost'),
className: classNames(ghost.children.props.className, 'domDragDrop_ghost'),
style: ghost.style,
})
: null}
@ -719,8 +740,14 @@ const ReorderableDrag = memo(function ReorderableDrag(
setReorderState,
} = useContext(ReorderContext);
const { value, setActiveDropTarget, activeDraggingProps, reorderableGroup, setA11yMessage } =
props;
const {
value,
setActiveDropTarget,
activeDraggingProps,
reorderableGroup,
setA11yMessage,
dataTestSubjPrefix,
} = props;
const keyboardMode = activeDraggingProps?.keyboardMode;
const activeDropTarget = activeDraggingProps?.activeDropTarget;
@ -838,11 +865,11 @@ const ReorderableDrag = memo(function ReorderableDrag(
return (
<div
data-test-subj="lnsDragDrop-reorderableDrag"
data-test-subj={`${dataTestSubjPrefix}-reorderableDrag`}
className={
isDragging
? 'lnsDragDrop-reorderable lnsDragDrop-translatableDrag'
: 'lnsDragDrop-reorderable'
? 'domDragDrop-reorderable domDragDrop-translatableDrag'
: 'domDragDrop-reorderable'
}
style={
areItemsReordered
@ -857,7 +884,7 @@ const ReorderableDrag = memo(function ReorderableDrag(
>
<DragInner
{...props}
ariaDescribedBy="lnsDragDrop-keyboardInstructionsWithReorder"
ariaDescribedBy={`${dataTestSubjPrefix}-keyboardInstructionsWithReorder`}
extraKeyboardHandler={extraKeyboardHandler}
onDragStart={onReorderableDragStart}
onDragEnd={onReorderableDragEnd}
@ -879,6 +906,8 @@ const ReorderableDrop = memo(function ReorderableDrop(
setActiveDropTarget,
reorderableGroup,
setA11yMessage,
dataTestSubjPrefix,
onTrackUICounterEvent,
} = props;
const currentIndex = reorderableGroup.findIndex((i) => i.id === value.id);
@ -953,7 +982,7 @@ const ReorderableDrop = memo(function ReorderableDrop(
setKeyboardMode(false);
if (onDrop && dragging) {
trackUiCounterEvents('drop_total');
onTrackUICounterEvent?.('drop_total');
onDrop(dragging, 'reorder');
// setTimeout ensures it will run after dragEnd messaging
setTimeout(() =>
@ -973,16 +1002,16 @@ const ReorderableDrop = memo(function ReorderableDrop(
: undefined
}
ref={heightRef}
data-test-subj="lnsDragDrop-translatableDrop"
className="lnsDragDrop-translatableDrop lnsDragDrop-reorderable"
data-test-subj={`${dataTestSubjPrefix}-translatableDrop`}
className="domDragDrop-translatableDrop domDragDrop-reorderable"
>
<DropsInner {...props} />
</div>
<div
data-test-subj="lnsDragDrop-reorderableDropLayer"
className={classNames('lnsDragDrop', {
['lnsDragDrop__reorderableDrop']: dragging,
data-test-subj={`${dataTestSubjPrefix}-reorderableDropLayer`}
className={classNames('domDragDrop', {
['domDragDrop__reorderableDrop']: dragging,
})}
onDrop={onReorderableDrop}
onDragOver={onReorderableDragOver}

View file

@ -0,0 +1,22 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
getCustomDropTarget,
getAdditionalClassesOnDroppable,
getAdditionalClassesOnEnter,
} from './swap_duplicate_combine';
/**
* Helpers for swap/duplicate/combine extra drops
*/
export const DropTargetSwapDuplicateCombine = {
getCustomDropTarget,
getAdditionalClassesOnDroppable,
getAdditionalClassesOnEnter,
};

View file

@ -0,0 +1,133 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import classNames from 'classnames';
import { EuiIcon, EuiFlexItem, EuiFlexGroup, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { DropType } from '../types';
import { DEFAULT_DATA_TEST_SUBJ } from '../constants';
function getPropsForDropType(type: 'swap' | 'duplicate' | 'combine') {
switch (type) {
case 'duplicate':
return {
icon: 'copy',
label: i18n.translate('domDragDrop.dropTargets.duplicate', {
defaultMessage: 'Duplicate',
}),
controlKey: i18n.translate('domDragDrop.dropTargets.altOption', {
defaultMessage: 'Alt/Option',
}),
};
case 'swap':
return {
icon: 'merge',
label: i18n.translate('domDragDrop.dropTargets.swap', {
defaultMessage: 'Swap',
}),
controlKey: i18n.translate('domDragDrop.dropTargets.shift', {
defaultMessage: 'Shift',
}),
};
case 'combine':
return {
icon: 'aggregate',
label: i18n.translate('domDragDrop.dropTargets.combine', {
defaultMessage: 'Combine',
}),
controlKey: i18n.translate('domDragDrop.dropTargets.control', {
defaultMessage: 'Control',
}),
};
default:
throw Error('Drop type not supported');
}
}
const getExtraDrop = ({
type,
isIncompatible,
}: {
type: 'swap' | 'duplicate' | 'combine';
isIncompatible?: boolean;
}) => {
const { icon, label, controlKey } = getPropsForDropType(type);
return (
<EuiFlexGroup
gutterSize="s"
justifyContent="spaceBetween"
alignItems="center"
className={classNames('domDragDrop__extraDrop', {
'domDragDrop-incompatibleExtraDrop': isIncompatible,
})}
>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
<EuiIcon size="m" type={icon} />
</EuiFlexItem>
<EuiFlexItem grow={false} data-test-subj={`${DEFAULT_DATA_TEST_SUBJ}-dropTarget-${type}`}>
<EuiText size="s">{label}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText size="xs">
<code> {controlKey}</code>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
);
};
const customDropTargetsMap: Partial<{ [dropType in DropType]: React.ReactElement }> = {
replace_duplicate_incompatible: getExtraDrop({ type: 'duplicate', isIncompatible: true }),
duplicate_incompatible: getExtraDrop({ type: 'duplicate', isIncompatible: true }),
swap_incompatible: getExtraDrop({ type: 'swap', isIncompatible: true }),
replace_duplicate_compatible: getExtraDrop({ type: 'duplicate' }),
duplicate_compatible: getExtraDrop({ type: 'duplicate' }),
swap_compatible: getExtraDrop({ type: 'swap' }),
field_combine: getExtraDrop({ type: 'combine' }),
combine_compatible: getExtraDrop({ type: 'combine' }),
combine_incompatible: getExtraDrop({ type: 'combine', isIncompatible: true }),
};
export const getCustomDropTarget = (dropType: DropType) => customDropTargetsMap?.[dropType] || null;
export const getAdditionalClassesOnEnter = (dropType?: string) => {
if (
dropType &&
[
'field_replace',
'replace_compatible',
'replace_incompatible',
'replace_duplicate_compatible',
'replace_duplicate_incompatible',
].includes(dropType)
) {
return 'domDragDrop-isReplacing';
}
};
export const getAdditionalClassesOnDroppable = (dropType?: string) => {
if (
dropType &&
[
'move_incompatible',
'replace_incompatible',
'swap_incompatible',
'duplicate_incompatible',
'replace_duplicate_incompatible',
'combine_incompatible',
].includes(dropType)
) {
return 'domDragDrop-notCompatible';
}
};

View file

@ -1,9 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './types';
export * from './providers';
export * from './drag_drop';

View file

@ -1,12 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { i18n } from '@kbn/i18n';
import { DropType } from '../../types';
import { DropType } from '../types';
import { HumanData } from '.';
type AnnouncementFunction = (
@ -35,7 +36,7 @@ const replaceAnnouncement = {
announceModifierKeys?: boolean
) => {
if (announceModifierKeys && (canSwap || canDuplicate)) {
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.replaceMain', {
return i18n.translate('domDragDrop.announce.selectedTarget.replaceMain', {
defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to replace {dropLabel} with {label}.{duplicateCopy}{swapCopy}{combineCopy}`,
values: {
label,
@ -52,7 +53,7 @@ const replaceAnnouncement = {
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.replace', {
return i18n.translate('domDragDrop.announce.selectedTarget.replace', {
defaultMessage: `Replace {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber} with {label}. Press space or enter to replace.`,
values: {
label,
@ -67,7 +68,7 @@ const replaceAnnouncement = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, layerNumber: dropLayerNumber }: HumanData
) => {
return i18n.translate('xpack.lens.dragDrop.announce.duplicated.replace', {
return i18n.translate('domDragDrop.announce.duplicated.replace', {
defaultMessage:
'Replaced {dropLabel} with {label} in {groupLabel} at position {position} in layer {dropLayerNumber}',
values: {
@ -87,7 +88,7 @@ const duplicateAnnouncement = {
{ groupLabel: dropGroupLabel, position }: HumanData
) => {
if (groupLabel !== dropGroupLabel) {
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.duplicated', {
return i18n.translate('domDragDrop.announce.selectedTarget.duplicated', {
defaultMessage: `Duplicate {label} to {dropGroupLabel} group at position {position} in layer {layerNumber}. Hold Alt or Option and press space or enter to duplicate`,
values: {
label,
@ -97,7 +98,7 @@ const duplicateAnnouncement = {
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.duplicatedInGroup', {
return i18n.translate('domDragDrop.announce.selectedTarget.duplicatedInGroup', {
defaultMessage: `Duplicate {label} to {dropGroupLabel} group at position {position} in layer {layerNumber}. Press space or enter to duplicate`,
values: {
label,
@ -108,7 +109,7 @@ const duplicateAnnouncement = {
});
},
dropped: ({ label }: HumanData, { groupLabel, position, layerNumber }: HumanData) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.duplicated', {
i18n.translate('domDragDrop.announce.dropped.duplicated', {
defaultMessage:
'Duplicated {label} in {groupLabel} group at position {position} in layer {layerNumber}',
values: {
@ -126,14 +127,14 @@ const reorderAnnouncement = {
{ position }: HumanData
) => {
return prevPosition === position
? i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.reorderedBack', {
? i18n.translate('domDragDrop.announce.selectedTarget.reorderedBack', {
defaultMessage: `{label} returned to its initial position {prevPosition}`,
values: {
label,
prevPosition,
},
})
: i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.reordered', {
: i18n.translate('domDragDrop.announce.selectedTarget.reordered', {
defaultMessage: `Reorder {label} in {groupLabel} group from position {prevPosition} to position {position}. Press space or enter to reorder`,
values: {
label,
@ -144,7 +145,7 @@ const reorderAnnouncement = {
});
},
dropped: ({ label, groupLabel, position: prevPosition }: HumanData, { position }: HumanData) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.reordered', {
i18n.translate('domDragDrop.announce.dropped.reordered', {
defaultMessage:
'Reordered {label} in {groupLabel} group from position {prevPosition} to position {position}',
values: {
@ -171,7 +172,7 @@ const combineAnnouncement = {
announceModifierKeys?: boolean
) => {
if (announceModifierKeys && (canSwap || canDuplicate || canCombine)) {
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.combineMain', {
return i18n.translate('domDragDrop.announce.selectedTarget.combineMain', {
defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to combine {dropLabel} with {label}.{duplicateCopy}{swapCopy}{combineCopy}`,
values: {
label,
@ -188,7 +189,7 @@ const combineAnnouncement = {
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.combine', {
return i18n.translate('domDragDrop.announce.selectedTarget.combine', {
defaultMessage: `Combine {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber} with {label}. Press space or enter to combine.`,
values: {
label,
@ -203,7 +204,7 @@ const combineAnnouncement = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.duplicated.combine', {
i18n.translate('domDragDrop.announce.duplicated.combine', {
defaultMessage:
'Combine {dropLabel} with {label} in {groupLabel} at position {position} in layer {dropLayerNumber}',
values: {
@ -216,15 +217,15 @@ const combineAnnouncement = {
}),
};
const DUPLICATE_SHORT = i18n.translate('xpack.lens.dragDrop.announce.duplicate.short', {
const DUPLICATE_SHORT = i18n.translate('domDragDrop.announce.duplicate.short', {
defaultMessage: ' Hold alt or option to duplicate.',
});
const SWAP_SHORT = i18n.translate('xpack.lens.dragDrop.announce.swap.short', {
const SWAP_SHORT = i18n.translate('domDragDrop.announce.swap.short', {
defaultMessage: ' Hold shift to swap.',
});
const COMBINE_SHORT = i18n.translate('xpack.lens.dragDrop.announce.combine.short', {
const COMBINE_SHORT = i18n.translate('domDragDrop.announce.combine.short', {
defaultMessage: ' Hold control to combine',
});
@ -250,28 +251,25 @@ export const announcements: CustomAnnouncementsType = {
announceModifierKeys?: boolean
) => {
if (announceModifierKeys && (canSwap || canDuplicate || canCombine)) {
return i18n.translate(
'xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatibleMain',
{
defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to convert {label} to {nextLabel} and replace {dropLabel}.{duplicateCopy}{swapCopy}{combineCopy}`,
values: {
label,
groupLabel,
position,
dropLabel,
dropGroupLabel,
dropPosition,
nextLabel,
duplicateCopy: canDuplicate ? DUPLICATE_SHORT : '',
swapCopy: canSwap ? SWAP_SHORT : '',
combineCopy: canCombine ? COMBINE_SHORT : '',
layerNumber,
dropLayerNumber,
},
}
);
return i18n.translate('domDragDrop.announce.selectedTarget.replaceIncompatibleMain', {
defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over {dropLabel} from {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to convert {label} to {nextLabel} and replace {dropLabel}.{duplicateCopy}{swapCopy}{combineCopy}`,
values: {
label,
groupLabel,
position,
dropLabel,
dropGroupLabel,
dropPosition,
nextLabel,
duplicateCopy: canDuplicate ? DUPLICATE_SHORT : '',
swapCopy: canSwap ? SWAP_SHORT : '',
combineCopy: canCombine ? COMBINE_SHORT : '',
layerNumber,
dropLayerNumber,
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatible', {
return i18n.translate('domDragDrop.announce.selectedTarget.replaceIncompatible', {
defaultMessage: `Convert {label} to {nextLabel} and replace {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to replace`,
values: {
label,
@ -296,7 +294,7 @@ export const announcements: CustomAnnouncementsType = {
announceModifierKeys?: boolean
) => {
if (announceModifierKeys && (canSwap || canDuplicate)) {
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.moveIncompatibleMain', {
return i18n.translate('domDragDrop.announce.selectedTarget.moveIncompatibleMain', {
defaultMessage: `You're dragging {label} from {groupLabel} at position {position} in layer {layerNumber} over position {dropPosition} in {dropGroupLabel} group in layer {dropLayerNumber}. Press space or enter to convert {label} to {nextLabel} and move.{duplicateCopy}`,
values: {
label,
@ -311,7 +309,7 @@ export const announcements: CustomAnnouncementsType = {
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.moveIncompatible', {
return i18n.translate('domDragDrop.announce.selectedTarget.moveIncompatible', {
defaultMessage: `Convert {label} to {nextLabel} and move to {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to move`,
values: {
label,
@ -335,7 +333,7 @@ export const announcements: CustomAnnouncementsType = {
announceModifierKeys?: boolean
) => {
if (announceModifierKeys && (canSwap || canDuplicate)) {
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.moveCompatibleMain', {
return i18n.translate('domDragDrop.announce.selectedTarget.moveCompatibleMain', {
defaultMessage: `You're dragging {label} from {groupLabel} at position {position} over position {dropPosition} in {dropGroupLabel} group in layer {dropLayerNumber}. Press space or enter to move.{duplicateCopy}`,
values: {
label,
@ -348,7 +346,7 @@ export const announcements: CustomAnnouncementsType = {
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.moveCompatible', {
return i18n.translate('domDragDrop.announce.selectedTarget.moveCompatible', {
defaultMessage: `Move {label} to {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Press space or enter to move`,
values: {
label,
@ -362,7 +360,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ groupLabel, position, nextLabel, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.duplicateIncompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.duplicateIncompatible', {
defaultMessage:
'Convert copy of {label} to {nextLabel} and add to {groupLabel} group at position {position} in layer {dropLayerNumber}. Hold Alt or Option and press space or enter to duplicate',
values: {
@ -377,7 +375,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, nextLabel, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateIncompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.replaceDuplicateIncompatible', {
defaultMessage:
'Convert copy of {label} to {nextLabel} and replace {dropLabel} in {groupLabel} group at position {position} in layer {dropLayerNumber}. Hold Alt or Option and press space or enter to duplicate and replace',
values: {
@ -393,7 +391,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateCompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.replaceDuplicateCompatible', {
defaultMessage:
'Duplicate {label} and replace {dropLabel} in {groupLabel} at position {position} in layer {dropLayerNumber}. Hold Alt or Option and press space or enter to duplicate and replace',
values: {
@ -413,7 +411,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.swapCompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.swapCompatible', {
defaultMessage:
'Swap {label} in {groupLabel} group at position {position} in layer {layerNumber} with {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Hold Shift and press space or enter to swap',
values: {
@ -437,7 +435,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.swapIncompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.swapIncompatible', {
defaultMessage:
'Convert {label} to {nextLabel} in {groupLabel} group at position {position} in layer {layerNumber} and swap with {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Hold Shift and press space or enter to swap',
values: {
@ -461,7 +459,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.combineCompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.combineCompatible', {
defaultMessage:
'Combine {label} in {groupLabel} group at position {position} in layer {layerNumber} with {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Hold Control and press space or enter to combine',
values: {
@ -485,7 +483,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.combineIncompatible', {
i18n.translate('domDragDrop.announce.selectedTarget.combineIncompatible', {
defaultMessage:
'Convert {label} to {nextLabel} in {groupLabel} group at position {position} in layer {layerNumber} and combine with {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}. Hold Control and press space or enter to combine',
values: {
@ -511,7 +509,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, nextLabel, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.replaceIncompatible', {
i18n.translate('domDragDrop.announce.dropped.replaceIncompatible', {
defaultMessage:
'Converted {label} to {nextLabel} and replaced {dropLabel} in {groupLabel} group at position {position} in layer {dropLayerNumber}',
values: {
@ -527,7 +525,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ groupLabel, position, nextLabel, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.moveIncompatible', {
i18n.translate('domDragDrop.announce.dropped.moveIncompatible', {
defaultMessage:
'Converted {label} to {nextLabel} and moved to {groupLabel} group at position {position} in layer {dropLayerNumber}',
values: {
@ -543,7 +541,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ groupLabel, position, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.moveCompatible', {
i18n.translate('domDragDrop.announce.dropped.moveCompatible', {
defaultMessage:
'Moved {label} to {groupLabel} group at position {position} in layer {dropLayerNumber}',
values: {
@ -558,7 +556,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ groupLabel, position, nextLabel, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.duplicateIncompatible', {
i18n.translate('domDragDrop.announce.dropped.duplicateIncompatible', {
defaultMessage:
'Converted copy of {label} to {nextLabel} and added to {groupLabel} group at position {position} in layer {dropLayerNumber}',
values: {
@ -574,7 +572,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, nextLabel, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.replaceDuplicateIncompatible', {
i18n.translate('domDragDrop.announce.dropped.replaceDuplicateIncompatible', {
defaultMessage:
'Converted copy of {label} to {nextLabel} and replaced {dropLabel} in {groupLabel} group at position {position} in layer {dropLayerNumber}',
values: {
@ -590,7 +588,7 @@ export const announcements: CustomAnnouncementsType = {
{ label }: HumanData,
{ label: dropLabel, groupLabel, position, layerNumber: dropLayerNumber }: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.duplicated.replaceDuplicateCompatible', {
i18n.translate('domDragDrop.announce.duplicated.replaceDuplicateCompatible', {
defaultMessage:
'Replaced {dropLabel} with a copy of {label} in {groupLabel} at position {position} in layer {dropLayerNumber}',
values: {
@ -610,7 +608,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.swapCompatible', {
i18n.translate('domDragDrop.announce.dropped.swapCompatible', {
defaultMessage:
'Moved {label} to {dropGroupLabel} at position {dropPosition} in layer {dropLayerNumber} and {dropLabel} to {groupLabel} group at position {position} in layer {layerNumber}',
values: {
@ -634,7 +632,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.swapIncompatible', {
i18n.translate('domDragDrop.announce.dropped.swapIncompatible', {
defaultMessage:
'Converted {label} to {nextLabel} in {groupLabel} group at position {position} in layer {layerNumber} and swapped with {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}',
values: {
@ -658,7 +656,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.combineCompatible', {
i18n.translate('domDragDrop.announce.dropped.combineCompatible', {
defaultMessage:
'Combined {label} in group {groupLabel} to {dropLabel} in group {dropGroupLabel} at position {dropPosition} in layer {dropLayerNumber}',
values: {
@ -680,7 +678,7 @@ export const announcements: CustomAnnouncementsType = {
layerNumber: dropLayerNumber,
}: HumanData
) =>
i18n.translate('xpack.lens.dragDrop.announce.dropped.combineIncompatible', {
i18n.translate('domDragDrop.announce.dropped.combineIncompatible', {
defaultMessage:
'Converted {label} to {nextLabel} in {groupLabel} group at position {position} and combined with {dropLabel} in {dropGroupLabel} group at position {dropPosition} in layer {dropLayerNumber}',
values: {
@ -699,7 +697,7 @@ export const announcements: CustomAnnouncementsType = {
const defaultAnnouncements = {
lifted: ({ label }: HumanData) =>
i18n.translate('xpack.lens.dragDrop.announce.lifted', {
i18n.translate('domDragDrop.announce.lifted', {
defaultMessage: `Lifted {label}`,
values: {
label,
@ -707,14 +705,14 @@ const defaultAnnouncements = {
}),
cancelled: ({ label, groupLabel, position }: HumanData) => {
if (!groupLabel || !position) {
return i18n.translate('xpack.lens.dragDrop.announce.cancelled', {
return i18n.translate('domDragDrop.announce.cancelled', {
defaultMessage: 'Movement cancelled. {label} returned to its initial position',
values: {
label,
},
});
}
return i18n.translate('xpack.lens.dragDrop.announce.cancelledItem', {
return i18n.translate('domDragDrop.announce.cancelledItem', {
defaultMessage:
'Movement cancelled. {label} returned to {groupLabel} group at position {position}',
values: {
@ -726,7 +724,7 @@ const defaultAnnouncements = {
},
noTarget: () => {
return i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.noSelected', {
return i18n.translate('domDragDrop.announce.selectedTarget.noSelected', {
defaultMessage: `No target selected. Use arrow keys to select a target`,
});
},
@ -741,7 +739,7 @@ const defaultAnnouncements = {
}: HumanData
) =>
dropGroupLabel && position
? i18n.translate('xpack.lens.dragDrop.announce.droppedDefault', {
? i18n.translate('domDragDrop.announce.droppedDefault', {
defaultMessage:
'Added {label} in {dropGroupLabel} group at position {position} in layer {dropLayerNumber}',
values: {
@ -751,7 +749,7 @@ const defaultAnnouncements = {
dropLayerNumber,
},
})
: i18n.translate('xpack.lens.dragDrop.announce.droppedNoPosition', {
: i18n.translate('domDragDrop.announce.droppedNoPosition', {
defaultMessage: 'Added {label} to {dropLabel}',
values: {
label,
@ -768,7 +766,7 @@ const defaultAnnouncements = {
}: HumanData
) => {
return dropGroupLabel && position
? i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.default', {
? i18n.translate('domDragDrop.announce.selectedTarget.default', {
defaultMessage: `Add {label} to {dropGroupLabel} group at position {position} in layer {dropLayerNumber}. Press space or enter to add`,
values: {
label,
@ -777,7 +775,7 @@ const defaultAnnouncements = {
dropLayerNumber,
},
})
: i18n.translate('xpack.lens.dragDrop.announce.selectedTarget.defaultNoPosition', {
: i18n.translate('domDragDrop.announce.selectedTarget.defaultNoPosition', {
defaultMessage: `Add {label} to {dropLabel}. Press space or enter to add`,
values: {
dropLabel,

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export * from './providers';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useContext } from 'react';

View file

@ -1,8 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useState, useMemo } from 'react';
@ -15,6 +16,7 @@ import {
RegisteredDropTargets,
DragContextState,
} from './types';
import { DEFAULT_DATA_TEST_SUBJ } from '../constants';
/**
* The drag / drop context singleton, used like so:
@ -31,6 +33,8 @@ export const DragContext = React.createContext<DragContextState>({
setA11yMessage: () => {},
dropTargetsByOrder: undefined,
registerDropTarget: () => {},
dataTestSubjPrefix: DEFAULT_DATA_TEST_SUBJ,
onTrackUICounterEvent: undefined,
});
/**
@ -50,7 +54,15 @@ export interface ProviderProps extends DragContextState {
*
* @param props
*/
export function RootDragDropProvider({ children }: { children: React.ReactNode }) {
export function RootDragDropProvider({
children,
dataTestSubj = DEFAULT_DATA_TEST_SUBJ,
onTrackUICounterEvent,
}: {
children: React.ReactNode;
dataTestSubj?: string;
onTrackUICounterEvent?: DragContextState['onTrackUICounterEvent'];
}) {
const [draggingState, setDraggingState] = useState<{ dragging?: DraggingIdentifier }>({
dragging: undefined,
});
@ -101,6 +113,8 @@ export function RootDragDropProvider({ children }: { children: React.ReactNode }
setActiveDropTarget={setActiveDropTarget}
registerDropTarget={registerDropTarget}
dropTargetsByOrder={dropTargetsByOrderState}
dataTestSubjPrefix={dataTestSubj}
onTrackUICounterEvent={onTrackUICounterEvent}
>
{children}
</ChildDragDropProvider>
@ -109,13 +123,13 @@ export function RootDragDropProvider({ children }: { children: React.ReactNode }
<p aria-live="assertive" aria-atomic={true}>
{a11yMessageState}
</p>
<p id={`lnsDragDrop-keyboardInstructionsWithReorder`}>
{i18n.translate('xpack.lens.dragDrop.keyboardInstructionsReorder', {
<p id={`${dataTestSubj}-keyboardInstructionsWithReorder`}>
{i18n.translate('domDragDrop.keyboardInstructionsReorder', {
defaultMessage: `Press space or enter to start dragging. When dragging, use the up/down arrow keys to reorder items in the group and left/right arrow keys to choose drop targets outside of the group. Press space or enter again to finish.`,
})}
</p>
<p id={`lnsDragDrop-keyboardInstructions`}>
{i18n.translate('xpack.lens.dragDrop.keyboardInstructions', {
<p id={`${dataTestSubj}-keyboardInstructions`}>
{i18n.translate('domDragDrop.keyboardInstructions', {
defaultMessage: `Press space or enter to start dragging. When dragging, use the left/right arrow keys to move between drop targets. Press space or enter again to finish.`,
})}
</p>
@ -202,6 +216,8 @@ export function ChildDragDropProvider({
setA11yMessage,
registerDropTarget,
dropTargetsByOrder,
dataTestSubjPrefix,
onTrackUICounterEvent,
children,
}: ProviderProps) {
const value = useMemo(
@ -215,6 +231,8 @@ export function ChildDragDropProvider({
setA11yMessage,
dropTargetsByOrder,
registerDropTarget,
dataTestSubjPrefix,
onTrackUICounterEvent,
}),
[
setDragging,
@ -226,6 +244,8 @@ export function ChildDragDropProvider({
setA11yMessage,
dropTargetsByOrder,
registerDropTarget,
dataTestSubjPrefix,
onTrackUICounterEvent,
]
);
return <DragContext.Provider value={value}>{children}</DragContext.Provider>;

View file

@ -1,13 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React, { useState, useMemo } from 'react';
import classNames from 'classnames';
import { DEFAULT_DATA_TEST_SUBJ } from '../constants';
/**
* Reorder state
*/
export interface ReorderState {
/**
* Ids of the elements that are translated up or down
@ -34,11 +39,17 @@ export interface ReorderState {
type SetReorderStateDispatch = (prevState: ReorderState) => ReorderState;
/**
* Reorder context state
*/
export interface ReorderContextState {
reorderState: ReorderState;
setReorderState: (dispatch: SetReorderStateDispatch) => void;
}
/**
* Reorder context
*/
export const ReorderContext = React.createContext<ReorderContextState>({
reorderState: {
reorderedItems: [],
@ -50,14 +61,24 @@ export const ReorderContext = React.createContext<ReorderContextState>({
setReorderState: () => () => {},
});
/**
* To create a reordering group, surround the elements from the same group with a `ReorderProvider`
* @param id
* @param children
* @param className
* @param dataTestSubj
* @constructor
*/
export function ReorderProvider({
id,
children,
className,
dataTestSubj = DEFAULT_DATA_TEST_SUBJ,
}: {
id: string;
children: React.ReactNode;
className?: string;
dataTestSubj?: string;
}) {
const [state, setState] = useState<ReorderContextState['reorderState']>({
reorderedItems: [],
@ -71,11 +92,12 @@ export function ReorderProvider({
() => (dispatch: SetReorderStateDispatch) => setState(dispatch),
[setState]
);
return (
<div
data-test-subj="lnsDragDrop-reorderableGroup"
data-test-subj={`${dataTestSubj}-reorderableGroup`}
className={classNames(className, {
'lnsDragDrop-isActiveGroup': state.isReorderOn && React.Children.count(children) > 1,
'domDragDrop-isActiveGroup': state.isReorderOn && React.Children.count(children) > 1,
})}
>
<ReorderContext.Provider value={{ reorderState: state, setReorderState }}>

View file

@ -1,11 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { DropType } from '../../types';
import { DropType } from '../types';
export interface HumanData {
label: string;
@ -23,6 +24,9 @@ export interface Ghost {
style: React.CSSProperties;
}
/**
* Drag Drop base identifier
*/
export type DragDropIdentifier = Record<string, unknown> & {
id: string;
/**
@ -31,10 +35,16 @@ export type DragDropIdentifier = Record<string, unknown> & {
humanData: HumanData;
};
/**
* Dragging identifier
*/
export type DraggingIdentifier = DragDropIdentifier & {
ghost?: Ghost;
};
/**
* Drop identifier
*/
export type DropIdentifier = DragDropIdentifier & {
dropType: DropType;
onDrop: DropHandler;
@ -50,7 +60,6 @@ export type RegisteredDropTargets = Record<string, DropIdentifier | undefined> |
/**
* The shape of the drag / drop context.
*/
export interface DragContextState {
/**
* The item being dragged or undefined.
@ -78,4 +87,15 @@ export interface DragContextState {
setA11yMessage: (message: string) => void;
registerDropTarget: (order: number[], dropTarget?: DropIdentifier) => void;
/**
* Customizable data-test-subj prefix
*/
dataTestSubjPrefix: string;
/**
* A custom callback for telemetry
* @param event
*/
onTrackUICounterEvent?: (event: string) => void;
}

View file

@ -1,15 +1,14 @@
@import '../variables';
@import '../mixins';
@import './drag_drop_mixins';
.lnsDragDrop {
.domDragDrop {
user-select: none;
transition: $euiAnimSpeedFast ease-in-out;
transition-property: background-color, border-color, opacity;
z-index: $lnsZLevel1;
z-index: $domDragDropZLevel1;
}
.lnsDragDrop_ghost {
@include lnsDraggable;
.domDragDrop_ghost {
@include mixinDomDraggable;
border: $euiBorderWidthThin dashed $euiBorderColor;
position: absolute !important; // sass-lint:disable-line no-important
margin: 0 !important; // sass-lint:disable-line no-important
@ -18,16 +17,16 @@
left: 0;
opacity: .9;
transform: translate(-12px, 8px);
z-index: $lnsZLevel3;
z-index: $domDragDropZLevel3;
pointer-events: none;
outline: $euiFocusRingSize solid currentColor; // Safari & Firefox
outline-style: auto; // Chrome
}
// Draggable item
.lnsDragDrop-isDraggable {
@include lnsDraggable;
@include lnsDragDropHover;
.domDragDrop-isDraggable {
@include mixinDomDraggable;
@include mixinDomDragDropHover;
// Include a possible nested button like when using FieldButton
> .kbnFieldButton__button {
@ -40,90 +39,88 @@
}
// Drop area
.lnsDragDrop-isDroppable {
@include lnsDroppable;
.domDragDrop-isDroppable {
@include mixinDomDroppable;
}
// Drop area when there's an item being dragged
.lnsDragDrop-isDropTarget {
@include lnsDroppable;
@include lnsDroppableActive;
.domDragDrop-isDropTarget {
@include mixinDomDroppable;
@include mixinDomDroppableActive;
> * {
pointer-events: none;
}
}
.lnsDragDrop-isActiveGroup {
.domDragDrop-isActiveGroup {
background-color: transparentize($euiColorVis0, .75);
}
// Drop area while hovering with item
.lnsDragDrop-isActiveDropTarget {
z-index: $lnsZLevel3;
@include lnsDroppableActiveHover;
.domDragDrop-isActiveDropTarget {
z-index: $domDragDropZLevel3;
@include mixinDomDroppableActiveHover;
}
// Drop area that is not allowed for current item
.lnsDragDrop-isNotDroppable {
@include lnsDroppableNotAllowed;
.domDragDrop-isNotDroppable {
@include mixinDomDroppableNotAllowed;
}
// Drop area will be replacing existing content
.lnsDragDrop-isReplacing {
&,
.lnsLayerPanel__triggerText {
text-decoration: line-through;
.domDragDrop-isReplacing {
text-decoration: line-through;
}
.domDragDrop-notCompatible {
background-color: $euiColorHighlight !important;
border: $euiBorderWidthThin dashed $euiBorderColor !important;
&.domDragDrop-isActiveDropTarget {
background-color: rgba(251, 208, 17, .25) !important;
border-color: $euiColorVis5 !important;
}
}
.lnsDragDrop-notCompatible {
background-color: $euiColorHighlight;
border: $euiBorderWidthThin dashed $euiBorderColor;
&.lnsDragDrop-isActiveDropTarget {
background-color: rgba(251, 208, 17, .25);
border-color: $euiColorVis5;
}
}
.lnsDragDrop__container {
.domDragDrop__container {
position: relative;
width: 100%;
height: 100%;
&.lnsDragDrop__container-active {
z-index: $lnsZLevel3;
&.domDragDrop__container-active {
z-index: $domDragDropZLevel3;
}
}
.lnsDragDrop__reorderableDrop {
$lnsLayerPanelDimensionMargin: 8px;
.domDragDrop__reorderableDrop {
position: absolute;
width: 100%;
top: 0;
height: calc(100% + #{$lnsLayerPanelDimensionMargin});
}
.lnsDragDrop-translatableDrop {
.domDragDrop-translatableDrop {
transform: translateY(0);
transition: transform $euiAnimSpeedFast ease-in-out;
pointer-events: none;
.lnsDragDrop-isDropTarget {
@include lnsDraggable;
.domDragDrop-isDropTarget {
@include mixinDomDraggable;
}
.lnsDragDrop-isActiveDropTarget {
z-index: $lnsZLevel3;
.domDragDrop-isActiveDropTarget {
z-index: $domDragDropZLevel3;
}
}
.lnsDragDrop-translatableDrag {
.domDragDrop-translatableDrag {
transform: translateY(0);
transition: transform $euiAnimSpeedFast ease-in-out;
position: relative;
z-index: $lnsZLevel1;
z-index: $domDragDropZLevel1;
}
.lnsDragDrop__keyboardHandler {
.domDragDrop__keyboardHandler {
top: 0;
position: absolute;
width: 100%;
@ -134,14 +131,14 @@
&:focus-within {
@include euiFocusRing;
pointer-events: none;
z-index: $lnsZLevel2;
z-index: $domDragDropZLevel2;
}
}
// Draggable item when it is moving
.lnsDragDrop-isHidden {
.domDragDrop-isHidden {
opacity: 0;
.lnsDragDrop__keyboardHandler {
.domDragDrop__keyboardHandler {
&:focus,
&:focus-within {
animation: none;
@ -149,59 +146,58 @@
}
}
.lnsDragDrop__extraDrops {
.domDragDrop__extraDrops {
opacity: 0;
visibility: hidden;
position: absolute;
z-index: $lnsZLevel2;
z-index: $domDragDropZLevel2;
right: calc(100% + #{$euiSizeS});
top: 0;
transition: opacity $euiAnimSpeedFast ease-in-out;
width:100%;
}
.lnsDragDrop__extraDrops-visible {
.domDragDrop__extraDrops-visible {
opacity: 1;
visibility: visible;
}
.lnsDragDrop__diamondPath {
.domDragDrop__diamondPath {
position: absolute;
width: 30%;
top: 0;
left: -$euiSize;
z-index: $lnsZLevel0;
z-index: $domDragDropZLevel0;
}
.lnsDragDrop__extraDropWrapper {
.domDragDrop__extraDropWrapper {
position: relative;
width: 100%;
height: 100%;
background: $euiColorLightestShade;
padding: $euiSizeXS;
border-radius: 0;
&:first-child, &:first-child .lnsDragDrop__extraDrop {
&:first-child, &:first-child .domDragDrop__extraDrop {
border-top-left-radius: $euiSizeXS;
border-top-right-radius: $euiSizeXS;
}
&:last-child, &:last-child .lnsDragDrop__extraDrop {
&:last-child, &:last-child .domDragDrop__extraDrop {
border-bottom-left-radius: $euiSizeXS;
border-bottom-right-radius: $euiSizeXS;
}
}
// collapse borders
.lnsDragDrop__extraDropWrapper + .lnsDragDrop__extraDropWrapper {
.domDragDrop__extraDropWrapper + .domDragDrop__extraDropWrapper {
margin-top: -1px;
}
.lnsDragDrop__extraDrop {
.domDragDrop__extraDrop {
position: relative;
height: $euiSizeXS * 10;
min-width: $euiSize * 7;
color: $euiColorSuccessText;
padding: $euiSizeXS;
&.lnsDragDrop-incompatibleExtraDrop {
&.domDragDrop-incompatibleExtraDrop {
color: $euiColorWarningText;
}
}

View file

@ -0,0 +1,46 @@
// from variables:
$domDragDropZLevel0: 0;
$domDragDropZLevel1: 1;
$domDragDropZLevel2: 2;
$domDragDropZLevel3: 3;
// from mixins
// sass-lint:disable-block indentation, no-color-keywords
// Static styles for a draggable item
@mixin mixinDomDraggable {
@include euiSlightShadow;
background: $euiColorEmptyShade;
border: $euiBorderWidthThin dashed transparent;
cursor: grab;
}
// Static styles for a drop area
@mixin mixinDomDroppable {
border: $euiBorderWidthThin dashed $euiBorderColor !important;
}
// Hovering state for drag item and drop area
@mixin mixinDomDragDropHover {
&:hover {
border: $euiBorderWidthThin dashed $euiColorMediumShade !important;
}
}
// Style for drop area when there's an item being dragged
@mixin mixinDomDroppableActive {
background-color: transparentize($euiColorVis0, .9) !important;
}
// Style for drop area while hovering with item
@mixin mixinDomDroppableActiveHover {
background-color: transparentize($euiColorVis0, .75) !important;
border: $euiBorderWidthThin dashed $euiColorVis0 !important;
}
// Style for drop area that is not allowed for current item
@mixin mixinDomDroppableNotAllowed {
opacity: .5;
}

View file

@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
/**
* Types of drop action
*/
export type DropType =
| 'field_add'
| 'field_replace'
| 'reorder'
| 'move_compatible'
| 'replace_compatible'
| 'move_incompatible'
| 'replace_incompatible'
| 'replace_duplicate_compatible'
| 'duplicate_compatible'
| 'swap_compatible'
| 'replace_duplicate_incompatible'
| 'duplicate_incompatible'
| 'swap_incompatible'
| 'field_combine'
| 'combine_compatible'
| 'combine_incompatible';

View file

@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "target/types"
},
"include": ["*.ts", "src/**/*"],
"kbn_references": [
"@kbn/i18n",
],
"exclude": ["target/**/*"]
}

View file

@ -0,0 +1,53 @@
// Removes EUI focus ring
@mixin removeEuiFocusRing {
outline: none;
&:focus-visible {
outline-style: none;
}
}
// Passes focus ring styles down to a child of a focused element
@mixin passDownFocusRing($target) {
@include removeEuiFocusRing;
#{$target} {
outline: $euiFocusRingSize solid currentColor; // Safari & Firefox
}
&:focus-visible #{$target} {
outline-style: auto; // Chrome
}
&:not(:focus-visible) #{$target} {
outline: none;
}
}
.unifiedFieldItemButton {
width: 100%;
&:hover:not([class*='isActive']) {
cursor: grab;
}
&.kbnFieldButton {
&:focus-within,
&-isActive {
@include removeEuiFocusRing;
}
}
.kbnFieldButton__button:focus {
@include passDownFocusRing('.kbnFieldButton__name > span');
.kbnFieldButton__name > span {
text-decoration: underline;
}
}
}
.unifiedFieldItemButton--missing {
background: lightOrDarkTheme(transparentize($euiColorMediumShade, .9), $euiColorEmptyShade);
color: $euiColorDarkShade;
}

View file

@ -0,0 +1,98 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import React from 'react';
import { i18n } from '@kbn/i18n';
import classnames from 'classnames';
import { FieldButton, type FieldButtonProps } from '@kbn/react-field';
import { EuiHighlight } from '@elastic/eui';
import type { DataViewField } from '@kbn/data-views-plugin/common';
import { type FieldListItem, type GetCustomFieldType } from '../../types';
import { wrapFieldNameOnDot } from '../../utils/wrap_field_name_on_dot';
import { FieldIcon, getFieldIconProps } from '../field_icon';
import './field_item_button.scss';
/**
* Props of FieldItemButton component
*/
export interface FieldItemButtonProps<T extends FieldListItem> {
field: T;
fieldSearchHighlight?: string;
isActive?: FieldButtonProps['isActive'];
isEmpty?: boolean; // whether the field has data or not
infoIcon?: FieldButtonProps['fieldInfoIcon'];
className?: FieldButtonProps['className'];
getCustomFieldType?: GetCustomFieldType<T>;
onClick: FieldButtonProps['onClick'];
}
/**
* Inner part of field list item
* @param field
* @param fieldSearchHighlight
* @param isActive
* @param isEmpty
* @param infoIcon
* @param className
* @param getCustomFieldType
* @param onClick
* @param otherProps
* @constructor
*/
export function FieldItemButton<T extends FieldListItem = DataViewField>({
field,
fieldSearchHighlight,
isActive,
isEmpty,
infoIcon,
className,
getCustomFieldType,
onClick,
...otherProps
}: FieldItemButtonProps<T>) {
const displayName = field.displayName || field.name;
const iconProps = getCustomFieldType
? { type: getCustomFieldType(field) }
: getFieldIconProps(field);
const type = iconProps.type;
const classes = classnames(
'unifiedFieldItemButton',
{
[`unifiedFieldItemButton--${type}`]: type,
[`unifiedFieldItemButton--exists`]: !isEmpty,
[`unifiedFieldItemButton--missing`]: isEmpty,
},
className
);
return (
<FieldButton
className={classes}
isActive={isActive}
buttonProps={{
['aria-label']: i18n.translate('unifiedFieldList.fieldItemButtonAriaLabel', {
defaultMessage: 'Preview {fieldName}: {fieldType}',
values: {
fieldName: displayName,
fieldType: getCustomFieldType ? getCustomFieldType(field) : field.type,
},
}),
}}
fieldIcon={<FieldIcon {...iconProps} />}
fieldName={
<EuiHighlight search={wrapFieldNameOnDot(fieldSearchHighlight)}>
{wrapFieldNameOnDot(displayName)}
</EuiHighlight>
}
fieldInfoIcon={infoIcon}
onClick={onClick}
{...otherProps}
/>
);
}

View file

@ -0,0 +1,9 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { FieldItemButton, type FieldItemButtonProps } from './field_item_button';

View file

@ -17,6 +17,7 @@ export { FieldList, type FieldListProps } from './components/field_list';
export { FieldListGrouped, type FieldListGroupedProps } from './components/field_list_grouped';
export { FieldListFilters, type FieldListFiltersProps } from './components/field_list_filters';
export { FieldIcon, type FieldIconProps, getFieldIconProps } from './components/field_icon';
export { FieldItemButton, type FieldItemButtonProps } from './components/field_item_button';
export type {
FieldTopValuesBucketProps,
FieldTopValuesBucketParams,

View file

@ -618,6 +618,8 @@
"@kbn/doc-links/*": ["packages/kbn-doc-links/*"],
"@kbn/docs-utils": ["packages/kbn-docs-utils"],
"@kbn/docs-utils/*": ["packages/kbn-docs-utils/*"],
"@kbn/dom-drag-drop": ["packages/kbn-dom-drag-drop"],
"@kbn/dom-drag-drop/*": ["packages/kbn-dom-drag-drop/*"],
"@kbn/ebt-tools": ["packages/kbn-ebt-tools"],
"@kbn/ebt-tools/*": ["packages/kbn-ebt-tools/*"],
"@kbn/ecs": ["packages/kbn-ecs"],

View file

@ -12,42 +12,6 @@
);
}
// Static styles for a draggable item
@mixin lnsDraggable {
@include euiSlightShadow;
background: $euiColorEmptyShade;
border: $euiBorderWidthThin dashed transparent;
cursor: grab;
}
// Static styles for a drop area
@mixin lnsDroppable {
border: $euiBorderWidthThin dashed $euiBorderColor;
}
// Hovering state for drag item and drop area
@mixin lnsDragDropHover {
&:hover {
border: $euiBorderWidthThin dashed $euiColorMediumShade;
}
}
// Style for drop area when there's an item being dragged
@mixin lnsDroppableActive {
background-color: transparentize($euiColorVis0, .9);
}
// Style for drop area while hovering with item
@mixin lnsDroppableActiveHover {
background-color: transparentize($euiColorVis0, .75);
border: $euiBorderWidthThin dashed $euiColorVis0;
}
// Style for drop area that is not allowed for current item
@mixin lnsDroppableNotAllowed {
opacity: .5;
}
// Removes EUI focus ring
@mixin removeEuiFocusRing {
outline: none;
@ -103,4 +67,4 @@
opacity: 1;
transform: translateX(0%);
}
}
}

View file

@ -3,9 +3,8 @@ $lnsPanelMinWidth: $euiSize * 18;
// These sizes also match canvas' page thumbnails for consistency
$lnsSuggestionHeight: 100px;
$lnsSuggestionWidth: 150px;
$lnsLayerPanelDimensionMargin: 8px;
$lnsZLevel0: 0;
$lnsZLevel1: 1;
$lnsZLevel2: 2;
$lnsZLevel3: 3;
$lnsZLevel3: 3;

View file

@ -27,6 +27,7 @@ import {
useExistingFieldsFetcher,
useGroupedFields,
} from '@kbn/unified-field-list-plugin/public';
import { ChildDragDropProvider, DragContextState } from '@kbn/dom-drag-drop';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
import type {
DatasourceDataPanelProps,
@ -34,7 +35,6 @@ import type {
IndexPattern,
IndexPatternField,
} from '../../types';
import { ChildDragDropProvider, DragContextState } from '../../drag_drop';
import type { FormBasedPrivateState } from './types';
import { IndexPatternServiceAPI } from '../../data_views_service/service';
import { FieldItem } from './field_item';

View file

@ -5,9 +5,9 @@
* 2.0.
*/
import { DragContextState, DropType } from '@kbn/dom-drag-drop';
import {
isOperation,
DropType,
DragDropOperation,
IndexPattern,
IndexPatternMap,
@ -20,7 +20,6 @@ import {
} from '../../operations';
import { isDraggedDataViewField, isOperationFromTheSameGroup } from '../../../../utils';
import { hasField } from '../../pure_utils';
import { DragContextState } from '../../../../drag_drop/providers';
import { OperationMetadata, DraggedField } from '../../../../types';
import { getOperationTypesForField } from '../../operations';
import { GenericIndexPatternColumn } from '../../form_based';

View file

@ -5,13 +5,10 @@
* 2.0.
*/
import { DropType } from '@kbn/dom-drag-drop';
import { onDrop } from './on_drop_handler';
import { FormBasedPrivateState } from '../../types';
import {
OperationMetadata,
DropType,
DatasourceDimensionDropHandlerProps,
} from '../../../../types';
import { OperationMetadata, DatasourceDimensionDropHandlerProps } from '../../../../types';
import { FormulaIndexPatternColumn, MedianIndexPatternColumn } from '../../operations';
import { generateId } from '../../../../id_generator';
import {

View file

@ -4,11 +4,11 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { DropType } from '@kbn/dom-drag-drop';
import { isDraggedDataViewField } from '../../../../utils';
import {
DatasourceDimensionDropHandlerProps,
DragDropOperation,
DropType,
IndexPatternMap,
isOperation,
StateSetter,

View file

@ -1,31 +1,10 @@
@import '../../mixins';
.lnsFieldItem {
width: 100%;
&.kbnFieldButton {
&:focus-within,
&-isActive {
@include removeEuiFocusRing;
}
}
.kbnFieldButton__button:focus {
@include passDownFocusRing('.kbnFieldButton__name > span');
.kbnFieldButton__name > span {
text-decoration: underline;
}
}
.kbnFieldButton {
.lnsFieldItem__infoIcon {
visibility: hidden;
opacity: 0;
}
&:hover:not([class*='isActive']) {
cursor: grab;
.lnsFieldItem__infoIcon {
visibility: visible;
opacity: 1;
@ -34,22 +13,13 @@
}
}
.kbnFieldButton.lnsDragDrop_ghost {
.kbnFieldButton.domDragDrop_ghost {
.lnsFieldItem__infoIcon {
visibility: hidden;
opacity: 0;
}
}
.kbnFieldButton__name {
transition: background-color $euiAnimSpeedFast ease-in-out;
}
.lnsFieldItem--missing {
background: lightOrDarkTheme(transparentize($euiColorMediumShade, .9), $euiColorEmptyShade);
color: $euiColorDarkShade;
}
.lnsFieldItem__fieldPanel {
min-width: 260px;
max-width: 300px;

View file

@ -8,12 +8,10 @@
import './field_item.scss';
import React, { useCallback, useState, useMemo } from 'react';
import { EuiIconTip, EuiText, EuiButton, EuiPopoverFooter } from '@elastic/eui';
import { EuiText, EuiButton, EuiPopoverFooter, EuiIconTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { FieldButton } from '@kbn/react-field';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import { EuiHighlight } from '@elastic/eui';
import { Filter, Query } from '@kbn/es-query';
import { DataViewField, type DataView } from '@kbn/data-views-plugin/common';
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
@ -24,12 +22,10 @@ import {
FieldPopover,
FieldPopoverHeader,
FieldPopoverVisualize,
FieldIcon,
getFieldIconProps,
wrapFieldNameOnDot,
FieldItemButton,
} from '@kbn/unified-field-list-plugin/public';
import { DragDrop } from '@kbn/dom-drag-drop';
import { generateFilters, getEsQueryConfig } from '@kbn/data-plugin/public';
import { DragDrop } from '../../drag_drop';
import { DatasourceDataPanelProps } from '../../types';
import { DOCUMENT_FIELD_NAME } from '../../../common';
import type { IndexPattern, IndexPatternField } from '../../types';
@ -150,7 +146,6 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) {
const order = useMemo(() => [0, groupIndex, itemIndex], [groupIndex, itemIndex]);
const lensFieldIcon = <FieldIcon {...getFieldIconProps(field)} />;
const lensInfoIcon = (
<EuiIconTip
anchorClassName="lnsFieldItem__infoIcon"
@ -195,31 +190,13 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) {
dataTestSubj={`lnsFieldListPanelField-${field.name}`}
onDragStart={onDragStart}
>
<FieldButton
className={`lnsFieldItem lnsFieldItem--${field.type} lnsFieldItem--${
exists ? 'exists' : 'missing'
}`}
<FieldItemButton<IndexPatternField>
isEmpty={!exists}
isActive={infoIsOpen}
infoIcon={lensInfoIcon}
field={field}
fieldSearchHighlight={highlight}
onClick={togglePopover}
buttonProps={{
['aria-label']: i18n.translate(
'xpack.lens.indexPattern.fieldStatsButtonAriaLabel',
{
defaultMessage: 'Preview {fieldName}: {fieldType}',
values: {
fieldName: field.displayName,
fieldType: field.type,
},
}
),
}}
fieldIcon={lensFieldIcon}
fieldName={
<EuiHighlight search={wrapFieldNameOnDot(highlight)}>
{wrapFieldNameOnDot(field.displayName)}
</EuiHighlight>
}
fieldInfoIcon={lensInfoIcon}
/>
</DragDrop>
}

View file

@ -25,6 +25,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import { EuiButton } from '@elastic/eui';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { DraggingIdentifier } from '@kbn/dom-drag-drop';
import type {
DatasourceDimensionEditorProps,
DatasourceDimensionTriggerProps,
@ -92,7 +93,6 @@ import { mergeLayer, mergeLayers } from './state_helpers';
import type { Datasource, VisualizeEditorContext } from '../../types';
import { deleteColumn, isReferenced } from './operations';
import { GeoFieldWorkspacePanel } from '../../editor_frame_service/editor_frame/workspace_panel/geo_field_workspace_panel';
import type { DraggingIdentifier } from '../../drag_drop';
import { getStateTimeShiftWarningMessages } from './time_shift_utils';
import { getPrecisionErrorWarningMessages } from './utils';
import { DOCUMENT_FIELD_NAME } from '../../../common/constants';

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { DragContextState } from '../../drag_drop';
import { DragContextState } from '@kbn/dom-drag-drop';
import { getFieldByNameFactory } from './pure_helpers';
import type { IndexPattern, IndexPatternField } from '../../types';
@ -216,6 +216,7 @@ export const createMockedIndexPatternWithoutType = (
export function createMockedDragDropContext(): jest.Mocked<DragContextState> {
return {
dataTestSubjPrefix: 'lnsDragDrop',
dragging: undefined,
setDragging: jest.fn(),
activeDropTarget: undefined,

View file

@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { DragDropIdentifier } from '../../drag_drop/providers';
import type { DragDropIdentifier } from '@kbn/dom-drag-drop';
import type { IncompleteColumn, GenericIndexPatternColumn } from './operations';
import type { IndexPattern, IndexPatternField, DragDropOperation } from '../../types';

View file

@ -6,7 +6,6 @@
*/
import React, { useCallback, useEffect, useState } from 'react';
import { EuiHighlight } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import usePrevious from 'react-use/lib/usePrevious';
import { isEqual } from 'lodash';
@ -19,19 +18,17 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import {
FieldList,
FieldListFilters,
FieldIcon,
FieldItemButton,
GetCustomFieldType,
wrapFieldNameOnDot,
FieldListGrouped,
FieldListGroupedProps,
FieldsGroupNames,
useGroupedFields,
} from '@kbn/unified-field-list-plugin/public';
import { FieldButton } from '@kbn/react-field';
import { ChildDragDropProvider, DragDrop } from '@kbn/dom-drag-drop';
import type { DatasourceDataPanelProps } from '../../types';
import type { TextBasedPrivateState } from './types';
import { getStateFromAggregateQuery } from './utils';
import { ChildDragDropProvider, DragDrop } from '../../drag_drop';
const getCustomFieldType: GetCustomFieldType<DatatableColumn> = (field) => field?.meta.type;
@ -126,16 +123,13 @@ export function TextBasedDataPanel({
}}
dataTestSubj={`lnsFieldListPanelField-${field.name}`}
>
<FieldButton
className={`lnsFieldItem lnsFieldItem--${field.meta.type}`}
<FieldItemButton<DatatableColumn>
isEmpty={false}
isActive={false}
field={field}
fieldSearchHighlight={fieldSearchHighlight}
getCustomFieldType={getCustomFieldType}
onClick={() => {}}
fieldIcon={<FieldIcon type={getCustomFieldType(field)} />}
fieldName={
<EuiHighlight search={wrapFieldNameOnDot(fieldSearchHighlight)}>
{wrapFieldNameOnDot(field.name)}
</EuiHighlight>
}
/>
</DragDrop>
);

View file

@ -5,10 +5,11 @@
* 2.0.
*/
import { DragContextState } from '../../drag_drop';
import { DragContextState } from '@kbn/dom-drag-drop';
export function createMockedDragDropContext(): jest.Mocked<DragContextState> {
return {
dataTestSubjPrefix: 'lnsDragDrop',
dragging: undefined,
setDragging: jest.fn(),
activeDropTarget: undefined,

View file

@ -6,23 +6,23 @@
*/
import React, { useMemo, useCallback, useContext, ReactElement } from 'react';
import {
DragDrop,
DragDropIdentifier,
DragContext,
DropType,
DropTargetSwapDuplicateCombine,
} from '@kbn/dom-drag-drop';
import { isDraggedField } from '../../../../utils';
import { DragDrop, DragDropIdentifier, DragContext } from '../../../../drag_drop';
import {
Datasource,
VisualizationDimensionGroupConfig,
isOperation,
DropType,
DatasourceLayers,
IndexPatternMap,
DragDropOperation,
Visualization,
} from '../../../../types';
import {
getCustomDropTarget,
getAdditionalClassesOnDroppable,
getAdditionalClassesOnEnter,
} from './drop_targets_utils';
export function DraggableDimensionButton({
order,
@ -139,9 +139,11 @@ export function DraggableDimensionButton({
data-test-subj={group.dataTestSubj}
>
<DragDrop
getCustomDropTarget={getCustomDropTarget}
getAdditionalClassesOnEnter={getAdditionalClassesOnEnter}
getAdditionalClassesOnDroppable={getAdditionalClassesOnDroppable}
getCustomDropTarget={DropTargetSwapDuplicateCombine.getCustomDropTarget}
getAdditionalClassesOnEnter={DropTargetSwapDuplicateCombine.getAdditionalClassesOnEnter}
getAdditionalClassesOnDroppable={
DropTargetSwapDuplicateCombine.getAdditionalClassesOnDroppable
}
order={order}
draggable
dragType={isOperation(dragging) ? 'move' : 'copy'}

View file

@ -5,13 +5,8 @@
* 2.0.
*/
import React from 'react';
import classNames from 'classnames';
import { EuiIcon, EuiFlexItem, EuiFlexGroup, EuiText } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { DragDropIdentifier } from '../../../../drag_drop';
import { DragDropIdentifier, DropType } from '@kbn/dom-drag-drop';
import {
DropType,
FramePublicAPI,
isOperation,
Visualization,
@ -19,125 +14,6 @@ import {
VisualizationDimensionGroupConfig,
} from '../../../../types';
function getPropsForDropType(type: 'swap' | 'duplicate' | 'combine') {
switch (type) {
case 'duplicate':
return {
icon: 'copy',
label: i18n.translate('xpack.lens.dragDrop.duplicate', {
defaultMessage: 'Duplicate',
}),
controlKey: i18n.translate('xpack.lens.dragDrop.altOption', {
defaultMessage: 'Alt/Option',
}),
};
case 'swap':
return {
icon: 'merge',
label: i18n.translate('xpack.lens.dragDrop.swap', {
defaultMessage: 'Swap',
}),
controlKey: i18n.translate('xpack.lens.dragDrop.shift', {
defaultMessage: 'Shift',
}),
};
case 'combine':
return {
icon: 'aggregate',
label: i18n.translate('xpack.lens.dragDrop.combine', {
defaultMessage: 'Combine',
}),
controlKey: i18n.translate('xpack.lens.dragDrop.control', {
defaultMessage: 'Control',
}),
};
default:
throw Error('Drop type not supported');
}
}
const getExtraDrop = ({
type,
isIncompatible,
}: {
type: 'swap' | 'duplicate' | 'combine';
isIncompatible?: boolean;
}) => {
const { icon, label, controlKey } = getPropsForDropType(type);
return (
<EuiFlexGroup
gutterSize="s"
justifyContent="spaceBetween"
alignItems="center"
className={classNames('lnsDragDrop__extraDrop', {
'lnsDragDrop-incompatibleExtraDrop': isIncompatible,
})}
>
<EuiFlexItem grow={false}>
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
<EuiIcon size="m" type={icon} />
</EuiFlexItem>
<EuiFlexItem grow={false} data-test-subj={`lnsDragDrop-${type}`}>
<EuiText size="s">{label}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText size="xs">
<code> {controlKey}</code>
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
);
};
const customDropTargetsMap: Partial<{ [dropType in DropType]: React.ReactElement }> = {
replace_duplicate_incompatible: getExtraDrop({ type: 'duplicate', isIncompatible: true }),
duplicate_incompatible: getExtraDrop({ type: 'duplicate', isIncompatible: true }),
swap_incompatible: getExtraDrop({ type: 'swap', isIncompatible: true }),
replace_duplicate_compatible: getExtraDrop({ type: 'duplicate' }),
duplicate_compatible: getExtraDrop({ type: 'duplicate' }),
swap_compatible: getExtraDrop({ type: 'swap' }),
field_combine: getExtraDrop({ type: 'combine' }),
combine_compatible: getExtraDrop({ type: 'combine' }),
combine_incompatible: getExtraDrop({ type: 'combine', isIncompatible: true }),
};
export const getCustomDropTarget = (dropType: DropType) => customDropTargetsMap?.[dropType] || null;
export const getAdditionalClassesOnEnter = (dropType?: string) => {
if (
dropType &&
[
'field_replace',
'replace_compatible',
'replace_incompatible',
'replace_duplicate_compatible',
'replace_duplicate_incompatible',
].includes(dropType)
) {
return 'lnsDragDrop-isReplacing';
}
};
export const getAdditionalClassesOnDroppable = (dropType?: string) => {
if (
dropType &&
[
'move_incompatible',
'replace_incompatible',
'swap_incompatible',
'duplicate_incompatible',
'replace_duplicate_incompatible',
'combine_incompatible',
].includes(dropType)
) {
return 'lnsDragDrop-notCompatible';
}
};
export interface OnVisDropProps<T> {
prevState: T;
target: DragDropOperation;

View file

@ -9,21 +9,25 @@ import React, { useMemo, useState, useEffect, useContext } from 'react';
import { EuiButtonEmpty } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import {
DragDrop,
DragDropIdentifier,
DragContext,
DropType,
DropTargetSwapDuplicateCombine,
} from '@kbn/dom-drag-drop';
import { isDraggedField } from '../../../../utils';
import { generateId } from '../../../../id_generator';
import { DragDrop, DragDropIdentifier, DragContext } from '../../../../drag_drop';
import {
Datasource,
VisualizationDimensionGroupConfig,
DropType,
DatasourceLayers,
isOperation,
IndexPatternMap,
DragDropOperation,
Visualization,
} from '../../../../types';
import { getCustomDropTarget, getAdditionalClassesOnDroppable } from './drop_targets_utils';
interface EmptyButtonProps {
columnId: string;
@ -192,12 +196,14 @@ export function EmptyDimensionButton({
return (
<div className="lnsLayerPanel__dimensionContainer" data-test-subj={group.dataTestSubj}>
<DragDrop
getAdditionalClassesOnDroppable={getAdditionalClassesOnDroppable}
getCustomDropTarget={DropTargetSwapDuplicateCombine.getCustomDropTarget}
getAdditionalClassesOnDroppable={
DropTargetSwapDuplicateCombine.getAdditionalClassesOnDroppable
}
value={value}
order={order}
onDrop={handleOnDrop}
dropTypes={dropTypes}
getCustomDropTarget={getCustomDropTarget}
>
<div className="lnsLayerPanel__dimension lnsLayerPanel__dimension--empty">
{typeof group.suggestedValue?.() === 'number' ? (

View file

@ -106,6 +106,12 @@
font-weight: $euiFontWeightRegular;
}
.domDragDrop-isReplacing {
.lnsLayerPanel__triggerText {
text-decoration: line-through;
}
}
.lnsLayerPanel__triggerTextLabel {
transition: background-color $euiAnimSpeedFast ease-in-out;
}
@ -148,4 +154,4 @@
@include passDownFocusRing('.lnsLayerPanel__triggerTextLabel');
background-color: transparent;
}
}
}

View file

@ -8,9 +8,9 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { EuiFormRow } from '@elastic/eui';
import { ChildDragDropProvider, DragDrop } from '@kbn/dom-drag-drop';
import { FramePublicAPI, Visualization, VisualizationConfigProps } from '../../../types';
import { LayerPanel } from './layer_panel';
import { ChildDragDropProvider, DragDrop } from '../../../drag_drop';
import { coreMock } from '@kbn/core/public/mocks';
import { generateId } from '../../../id_generator';
import {
@ -51,6 +51,7 @@ afterEach(() => {
});
const defaultContext = {
dataTestSubjPrefix: 'lnsDragDrop',
dragging: undefined,
setDragging: jest.fn(),
setActiveDropTarget: () => {},
@ -775,7 +776,7 @@ describe('LayerPanel', () => {
);
const dragDropElement = instance
.find('[data-test-subj="lnsGroup"] DragDrop .lnsDragDrop')
.find('[data-test-subj="lnsGroup"] DragDrop .domDragDrop')
.first();
dragDropElement.simulate('dragOver');
@ -889,7 +890,7 @@ describe('LayerPanel', () => {
// Simulate drop on the pre-populated dimension
const dragDropElement = instance
.find('[data-test-subj="lnsGroupB"] DragDrop .lnsDragDrop')
.find('[data-test-subj="lnsGroupB"] DragDrop .domDragDrop')
.at(0);
dragDropElement.simulate('dragOver');
dragDropElement.simulate('drop');
@ -904,7 +905,7 @@ describe('LayerPanel', () => {
// Simulate drop on the empty dimension
const updatedDragDropElement = instance
.find('[data-test-subj="lnsGroupB"] DragDrop .lnsDragDrop')
.find('[data-test-subj="lnsGroupB"] DragDrop .domDragDrop')
.at(2);
updatedDragDropElement.simulate('dragOver');

View file

@ -20,6 +20,7 @@ import {
import { i18n } from '@kbn/i18n';
import { css } from '@emotion/react';
import { euiThemeVars } from '@kbn/ui-theme';
import { DragDropIdentifier, ReorderProvider, DropType } from '@kbn/dom-drag-drop';
import { LayerType } from '../../../../common';
import { LayerActions } from './layer_actions';
import { IndexPatternServiceAPI } from '../../../data_views_service/service';
@ -28,13 +29,11 @@ import {
StateSetter,
Visualization,
DragDropOperation,
DropType,
isOperation,
LayerAction,
VisualizationDimensionGroupConfig,
UserMessagesGetter,
} from '../../../types';
import { DragDropIdentifier, ReorderProvider } from '../../../drag_drop';
import { LayerSettings } from './layer_settings';
import { LayerPanelProps, ActiveDimensionState } from './types';
import { DimensionContainer } from './dimension_container';
@ -508,7 +507,11 @@ export function LayerPanel(
>
<>
{group.accessors.length ? (
<ReorderProvider id={group.groupId} className={'lnsLayerPanel__group'}>
<ReorderProvider
id={group.groupId}
className={'lnsLayerPanel__group'}
dataTestSubj="lnsDragDrop"
>
{group.accessors.map((accessorConfig, accessorIndex) => {
const { columnId } = accessorConfig;
@ -599,7 +602,7 @@ export function LayerPanel(
{group.fakeFinalAccessor && (
<div
className="lnsLayerPanel__dimension lnsDragDrop-isDraggable"
className="lnsLayerPanel__dimension domDragDrop-isDraggable"
css={css`
cursor: default !important;
border-color: transparent !important;

View file

@ -6,9 +6,9 @@
*/
import React from 'react';
import { DragDropIdentifier } from '@kbn/dom-drag-drop';
import { DataPanelWrapper } from './data_panel_wrapper';
import { Datasource, DatasourceDataPanelProps, VisualizationMap } from '../../types';
import { DragDropIdentifier } from '../../drag_drop';
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { createMockFramePublicAPI, mockStoreDeps, mountWithProvider } from '../../mocks';
import { disableAutoApply } from '../../state_management/lens_slice';

View file

@ -11,9 +11,9 @@ import React, { useMemo, memo, useContext, useEffect, useCallback } from 'react'
import { Storage } from '@kbn/kibana-utils-plugin/public';
import { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import { DragContext, DragDropIdentifier } from '@kbn/dom-drag-drop';
import { Easteregg } from './easteregg';
import { NativeRenderer } from '../../native_renderer';
import { DragContext, DragDropIdentifier } from '../../drag_drop';
import {
StateSetter,
DatasourceDataPanelProps,

View file

@ -41,7 +41,7 @@ import {
} from '../../mocks';
import { inspectorPluginMock } from '@kbn/inspector-plugin/public/mocks';
import { ReactExpressionRendererType } from '@kbn/expressions-plugin/public';
import { DragDrop } from '../../drag_drop';
import { DragDrop } from '@kbn/dom-drag-drop';
import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks';
import { chartPluginMock } from '@kbn/charts-plugin/public/mocks';
import { expressionsPluginMock } from '@kbn/expressions-plugin/public/mocks';

View file

@ -8,6 +8,7 @@
import React, { useCallback, useRef } from 'react';
import { CoreStart } from '@kbn/core/public';
import { ReactExpressionRendererType } from '@kbn/expressions-plugin/public';
import { DragDropIdentifier, RootDragDropProvider } from '@kbn/dom-drag-drop';
import { trackUiCounterEvents } from '../../lens_ui_telemetry';
import {
DatasourceMap,
@ -23,7 +24,6 @@ import { ConfigPanelWrapper } from './config_panel';
import { FrameLayout } from './frame_layout';
import { SuggestionPanelWrapper } from './suggestion_panel';
import { WorkspacePanel } from './workspace_panel';
import { DragDropIdentifier, RootDragDropProvider } from '../../drag_drop';
import { EditorFrameStartPlugins } from '../service';
import { getTopSuggestionForField, switchToSuggestion } from './suggestion_helpers';
import {
@ -108,7 +108,7 @@ export function EditorFrame(props: EditorFrameProps) {
const bannerMessages = props.getUserMessages('banner', { severity: 'warning' });
return (
<RootDragDropProvider>
<RootDragDropProvider dataTestSubj="lnsDragDrop" onTrackUICounterEvent={trackUiCounterEvents}>
<FrameLayout
bannerMessages={
bannerMessages.length ? (

View file

@ -9,6 +9,7 @@ import type { Datatable } from '@kbn/expressions-plugin/common';
import type { PaletteOutput } from '@kbn/coloring';
import type { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public';
import { LayerTypes } from '@kbn/expression-xy-plugin/public';
import type { DragDropIdentifier } from '@kbn/dom-drag-drop';
import { showMemoizedErrorNotification } from '../../lens_ui_errors';
import type {
Visualization,
@ -21,7 +22,6 @@ import type {
Suggestion,
DatasourceLayers,
} from '../../types';
import type { DragDropIdentifier } from '../../drag_drop';
import type { LayerType } from '../../../common';
import { getLayerType } from './config_panel/add_layer';
import {

View file

@ -1,18 +1,5 @@
@import '../../../mixins';
.lnsVisualizeGeoFieldWorkspacePanel__dragDrop {
padding: $euiSizeXXL ($euiSizeXL * 2);
border: $euiBorderThin;
border-radius: $euiBorderRadius;
&.lnsDragDrop-isDropTarget {
@include lnsDroppable;
@include lnsDroppableActive;
}
&.lnsDragDrop-isActiveDropTarget {
@include lnsDroppableActiveHover;
}
}

View file

@ -11,9 +11,9 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { UiActionsStart, VISUALIZE_GEO_FIELD_TRIGGER } from '@kbn/ui-actions-plugin/public';
import { GlobeIllustration } from '@kbn/chart-icons';
import { DragDrop } from '@kbn/dom-drag-drop';
import { IndexPattern } from '../../../types';
import { getVisualizeGeoFieldMessage } from '../../../utils';
import { DragDrop } from '../../../drag_drop';
import { APP_ID } from '../../../../common/constants';
import './geo_field_workspace_panel.scss';

View file

@ -25,7 +25,7 @@ jest.mock('../../../debounced_component', () => {
import { WorkspacePanel } from './workspace_panel';
import { ReactWrapper } from 'enzyme';
import { DragDrop, ChildDragDropProvider } from '../../../drag_drop';
import { DragDrop, ChildDragDropProvider } from '@kbn/dom-drag-drop';
import { buildExistsFilter } from '@kbn/es-query';
import { coreMock } from '@kbn/core/public/mocks';
import { DataView } from '@kbn/data-views-plugin/public';
@ -933,6 +933,7 @@ describe('workspace_panel', () => {
async function initComponent(draggingContext = draggedField) {
const mounted = await mountWithProvider(
<ChildDragDropProvider
dataTestSubjPrefix="lnsDragDrop"
dragging={draggingContext}
setDragging={() => {}}
setActiveDropTarget={() => {}}

View file

@ -33,6 +33,7 @@ import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public';
import type { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common';
import type { Datatable } from '@kbn/expressions-plugin/public';
import { DropIllustration } from '@kbn/chart-icons';
import { DragDrop, DragContext, DragDropIdentifier } from '@kbn/dom-drag-drop';
import { trackUiCounterEvents } from '../../../lens_ui_telemetry';
import { getSearchWarningMessages } from '../../../utils';
import {
@ -50,7 +51,6 @@ import {
AddUserMessages,
isMessageRemovable,
} from '../../../types';
import { DragDrop, DragContext, DragDropIdentifier } from '../../../drag_drop';
import { switchToSuggestion } from '../suggestion_helpers';
import { buildExpression } from '../expression_helpers';
import { WorkspacePanelWrapper } from './workspace_panel_wrapper';

View file

@ -47,10 +47,7 @@
.lnsWorkspacePanel__dragDrop {
border: $euiBorderWidthThin solid transparent;
&.lnsDragDrop-isDropTarget {
@include lnsDroppable;
@include lnsDroppableActive;
&.domDragDrop-isDropTarget {
p {
transition: filter $euiAnimSpeedFast ease-in-out;
filter: blur(5px);
@ -63,9 +60,7 @@
}
}
&.lnsDragDrop-isActiveDropTarget {
@include lnsDroppableActiveHover;
&.domDragDrop-isActiveDropTarget {
.lnsDropIllustration__hand {
animation: lnsWorkspacePanel__illustrationPulseContinuous 1.5s ease-in-out 0s infinite normal forwards;
}

View file

@ -39,7 +39,12 @@ import { SearchRequest } from '@kbn/data-plugin/public';
import { estypes } from '@elastic/elasticsearch';
import React from 'react';
import { CellValueContext } from '@kbn/embeddable-plugin/public';
import type { DraggingIdentifier, DragDropIdentifier, DragContextState } from './drag_drop';
import type {
DraggingIdentifier,
DragDropIdentifier,
DragContextState,
DropType,
} from '@kbn/dom-drag-drop';
import type { DateRange, LayerType, SortingHint } from '../common';
import type {
LensSortActionData,
@ -213,24 +218,6 @@ export type TableChangeType =
| 'reorder'
| 'layers';
export type DropType =
| 'field_add'
| 'field_replace'
| 'reorder'
| 'move_compatible'
| 'replace_compatible'
| 'move_incompatible'
| 'replace_incompatible'
| 'replace_duplicate_compatible'
| 'duplicate_compatible'
| 'swap_compatible'
| 'replace_duplicate_incompatible'
| 'duplicate_incompatible'
| 'swap_incompatible'
| 'field_combine'
| 'combine_compatible'
| 'combine_incompatible';
export interface DatasourceSuggestion<T = unknown> {
state: T;
table: TableSuggestion;

View file

@ -21,6 +21,7 @@ import {
} from '@kbn/charts-plugin/public';
import { RequestAdapter } from '@kbn/inspector-plugin/common';
import { ISearchStart } from '@kbn/data-plugin/public';
import type { DraggingIdentifier } from '@kbn/dom-drag-drop';
import type { Document } from './persistence/saved_object_store';
import {
Datasource,
@ -35,7 +36,6 @@ import {
} from './types';
import type { DatasourceStates, VisualizationState } from './state_management';
import type { IndexPatternServiceAPI } from './data_views_service/service';
import type { DraggingIdentifier } from './drag_drop';
export function getVisualizeGeoFieldMessage(fieldType: string) {
return i18n.translate('xpack.lens.visualizeGeoFieldMessage', {

View file

@ -54,7 +54,6 @@
"@kbn/analytics",
"@kbn/core-execution-context-common",
"@kbn/chart-icons",
"@kbn/react-field",
"@kbn/tinymath",
"@kbn/ui-theme",
"@kbn/shared-ux-link-redirect-app",
@ -65,6 +64,7 @@
"@kbn/core-saved-objects-server",
"@kbn/safer-lodash-set",
"@kbn/shared-ux-router",
"@kbn/dom-drag-drop",
],
"exclude": [
"target/**/*",

View file

@ -19154,48 +19154,6 @@
"xpack.lens.configure.suggestedValuee": "Valeur suggérée : {value}",
"xpack.lens.confirmModal.saveDuplicateButtonLabel": "Enregistrer {name}",
"xpack.lens.datatable.visualizationOf": "Tableau {operations}",
"xpack.lens.dragDrop.announce.cancelled": "Mouvement annulé. {label} revenu à sa position initiale",
"xpack.lens.dragDrop.announce.cancelledItem": "Mouvement annulé. {label} revenu au groupe {groupLabel} à la position {position}",
"xpack.lens.dragDrop.announce.dropped.combineCompatible": "{label} combiné dans le groupe {groupLabel} en {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.combineIncompatible": "{label} converti en {nextLabel} dans le groupe {groupLabel} à la position {position} et combiné à {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.duplicated": "{label} dupliqué dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber}",
"xpack.lens.dragDrop.announce.dropped.duplicateIncompatible": "Copie de {label} convertie en {nextLabel} et ajoutée au groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.moveCompatible": "{label} déplacé dans le groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.moveIncompatible": "{label} converti en {nextLabel} et déplacé dans le groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.reordered": "{label} réorganisé dans le groupe {groupLabel} de la position {prevPosition} à la position {position}",
"xpack.lens.dragDrop.announce.dropped.replaceDuplicateIncompatible": "Copie de {label} convertie en {nextLabel} et {dropLabel} remplacé dans le groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.replaceIncompatible": "{label} converti en {nextLabel} et {dropLabel} remplacé dans le groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.dropped.swapCompatible": "{label} déplacé vers {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber} et {dropLabel} dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber}",
"xpack.lens.dragDrop.announce.dropped.swapIncompatible": "{label} converti en {nextLabel} dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber} et permuté avec {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.droppedDefault": "{label} ajouté dans le groupe {dropGroupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.droppedNoPosition": "{label} ajouté à {dropLabel}",
"xpack.lens.dragDrop.announce.duplicated.combine": "Combiner {dropLabel} avec {label} dans {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.duplicated.replace": "{dropLabel} remplacé par {label} dans {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.duplicated.replaceDuplicateCompatible": "{dropLabel} remplacé par une copie de {label} dans {groupLabel} à la position {position} dans le calque {dropLayerNumber}",
"xpack.lens.dragDrop.announce.lifted": "{label} levé",
"xpack.lens.dragDrop.announce.selectedTarget.combine": "Combinez {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber} avec {label}. Appuyez sur la barre despace ou sur Entrée pour combiner.",
"xpack.lens.dragDrop.announce.selectedTarget.combineCompatible": "Combinez {label} dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber} avec {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Maintenez la touche Contrôle enfoncée et appuyez sur la barre despace ou sur Entrée pour combiner.",
"xpack.lens.dragDrop.announce.selectedTarget.combineIncompatible": "Convertissez {label} en {nextLabel} dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber} combinez-le à {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Maintenez la touche Contrôle enfoncée et appuyez sur la barre despace ou sur Entrée pour combiner.",
"xpack.lens.dragDrop.announce.selectedTarget.combineMain": "Vous faites glisser {label} de {groupLabel} à la position {position} dans le calque {layerNumber} sur {dropLabel} à partir du groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Appuyez sur la barre d'espace ou sur Entrée pour combiner {dropLabel} à {label}.{duplicateCopy}{swapCopy}{combineCopy}.",
"xpack.lens.dragDrop.announce.selectedTarget.default": "Ajoutez {label} au groupe {dropGroupLabel} à la position {position} dans le calque {dropLayerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour ajouter",
"xpack.lens.dragDrop.announce.selectedTarget.defaultNoPosition": "Ajoutez {label} à {dropLabel}. Appuyer sur la barre d'espace ou sur Entrée pour ajouter",
"xpack.lens.dragDrop.announce.selectedTarget.duplicated": "Dupliquez {label} dans le groupe {dropGroupLabel} à la position {position} dans le calque {layerNumber}. Maintenir la touche Alt ou Option enfoncée et appuyer sur la barre d'espace ou sur Entrée pour dupliquer",
"xpack.lens.dragDrop.announce.selectedTarget.duplicatedInGroup": "Dupliquez {label} dans le groupe {dropGroupLabel} à la position {position} dans le calque {layerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour dupliquer",
"xpack.lens.dragDrop.announce.selectedTarget.duplicateIncompatible": "Convertissez la copie de {label} en {nextLabel} et ajoutez-la au groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}. Maintenir la touche Alt ou Option enfoncée et appuyer sur la barre d'espace ou sur Entrée pour dupliquer",
"xpack.lens.dragDrop.announce.selectedTarget.moveCompatible": "Déplacez {label} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour déplacer",
"xpack.lens.dragDrop.announce.selectedTarget.moveCompatibleMain": "Vous faites glisser {label} de {groupLabel} à la position {position} sur la position {dropPosition} dans le groupe {dropGroupLabel} dans le calque {dropLayerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour déplacer.{duplicateCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.moveIncompatible": "Convertissez {label} en {nextLabel} et déplacez-le dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour déplacer",
"xpack.lens.dragDrop.announce.selectedTarget.moveIncompatibleMain": "Vous faites glisser {label} de {groupLabel} à la position {position} dans le calque {layerNumber} sur la position {dropPosition} dans le groupe {dropGroupLabel} dans le calque {dropLayerNumber}. Appuyez sur la barre d'espace ou sur Entrée pour convertir {label} en {nextLabel} et le déplacer.{duplicateCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.reordered": "Réorganisez {label} dans le groupe {groupLabel} de la position {prevPosition} à la position {position}. Appuyer sur la barre d'espace ou sur Entrée pour réorganiser",
"xpack.lens.dragDrop.announce.selectedTarget.reorderedBack": "{label} revenu à sa position initiale {prevPosition}",
"xpack.lens.dragDrop.announce.selectedTarget.replace": "Remplacez {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber} par {label}. Appuyez sur la barre d'espace ou sur Entrée pour remplacer.",
"xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateCompatible": "Dupliquez {label} et remplacez {dropLabel} dans {groupLabel} à la position {position} dans le calque {dropLayerNumber}. Maintenir la touche Alt ou Option enfoncée et appuyer sur la barre d'espace ou sur Entrée pour dupliquer et remplacer",
"xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateIncompatible": "Convertissez la copie de {label} en {nextLabel} et remplacez {dropLabel} dans le groupe {groupLabel} à la position {position} dans le calque {dropLayerNumber}. Maintenir la touche Alt ou Option enfoncée et appuyer sur la barre d'espace ou sur Entrée pour dupliquer et remplacer",
"xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatible": "Convertissez {label} en {nextLabel} et remplacez {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour remplacer",
"xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatibleMain": "Vous faites glisser {label} de {groupLabel} à la position {position} dans le calque {layerNumber} sur {dropLabel} à partir du groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Appuyez sur la barre d'espace ou sur Entrée pour convertir {label} en {nextLabel} et remplacer {dropLabel}.{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.replaceMain": "Vous faites glisser {label} de {groupLabel} à la position {position} dans le calque {layerNumber} sur {dropLabel} à partir du groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Appuyer sur la barre d'espace ou sur Entrée pour remplacer {dropLabel} par {label}.{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.swapCompatible": "Permutez {label} dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber} avec {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Maintenir la touche Maj enfoncée tout en appuyant sur la barre d'espace ou sur Entrée pour permuter",
"xpack.lens.dragDrop.announce.selectedTarget.swapIncompatible": "Convertissez {label} en {nextLabel} dans le groupe {groupLabel} à la position {position} dans le calque {layerNumber} permutez-le avec {dropLabel} dans le groupe {dropGroupLabel} à la position {dropPosition} dans le calque {dropLayerNumber}. Maintenir la touche Maj enfoncée tout en appuyant sur la barre d'espace ou sur Entrée pour permuter",
"xpack.lens.editorFrame.colorIndicatorLabel": "Couleur de cette dimension : {hex}",
"xpack.lens.editorFrame.configurationFailureMoreErrors": " +{errors} {errors, plural, one {erreur} other {erreurs}}",
"xpack.lens.editorFrame.expressionFailureMessage": "Erreur de requête : {type}, {reason}",
@ -19224,7 +19182,6 @@
"xpack.lens.indexPattern.derivativeOf": "Différences de {name}",
"xpack.lens.indexPattern.fieldNoOperation": "Le champ {field} ne peut pas être utilisé sans opération",
"xpack.lens.indexPattern.fieldsNotFound": "{count, plural, one {Champ} other {Champs}} {missingFields} {count, plural, one {introuvable} other {introuvables}}.",
"xpack.lens.indexPattern.fieldStatsButtonAriaLabel": "Aperçu {fieldName} : {fieldType}",
"xpack.lens.indexPattern.fieldsWrongType": "{count, plural, one {Champ} other {Champs}} {invalidFields} {count, plural, other {}}de type incorrect",
"xpack.lens.indexPattern.filters.queryPlaceholderKql": "{example}",
"xpack.lens.indexPattern.filters.queryPlaceholderLucene": "{example}",
@ -19482,18 +19439,6 @@
"xpack.lens.dimensionContainer.close": "Fermer",
"xpack.lens.dimensionContainer.closeConfiguration": "Fermer la configuration",
"xpack.lens.discover.visualizeFieldLegend": "Visualiser le champ",
"xpack.lens.dragDrop.altOption": "Alt/Option",
"xpack.lens.dragDrop.announce.combine.short": " Maintenir la touche Contrôle enfoncée pour combiner",
"xpack.lens.dragDrop.announce.duplicate.short": " Maintenez la touche Alt ou Option enfoncée pour dupliquer.",
"xpack.lens.dragDrop.announce.selectedTarget.noSelected": "Aucune cible sélectionnée. Utiliser les touches fléchées pour sélectionner une cible",
"xpack.lens.dragDrop.announce.swap.short": " Maintenez la touche Maj enfoncée pour permuter.",
"xpack.lens.dragDrop.combine": "Combiner",
"xpack.lens.dragDrop.control": "Contrôler",
"xpack.lens.dragDrop.duplicate": "Dupliquer",
"xpack.lens.dragDrop.keyboardInstructions": "Appuyez sur la barre d'espace ou sur Entrée pour commencer à faire glisser. Lors du glissement, utilisez les touches fléchées gauche/droite pour vous déplacer entre les cibles de dépôt. Appuyez à nouveau sur la barre d'espace ou sur Entrée pour terminer.",
"xpack.lens.dragDrop.keyboardInstructionsReorder": "Appuyez sur la barre d'espace ou sur Entrée pour commencer à faire glisser. Lors du glissement, utilisez les touches fléchées haut/bas pour réorganiser les éléments dans le groupe et les touches gauche/droite pour choisir les cibles de dépôt à l'extérieur du groupe. Appuyez à nouveau sur la barre d'espace ou sur Entrée pour terminer.",
"xpack.lens.dragDrop.shift": "Déplacer",
"xpack.lens.dragDrop.swap": "Permuter",
"xpack.lens.editorFrame.aggregateIndicatorLabel": "Cette dimension n'est pas visible dans le graphique car toutes les valeurs individuelles sont agrégées en une valeur unique",
"xpack.lens.editorFrame.applyChanges": "Appliquer les modifications",
"xpack.lens.editorFrame.applyChangesLabel": "Appliquer les modifications",

View file

@ -19153,48 +19153,6 @@
"xpack.lens.configure.suggestedValuee": "候補の値:{value}",
"xpack.lens.confirmModal.saveDuplicateButtonLabel": "{name}を保存",
"xpack.lens.datatable.visualizationOf": "表 {operations}",
"xpack.lens.dragDrop.announce.cancelled": "移動がキャンセルされました。{label}は初期位置に戻りました",
"xpack.lens.dragDrop.announce.cancelledItem": "移動がキャンセルされました。{label}は位置{position}の{groupLabel}グループに戻りました",
"xpack.lens.dragDrop.announce.dropped.combineCompatible": "レイヤー{dropLayerNumber}の位置{dropPosition}でグループ{dropGroupLabel}の{dropLabel}にグループ{groupLabel}の{label}を結合しました。",
"xpack.lens.dragDrop.announce.dropped.combineIncompatible": "{label}を位置{position}の{groupLabel}グループの{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}の{dropGroupLabel}グループの{dropLabel}に結合しました",
"xpack.lens.dragDrop.announce.dropped.duplicated": "レイヤー{layerNumber}の位置{position}で{groupLabel}グループの{label}ラベルを複製しました",
"xpack.lens.dragDrop.announce.dropped.duplicateIncompatible": "{label}のコピーを{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループに追加しました",
"xpack.lens.dragDrop.announce.dropped.moveCompatible": "レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループに{label}ラベルを移動しました",
"xpack.lens.dragDrop.announce.dropped.moveIncompatible": "{label}を{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループに移動しました",
"xpack.lens.dragDrop.announce.dropped.reordered": "{groupLabel}の{label}を位置{prevPosition}から位置{position}に並べ替えました",
"xpack.lens.dragDrop.announce.dropped.replaceDuplicateIncompatible": "{label}のコピーを{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループの{dropLabel}を置き換えました",
"xpack.lens.dragDrop.announce.dropped.replaceIncompatible": "{label}を{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループの{dropLabel}を置き換えました",
"xpack.lens.dragDrop.announce.dropped.swapCompatible": "{label}をレイヤー{dropLayerNumber}の位置{dropPosition}で{dropGroupLabel}に移動し、{dropLabel}をレイヤー{layerNumber}の位置{position}の{groupLabel}グループに移動しました",
"xpack.lens.dragDrop.announce.dropped.swapIncompatible": "{label}をレイヤー{layerNumber}の位置{position}の{groupLabel}グループの{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}の{dropGroupLabel}グループの{dropLabel}と入れ替えました",
"xpack.lens.dragDrop.announce.droppedDefault": "レイヤー{dropLayerNumber}の位置{position}で{dropGroupLabel}グループの{label}ラベルを追加しました",
"xpack.lens.dragDrop.announce.droppedNoPosition": "{label} が {dropLabel} に追加されました",
"xpack.lens.dragDrop.announce.duplicated.combine": "レイヤー{dropLayerNumber}の位置{position}で{dropLabel}を{groupLabel}の{label}と結合",
"xpack.lens.dragDrop.announce.duplicated.replace": "レイヤー{dropLayerNumber}の位置{position}で{dropLabel}を{groupLabel}の{label}で置換",
"xpack.lens.dragDrop.announce.duplicated.replaceDuplicateCompatible": "レイヤー{dropLayerNumber}の位置{position}で{dropLabel}を{groupLabel}の{label}のコピーで置換",
"xpack.lens.dragDrop.announce.lifted": "持ち上げられた{label}",
"xpack.lens.dragDrop.announce.selectedTarget.combine": "レイヤー{dropLayerNumber}の位置{dropPosition}で{dropGroupLabel}グループの{dropLabel}ラベルを{label}と結合しました。スペースまたはEnterを押して結合します。",
"xpack.lens.dragDrop.announce.selectedTarget.combineCompatible": "{label}を位置{layerNumber}の{position}グループの{groupLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}の{dropGroupLabel}グループの{dropLabel}に結合しました。Ctrlキーを押しながらスペースバーまたはEnterキーを押すと、結合します",
"xpack.lens.dragDrop.announce.selectedTarget.combineIncompatible": "{label}をレイヤー{layerNumber}の位置{position}の{groupLabel}グループの{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}の{dropGroupLabel}グループの{dropLabel}と結合しました。Ctrlキーを押しながらスペースバーまたはEnterキーを押すと、結合します",
"xpack.lens.dragDrop.announce.selectedTarget.combineMain": "レイヤー {layerNumber} の位置 {position} にある {groupLabel} から {label} を、レイヤー {dropLayerNumber} の位置 {dropPosition} にある {dropGroupLabel} グループから {dropLabel} にドラッグしいます。スペースまたはEnterを押して、{dropLabel}と{label}.{duplicateCopy}{swapCopy}{combineCopy}を結合します。",
"xpack.lens.dragDrop.announce.selectedTarget.default": "レイヤー{dropLayerNumber}の位置{position}で{dropGroupLabel}グループに{label}ラベルを追加します。スペースまたはEnterを押して追加します",
"xpack.lens.dragDrop.announce.selectedTarget.defaultNoPosition": "{label} を {dropLabel} に追加します。スペースまたはEnterを押して追加します",
"xpack.lens.dragDrop.announce.selectedTarget.duplicated": "レイヤー{layerNumber}の位置{position}で{dropGroupLabel}グループに{label}ラベルを複製します。AltまたはOptionを押しながらスペースバーまたはEnterキーを押すと、複製します",
"xpack.lens.dragDrop.announce.selectedTarget.duplicatedInGroup": "レイヤー{layerNumber}の位置{position}で{dropGroupLabel}グループに{label}ラベルを複製します。スペースまたはEnterを押して複製します",
"xpack.lens.dragDrop.announce.selectedTarget.duplicateIncompatible": "{label}のコピーを{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループに追加します。AltまたはOptionを押しながらスペースバーまたはEnterキーを押すと、複製します",
"xpack.lens.dragDrop.announce.selectedTarget.moveCompatible": "レイヤー{dropLayerNumber}の位置{dropPosition}で{dropGroupLabel}グループに{label}ラベルを移動します。スペースまたはEnterを押して移動します",
"xpack.lens.dragDrop.announce.selectedTarget.moveCompatibleMain": "位置{position}の{groupLabel}の{label}をレイヤー{dropLayerNumber}の{dropGroupLabel}グループの位置{dropPosition}にドラッグしています。スペースまたはEnterを押して移動します。{duplicateCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.moveIncompatible": "{label}を{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}で{dropGroupLabel}グループに移動します。スペースまたはEnterを押して移動します",
"xpack.lens.dragDrop.announce.selectedTarget.moveIncompatibleMain": "レイヤー{layerNumber}の位置{position}の{groupLabel}の{label}をレイヤー{dropLayerNumber}の{dropGroupLabel}グループの位置{dropPosition}にドラッグしています。スペースキーまたはEnterキーを押すと、{label}が{nextLabel}に変換され、移動します。{duplicateCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.reordered": "{groupLabel}の{label}を位置{prevPosition}から位置{position}に並べ替えます。スペースまたはEnterを押して並べ替えます",
"xpack.lens.dragDrop.announce.selectedTarget.reorderedBack": "{label}は初期位置{prevPosition}に戻りました",
"xpack.lens.dragDrop.announce.selectedTarget.replace": "レイヤー{dropLayerNumber}の位置{dropPosition}で{dropGroupLabel}グループの{dropLabel}ラベルを{label}で置換します。スペースまたはEnterを押して置き換えます。",
"xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateCompatible": "{label}を複製し、レイヤー{dropLayerNumber}の位置{position}の{groupLabel}の{dropLabel}を置換します。AltまたはOptionを押しながらスペースバーまたはEnterキーを押すと、複製して置換します",
"xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateIncompatible": "{label}のコピーを{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{position}で{groupLabel}グループの{dropLabel}を置き換えます。AltまたはOptionを押しながらスペースバーまたはEnterキーを押すと、複製して置換します",
"xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatible": "{label}を{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}で{dropGroupLabel}グループの{dropLabel}を置き換えます。スペースまたはEnterを押して置き換えます",
"xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatibleMain": "レイヤー {layerNumber} の位置 {position} にある {groupLabel} から {label} を、レイヤー {dropLayerNumber} の位置 {dropPosition} にある {dropGroupLabel} グループから {dropLabel} にドラッグしいます。スペースキーまたはEnterキーを押して、{label}を{nextLabel}に変換し、{dropLabel}を置換します。{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.replaceMain": "レイヤー {layerNumber} の位置 {position} にある {groupLabel} から {label} を、レイヤー {dropLayerNumber} の位置 {dropPosition} にある {dropGroupLabel} グループから {dropLabel} にドラッグします。スペースまたはEnterを押して、{dropLabel}を{label}で置き換えます。{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.swapCompatible": "{label}を位置{layerNumber}の{position}グループの{groupLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}の{dropGroupLabel}グループの{dropLabel}に入れ替えます。Shiftキーを押しながらスペースバーまたはEnterキーを押すと、入れ替えます",
"xpack.lens.dragDrop.announce.selectedTarget.swapIncompatible": "{label}をレイヤー{layerNumber}の位置{position}の{groupLabel}グループの{nextLabel}に変換し、レイヤー{dropLayerNumber}の位置{dropPosition}の{dropGroupLabel}グループの{dropLabel}と入れ替えます。Shiftキーを押しながらスペースバーまたはEnterキーを押すと、入れ替えます",
"xpack.lens.editorFrame.colorIndicatorLabel": "このディメンションの色:{hex}",
"xpack.lens.editorFrame.configurationFailureMoreErrors": " +{errors} {errors, plural, other {エラー}}",
"xpack.lens.editorFrame.expressionFailureMessage": "リクエストエラー:{type}、{reason}",
@ -19223,7 +19181,6 @@
"xpack.lens.indexPattern.derivativeOf": "{name}の差異",
"xpack.lens.indexPattern.fieldNoOperation": "フィールド{field}は演算なしで使用できません",
"xpack.lens.indexPattern.fieldsNotFound": "{count, plural, other {フィールド}}{missingFields}{count, plural, other {が}}見つかりません",
"xpack.lens.indexPattern.fieldStatsButtonAriaLabel": "プレビュー{fieldName}{fieldType}",
"xpack.lens.indexPattern.fieldsWrongType": "{count, plural, other {フィールド}}\"{invalidFields}\"は正しくない型{count, plural, other {です}}",
"xpack.lens.indexPattern.filters.queryPlaceholderKql": "{example}",
"xpack.lens.indexPattern.filters.queryPlaceholderLucene": "{example}",
@ -19482,18 +19439,6 @@
"xpack.lens.dimensionContainer.close": "閉じる",
"xpack.lens.dimensionContainer.closeConfiguration": "構成を閉じる",
"xpack.lens.discover.visualizeFieldLegend": "Visualize フィールド",
"xpack.lens.dragDrop.altOption": "Alt/Option",
"xpack.lens.dragDrop.announce.combine.short": " Ctrlを押しながら結合します",
"xpack.lens.dragDrop.announce.duplicate.short": " AltキーまたはOptionを押し続けると複製します。",
"xpack.lens.dragDrop.announce.selectedTarget.noSelected": "対象が選択されていません。矢印キーを使用して対象を選択してください",
"xpack.lens.dragDrop.announce.swap.short": " Shiftキーを押すと入れ替えます。",
"xpack.lens.dragDrop.combine": "結合",
"xpack.lens.dragDrop.control": "Control",
"xpack.lens.dragDrop.duplicate": "複製",
"xpack.lens.dragDrop.keyboardInstructions": "スペースまたはEnterを押してドラッグを開始します。ドラッグするときには、左右の矢印キーを使用して、ドロップ対象間を移動します。もう一度スペースまたはEnterを押すと終了します。",
"xpack.lens.dragDrop.keyboardInstructionsReorder": "スペースまたはEnterを押してドラッグを開始します。ドラッグするときには、上下矢印キーを使用すると、グループの項目を並べ替えます。左右矢印キーを使用すると、グループの外側でドロップ対象を選択します。もう一度スペースまたはEnterを押すと終了します。",
"xpack.lens.dragDrop.shift": "Shift",
"xpack.lens.dragDrop.swap": "入れ替える",
"xpack.lens.editorFrame.aggregateIndicatorLabel": "すべての個別の値が1つの値に集約されているため、このディメンションはグラフに表示されません",
"xpack.lens.editorFrame.applyChanges": "変更を適用",
"xpack.lens.editorFrame.applyChangesLabel": "変更を適用",

View file

@ -19154,47 +19154,6 @@
"xpack.lens.configure.suggestedValuee": "建议值:{value}",
"xpack.lens.confirmModal.saveDuplicateButtonLabel": "保存 {name}",
"xpack.lens.datatable.visualizationOf": "表 {operations}",
"xpack.lens.dragDrop.announce.cancelled": "移动已取消。{label} 已返回至其初始位置",
"xpack.lens.dragDrop.announce.cancelledItem": "移动已取消。{label} 返回至 {groupLabel} 组中的位置 {position}",
"xpack.lens.dragDrop.announce.dropped.combineCompatible": "已将组 {groupLabel} 中的 {label} 组合到图层 {dropLayerNumber} 的组 {dropGroupLabel} 中的位置 {dropPosition} 上的 {dropLabel}",
"xpack.lens.dragDrop.announce.dropped.combineIncompatible": "已将 {label} 转换为组 {groupLabel} 中位置 {position} 上的 {nextLabel},并与图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {dropPosition} 上的 {dropLabel} 组合",
"xpack.lens.dragDrop.announce.dropped.duplicated": "已复制图层 {layerNumber} 的 {groupLabel} 组中位置 {position} 上的 {label}",
"xpack.lens.dragDrop.announce.dropped.duplicateIncompatible": "已将 {label} 的副本转换为 {nextLabel} 并添加到图层 {dropLayerNumber} 的 {groupLabel} 组中的位置 {position}",
"xpack.lens.dragDrop.announce.dropped.moveCompatible": "已将 {label} 移到图层 {dropLayerNumber} 的 {groupLabel} 组中的位置 {position}",
"xpack.lens.dragDrop.announce.dropped.moveIncompatible": "已将 {label} 转换为 {nextLabel} 并移到图层 {dropLayerNumber} 的 {groupLabel} 组中的位置 {position}",
"xpack.lens.dragDrop.announce.dropped.reordered": "已将 {groupLabel} 组中的 {label} 从位置 {prevPosition} 重新排到位置 {position}",
"xpack.lens.dragDrop.announce.dropped.replaceDuplicateIncompatible": "已将 {label} 的副本转换为 {nextLabel} 并替换图层 {dropLayerNumber} 的 {groupLabel} 组中位置 {position} 上的 {dropLabel}",
"xpack.lens.dragDrop.announce.dropped.replaceIncompatible": "已将 {label} 转换为 {nextLabel} 并替换图层 {dropLayerNumber} 的 {groupLabel} 组中位置 {position} 上的 {dropLabel}",
"xpack.lens.dragDrop.announce.dropped.swapCompatible": "已将 {label} 移至图层 {dropLayerNumber} 中位置 {dropPosition} 上的 {dropGroupLabel} 并将 {dropLabel} 移至图层 {layerNumber} 的 {groupLabel} 组中的位置 {position}",
"xpack.lens.dragDrop.announce.dropped.swapIncompatible": "已将 {label} 转换为图层 {layerNumber} 的组 {groupLabel} 中位置 {position} 上的 {nextLabel},并与图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel} 交换",
"xpack.lens.dragDrop.announce.droppedDefault": "已将 {label} 添加到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {position}",
"xpack.lens.dragDrop.announce.droppedNoPosition": "已将 {label} 添加到 {dropLabel}",
"xpack.lens.dragDrop.announce.duplicated.combine": "将 {dropLabel} 与图层 {dropLayerNumber} 的 {groupLabel} 中位置 {position} 上的 {label} 组合",
"xpack.lens.dragDrop.announce.duplicated.replace": "已将 {dropLabel} 替换为图层 {dropLayerNumber} 的 {groupLabel} 中位置 {position} 上的 {label}",
"xpack.lens.dragDrop.announce.duplicated.replaceDuplicateCompatible": "已将 {dropLabel} 替换为图层 {dropLayerNumber} 的 {groupLabel} 中位置 {position} 上的 {label} 副本",
"xpack.lens.dragDrop.announce.lifted": "已提升 {label}",
"xpack.lens.dragDrop.announce.selectedTarget.combine": "将图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {dropPosition} 上的 {dropLabel} 与 {label} 组合。按空格键或 enter 键组合。",
"xpack.lens.dragDrop.announce.selectedTarget.combineIncompatible": "将 {label} 转换为图层 {layerNumber} 的 {groupLabel} 组中位置 {position} 上的 {nextLabel},并与图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel} 组合。按住 Control 键并按空格键或 enter 键组合",
"xpack.lens.dragDrop.announce.selectedTarget.combineMain": "您正将图层 {layerNumber} 的 {groupLabel} 中位置 {position} 上的 {label} 拖到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel}。按空格键或 enter 键组合 {dropLabel} 与 {label}。{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.default": "将 {label} 移到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {position}。按空格键或 enter 键添加",
"xpack.lens.dragDrop.announce.selectedTarget.defaultNoPosition": "将 {label} 添加到 {dropLabel}。按空格键或 enter 键添加",
"xpack.lens.dragDrop.announce.selectedTarget.duplicated": "将 {label} 复制到图层 {layerNumber} 的 {dropGroupLabel} 组中的位置 {position}。按住 Alt 或 Option 并按空格键或 enter 键以复制",
"xpack.lens.dragDrop.announce.selectedTarget.duplicatedInGroup": "将 {label} 复制到图层 {layerNumber} 的 {dropGroupLabel} 组中的位置 {position}。按空格键或 enter 键复制",
"xpack.lens.dragDrop.announce.selectedTarget.duplicateIncompatible": "将 {label} 的副本转换为 {nextLabel} 并添加到图层 {dropLayerNumber} 的 {groupLabel} 组中的位置 {position}。按住 Alt 或 Option 并按空格键或 enter 键以复制",
"xpack.lens.dragDrop.announce.selectedTarget.moveCompatible": "将 {label} 移到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {dropPosition}。按空格键或 enter 键移动",
"xpack.lens.dragDrop.announce.selectedTarget.moveCompatibleMain": "您正将图层 {dropPosition} 的 {groupLabel} 中位置 {position} 上的 {label} 拖到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {dropPosition}。按空格键或 enter 键移动。{duplicateCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.moveIncompatible": "将 {label} 转换为 {nextLabel} 并移到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中的位置 {dropPosition}。按空格键或 enter 键移动",
"xpack.lens.dragDrop.announce.selectedTarget.moveIncompatibleMain": "您正将图层 {layerNumber} 的 {groupLabel} 中位置 {position} 上的 {label} 拖到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition}。按空格键或 enter 键将 {label} 转换为 {nextLabel} 并进行移动。{duplicateCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.reordered": "将 {groupLabel} 组中的 {label} 从位置 {prevPosition} 重新排到位置 {position}按空格键或 enter 键重新排列",
"xpack.lens.dragDrop.announce.selectedTarget.reorderedBack": "{label} 已返回至其初始位置 {prevPosition}",
"xpack.lens.dragDrop.announce.selectedTarget.replace": "将图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel} 替换为 {label}。按空格键或 enter 键替换。",
"xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateCompatible": "复制 {label} 为替换图层 {dropLayerNumber} 的 {groupLabel} 中位置 {position} 上的 {dropLabel}。按住 Alt 或 Option 并按空格键或 enter 键以复制并替换",
"xpack.lens.dragDrop.announce.selectedTarget.replaceDuplicateIncompatible": "将 {label} 的副本转换为 {nextLabel} 并替换图层 {dropLayerNumber} 的 {groupLabel} 组中位置 {position} 上的 {dropLabel}。按住 Alt 或 Option 并按空格键或 enter 键以复制并替换",
"xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatible": "将 {label} 转换为 {nextLabel} 并替换图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel}。按空格键或 enter 键替换",
"xpack.lens.dragDrop.announce.selectedTarget.replaceIncompatibleMain": "您正将图层 {layerNumber} 的 {groupLabel} 中位置 {position} 上的 {label} 拖到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel}。按空格键或 enter 键将 {label} 转换为 {nextLabel} 并替换 {dropLabel}。{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.replaceMain": "您正将图层 {layerNumber} 的 {groupLabel} 中位置 {position} 上的 {label} 拖到图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel}。按空格键或 enter 键将 {dropLabel} 替换为 {label}。{duplicateCopy}{swapCopy}{combineCopy}",
"xpack.lens.dragDrop.announce.selectedTarget.swapCompatible": "将图层 {layerNumber} 的 {groupLabel} 组中位置 {position} 上的 {label} 与图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel} 交换。按住 Shift 键并按空格键或 enter 键交换",
"xpack.lens.dragDrop.announce.selectedTarget.swapIncompatible": "将 {label} 转换为图层 {layerNumber} 的 {groupLabel} 组中位置 {position} 上的 {nextLabel},并与图层 {dropLayerNumber} 的 {dropGroupLabel} 组中位置 {dropPosition} 上的 {dropLabel} 交换。按住 Shift 键并按空格键或 enter 键交换",
"xpack.lens.editorFrame.colorIndicatorLabel": "此维度的颜色:{hex}",
"xpack.lens.editorFrame.configurationFailureMoreErrors": " +{errors} 个{errors, plural, other {错误}}",
"xpack.lens.editorFrame.expressionFailureMessage": "请求错误:{type}{reason}",
@ -19223,7 +19182,6 @@
"xpack.lens.indexPattern.derivativeOf": "{name} 的差异",
"xpack.lens.indexPattern.fieldNoOperation": "没有运算,无法使用字段 {field}",
"xpack.lens.indexPattern.fieldsNotFound": "找不到{count, plural, other {字段}} {missingFields} {count, plural, other {}}。",
"xpack.lens.indexPattern.fieldStatsButtonAriaLabel": "预览 {fieldName}{fieldType}",
"xpack.lens.indexPattern.fieldsWrongType": "{count, plural, other {字段}} {invalidFields} {count, plural, other {}} 的类型不正确",
"xpack.lens.indexPattern.filters.queryPlaceholderKql": "{example}",
"xpack.lens.indexPattern.filters.queryPlaceholderLucene": "{example}",
@ -19482,18 +19440,6 @@
"xpack.lens.dimensionContainer.close": "关闭",
"xpack.lens.dimensionContainer.closeConfiguration": "关闭配置",
"xpack.lens.discover.visualizeFieldLegend": "可视化字段",
"xpack.lens.dragDrop.altOption": "Alt/Option 键",
"xpack.lens.dragDrop.announce.combine.short": " 按住 Control 键组合",
"xpack.lens.dragDrop.announce.duplicate.short": " 按住 alt 或 option 键以复制。",
"xpack.lens.dragDrop.announce.selectedTarget.noSelected": "未选择任何目标。使用箭头键选择目标",
"xpack.lens.dragDrop.announce.swap.short": " 按住 Shift 键交换。",
"xpack.lens.dragDrop.combine": "组合",
"xpack.lens.dragDrop.control": "Control 键",
"xpack.lens.dragDrop.duplicate": "复制",
"xpack.lens.dragDrop.keyboardInstructions": "按空格键或 enter 键开始拖动。拖动时,请左右箭头键在拖动目标之间移动。再次按空格键或 enter 键结束操作。",
"xpack.lens.dragDrop.keyboardInstructionsReorder": "按空格键或 enter 键开始拖动。拖动时,请使用上下箭头键重新排列组中的项目,使用左右箭头键在组之外选择拖动目标。再次按空格键或 enter 键结束操作。",
"xpack.lens.dragDrop.shift": "Shift 键",
"xpack.lens.dragDrop.swap": "交换",
"xpack.lens.editorFrame.aggregateIndicatorLabel": "此维度在图表中不可见,因为所有个体值都聚合到单一值中",
"xpack.lens.editorFrame.applyChanges": "应用更改",
"xpack.lens.editorFrame.applyChangesLabel": "应用更改",

View file

@ -78,7 +78,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
it('should show a top values popover for a keyword field', async () => {
const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
const [fieldId] = await PageObjects.lens.findFieldIdsByType('keyword');
await log.debug(`Opening field stats for ${fieldId}`);
await testSubjects.click(fieldId);
// check for popover
@ -151,7 +151,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should show stats for a keyword runtime field', async () => {
await PageObjects.lens.searchField('runtime');
await PageObjects.lens.waitForField('runtime_string');
const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
const [fieldId] = await PageObjects.lens.findFieldIdsByType('keyword');
await log.debug(`Opening field stats for ${fieldId}`);
await testSubjects.click(fieldId);
// check for popover
@ -169,7 +169,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
it('should change popover content if user defines a filter that affects field values', async () => {
// check the current records count for stats
const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
const [fieldId] = await PageObjects.lens.findFieldIdsByType('keyword');
await log.debug(`Opening field stats for ${fieldId}`);
await testSubjects.click(fieldId);
const valuesCount = parseInt(
@ -198,7 +198,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await filterBar.removeAllFilters();
await filterBar.addFilter({ field: 'bytes', operation: 'is', value: '-1' });
// check via popup fields have no data
const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
const [fieldId] = await PageObjects.lens.findFieldIdsByType('keyword');
await log.debug(`Opening field stats for ${fieldId}`);
await retry.try(async () => {
await testSubjects.click(fieldId);

View file

@ -380,7 +380,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
await retry.try(async () => {
await browser.pressKeys(browserKey);
await find.existsByCssSelector(
`.lnsDragDrop__extraDrop > [data-test-subj="lnsDragDrop-${metaToAction[metaKey]}"].lnsDragDrop-isActiveDropTarget`
`.domDragDrop__extraDrop > [data-test-subj="domDragDrop-dropTarget-${metaToAction[metaKey]}"].domDragDrop-isActiveDropTarget`
);
});
},
@ -405,7 +405,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
await field.focus();
await retry.try(async () => {
await browser.pressKeys(browser.keys.ENTER);
await testSubjects.exists('.lnsDragDrop-isDropTarget'); // checks if we're in dnd mode and there's any drop target active
await testSubjects.exists('.domDragDrop-isDropTarget'); // checks if we're in dnd mode and there's any drop target active
});
for (let i = 0; i < steps; i++) {
await browser.pressKeys(reverse ? browser.keys.LEFT : browser.keys.RIGHT);
@ -477,7 +477,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
async waitForLensDragDropToFinish() {
await retry.try(async () => {
const exists = await find.existsByCssSelector('.lnsDragDrop-isActiveGroup');
const exists = await find.existsByCssSelector('.domDragDrop-isActiveGroup');
if (exists) {
throw new Error('UI still in drag/drop mode');
}
@ -525,7 +525,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
* @param endIndex - the index of drop starting from 1
* */
async reorderDimensions(dimension: string, startIndex: number, endIndex: number) {
const dragging = `[data-test-subj='${dimension}']:nth-of-type(${startIndex}) .lnsDragDrop`;
const dragging = `[data-test-subj='${dimension}']:nth-of-type(${startIndex}) .domDragDrop`;
const dropping = `[data-test-subj='${dimension}']:nth-of-type(${endIndex}) [data-test-subj='lnsDragDrop-reorderableDropLayer'`;
await find.existsByCssSelector(dragging);
await browser.html5DragAndDrop(dragging, dropping);
@ -1470,7 +1470,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
await this.dragEnterDrop(
testSubjects.getCssSelector(from),
testSubjects.getCssSelector(`${to} > lnsDragDrop`),
testSubjects.getCssSelector(`${to} > lnsDragDrop-${type}`)
testSubjects.getCssSelector(`${to} > domDragDrop-dropTarget-${type}`)
);
await this.waitForVisualization(visDataTestSubj);
},
@ -1491,7 +1491,7 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
await this.dragEnterDrop(
testSubjects.getCssSelector(from),
testSubjects.getCssSelector(`${to} > lnsDragDrop`),
testSubjects.getCssSelector(`${to} > lnsDragDrop-${type}`)
testSubjects.getCssSelector(`${to} > domDragDrop-dropTarget-${type}`)
);
await this.waitForVisualization(visDataTestSubj);
},
@ -1658,12 +1658,12 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
},
async findFieldIdsByType(
type: 'string' | 'number' | 'date' | 'geo_point' | 'ip_range',
type: 'keyword' | 'number' | 'date' | 'geo_point' | 'ip_range',
group: 'available' | 'empty' | 'meta' = 'available'
) {
const groupCapitalized = `${group[0].toUpperCase()}${group.slice(1).toLowerCase()}`;
const allFieldsForType = await find.allByCssSelector(
`[data-test-subj="lnsIndexPattern${groupCapitalized}Fields"] .lnsFieldItem--${type}`
`[data-test-subj="lnsIndexPattern${groupCapitalized}Fields"] .unifiedFieldItemButton--${type}`
);
// map to testSubjId
return Promise.all(allFieldsForType.map((el) => el.getAttribute('data-test-subj')));

View file

@ -3973,6 +3973,10 @@
version "0.0.0"
uid ""
"@kbn/dom-drag-drop@link:packages/kbn-dom-drag-drop":
version "0.0.0"
uid ""
"@kbn/ebt-tools@link:packages/kbn-ebt-tools":
version "0.0.0"
uid ""