From badf38b0cd5ae78bff3bb8b730253fd617a3f3be Mon Sep 17 00:00:00 2001 From: Constance Date: Tue, 16 Mar 2021 08:30:32 -0700 Subject: [PATCH] [Curation] Add support for a custom drag handle to the Result component (#94652) * Update Result component to render a custom drag handle * Update Result library with a draggable example - note: this doesn't actually handle reorder logic, it's purely a UI/UX example * Update CurationResult to pass dragHandleProps through to Result --- .../curation/results/curation_result.test.tsx | 9 +++++-- .../curation/results/curation_result.tsx | 5 +++- .../app_search/components/library/library.tsx | 25 +++++++++++++++++++ .../app_search/components/result/result.scss | 17 ++++++++++--- .../components/result/result.test.tsx | 15 +++++++++++ .../app_search/components/result/result.tsx | 8 ++++++ 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx index 5c417d308636..460c0f4dfa44 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.test.tsx @@ -8,6 +8,7 @@ import { setMockValues } from '../../../../../__mocks__'; import React from 'react'; +import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; import { shallow, ShallowWrapper } from 'enzyme'; @@ -29,12 +30,15 @@ describe('CurationResult', () => { { title: 'add', iconType: 'plus', onClick: () => {} }, { title: 'remove', iconType: 'minus', onClick: () => {} }, ]; + const mockDragging = {} as DraggableProvidedDragHandleProps; // Passed from EuiDraggable let wrapper: ShallowWrapper; beforeAll(() => { setMockValues(values); - wrapper = shallow(); + wrapper = shallow( + + ); }); it('passes EngineLogic state', () => { @@ -42,8 +46,9 @@ describe('CurationResult', () => { expect(wrapper.find(Result).prop('schemaForTypeHighlights')).toEqual('some mock schema'); }); - it('passes result and actions props', () => { + it('passes result, actions, and dragHandleProps props', () => { expect(wrapper.find(Result).prop('result')).toEqual(mockResult); expect(wrapper.find(Result).prop('actions')).toEqual(mockActions); + expect(wrapper.find(Result).prop('dragHandleProps')).toEqual(mockDragging); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.tsx index 3be11bcd6595..c737d93ce182 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/results/curation_result.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; import { useValues } from 'kea'; @@ -18,9 +19,10 @@ import { Result as ResultType, ResultAction } from '../../../result/types'; interface Props { result: ResultType; actions: ResultAction[]; + dragHandleProps?: DraggableProvidedDragHandleProps; } -export const CurationResult: React.FC = ({ result, actions }) => { +export const CurationResult: React.FC = ({ result, actions, dragHandleProps }) => { const { isMetaEngine, engine: { schema }, @@ -33,6 +35,7 @@ export const CurationResult: React.FC = ({ result, actions }) => { actions={actions} isMetaEngine={isMetaEngine} schemaForTypeHighlights={schema} + dragHandleProps={dragHandleProps} /> diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx index 3f72199d1280..594584d9ba10 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx @@ -14,6 +14,9 @@ import { EuiTitle, EuiPageContentBody, EuiPageContent, + EuiDragDropContext, + EuiDroppable, + EuiDraggable, } from '@elastic/eui'; import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome'; @@ -228,6 +231,28 @@ export const Library: React.FC = () => { + + +

With a drag handle

+
+ + {}}> + + {[1, 2, 3].map((_, i) => ( + + {(provided) => } + + ))} + + + +

With field value type highlights

diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.scss b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.scss index f69acbdaba15..5f1b165f2c36 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.scss +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.scss @@ -1,10 +1,10 @@ .appSearchResult { display: grid; - grid-template-columns: 1fr auto; - grid-template-rows: 1fr auto; + grid-template-columns: auto 1fr auto; + grid-template-rows: auto 1fr auto; grid-template-areas: - 'content actions' - 'toggle actions'; + 'drag content actions' + 'drag toggle actions'; overflow: hidden; // Prevents child background-colors from clipping outside of panel border-radius &__content { @@ -52,6 +52,15 @@ background-color: $euiPageBackgroundColor; } } + + &__dragHandle { + grid-area: drag; + display: flex; + justify-content: center; + align-items: center; + width: $euiSizeXL; + border-right: $euiBorderThin; + } } /** diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx index 86b71229f378..15c9ee2967d3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; import { shallow, ShallowWrapper } from 'enzyme'; @@ -129,6 +130,20 @@ describe('Result', () => { }); }); + describe('dragging', () => { + // In the real world, the drag library sets data attributes, role, tabIndex, etc. + const mockDragHandleProps = ({ + someMockProp: true, + } as unknown) as DraggableProvidedDragHandleProps; + + it('will render a drag handle with the passed props', () => { + const wrapper = shallow(); + + expect(wrapper.find('.appSearchResult__dragHandle')).toHaveLength(1); + expect(wrapper.find('.appSearchResult__dragHandle').prop('someMockProp')).toEqual(true); + }); + }); + it('will render field details with type highlights if schemaForTypeHighlights has been provided', () => { const wrapper = shallow( diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx index 2812b596e87f..89208a041af3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.tsx @@ -6,6 +6,7 @@ */ import React, { useState, useMemo } from 'react'; +import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd'; import classNames from 'classnames'; @@ -31,6 +32,7 @@ interface Props { shouldLinkToDetailPage?: boolean; schemaForTypeHighlights?: Schema; actions?: ResultAction[]; + dragHandleProps?: DraggableProvidedDragHandleProps; } const RESULT_CUTOFF = 5; @@ -42,6 +44,7 @@ export const Result: React.FC = ({ shouldLinkToDetailPage = false, schemaForTypeHighlights, actions = [], + dragHandleProps, }) => { const [isOpen, setIsOpen] = useState(false); @@ -87,6 +90,11 @@ export const Result: React.FC = ({ values: { id: result[ID].raw }, })} > + {dragHandleProps && ( +
+ +
+ )} {conditionallyLinkedArticle( <>