Skip to content

Commit

Permalink
[SIEM] Fixes dragging entries to the Timeline while data is loading m…
Browse files Browse the repository at this point in the history
…ay trigger a partial page reload (#59476) (#59521)

## [SIEM] Fixes dragging entries to the Timeline while data is loading may trigger a partial page reload

The `react-beautiful-dnd` library, upgraded during the `7.6` stack release from
`10.0.1` to `12.2.0`, includes a breaking change to the way [errors are handled](https://github.com/atlassian/react-beautiful-dnd/blob/v12.0.0/docs/guides/setup-problem-detection-and-error-recovery.md)
and recovered. As a result of this change, an uncaught error may trigger a
an effect that feels (from the perspective of a user) like a partial page
reload.

The most common condition where this can occur is when dragging entries to the
Timeline while data is loading, per the animated gif below:

![refresh-error](https://user-images.githubusercontent.com/4459398/76016029-59755f80-5ed9-11ea-858d-cb1189d22ea9.gif)

## Reproduction steps

1. Navigate to the Hosts page
2. Open the Timeline
3. Drag a host to the Timeline
4. While data is still loading, drag a different host to the Timeline to create an `or` query

**Expected Results**
* The page does not appear to reload
* In development mode, a single error is logged to the JS console

**Actual Results**
* The page appears to reload
* In development mode, two errors are logged to the JS console

**Error 1**
```
react-beautiful-dnd
Invariant failed: Cannot find droppable entry with id [droppableId.content.event-details-value-default-draggable-plain-column-renderer-formatted-field-value-timeline-1-kLGooXABOOUskGlPiQw5-@timestamp-1583260131000]👷<200d> This is a development only message. It will be removed in production builds.
    in Draggable (created by ConnectFunction)
    in ConnectFunction (created by PrivateDraggable)
    in PrivateDraggable (created by PublicDraggable)
    in PublicDraggable (created by Droppable)
    in Droppable (created by ConnectFunction)
    in ConnectFunction
```

**Error 2**
```
react-beautiful-dnd
Invariant failed: Cannot find droppable entry with id [droppableId.content.event-details-value-default-draggable-plain-column-renderer-formatted-field-value-timeline-1-kLGooXABOOUskGlPiQw5-@timestamp-1583260131000]👷<200d> This is a development only message. It will be removed in production builds.
    in ErrorBoundary (created by DragDropContext)
    in DragDropContext (created by Anonymous)
    in Anonymous
```

### Desk testing

Tested locally in:
* Chrome `80.0.3987.122`
* Firefox `73.0.1`
* Safari `13.0.5`

Fixes #59466
  • Loading branch information
andrew-goldstein authored Mar 6, 2020
1 parent be365a4 commit ce31335
Showing 1 changed file with 61 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ DragEffects.displayName = 'DragEffects';
export const DraggablePortalContext = createContext<boolean>(false);
export const useDraggablePortalContext = () => useContext(DraggablePortalContext);

/**
* Wraps the `react-beautiful-dnd` error boundary. See also:
* https://github.com/atlassian/react-beautiful-dnd/blob/v12.0.0/docs/guides/setup-problem-detection-and-error-recovery.md
*
* NOTE: This extends from `PureComponent` because, at the time of this
* writing, there's no hook equivalent for `componentDidCatch`, per
* https://reactjs.org/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes
*/
class DragDropErrorBoundary extends React.PureComponent {
componentDidCatch() {
this.forceUpdate(); // required for recovery
}

render() {
return this.props.children;
}
}

const Wrapper = styled.div`
display: inline-block;
max-width: 100%;
Expand Down Expand Up @@ -94,50 +112,52 @@ export const DraggableWrapper = React.memo<Props>(

return (
<Wrapper data-test-subj="draggableWrapperDiv">
<Droppable isDropDisabled={true} droppableId={getDroppableId(dataProvider.id)}>
{droppableProvided => (
<div ref={droppableProvided.innerRef} {...droppableProvided.droppableProps}>
<Draggable
draggableId={getDraggableId(dataProvider.id)}
index={0}
key={getDraggableId(dataProvider.id)}
>
{(provided, snapshot) => (
<ConditionalPortal
isDragging={snapshot.isDragging}
registerProvider={registerProvider}
usePortal={snapshot.isDragging && usePortal}
>
<ProviderContainer
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
data-test-subj="providerContainer"
<DragDropErrorBoundary>
<Droppable isDropDisabled={true} droppableId={getDroppableId(dataProvider.id)}>
{droppableProvided => (
<div ref={droppableProvided.innerRef} {...droppableProvided.droppableProps}>
<Draggable
draggableId={getDraggableId(dataProvider.id)}
index={0}
key={getDraggableId(dataProvider.id)}
>
{(provided, snapshot) => (
<ConditionalPortal
isDragging={snapshot.isDragging}
registerProvider={registerProvider}
style={{
...provided.draggableProps.style,
}}
usePortal={snapshot.isDragging && usePortal}
>
{truncate && !snapshot.isDragging ? (
<TruncatableText data-test-subj="draggable-truncatable-content">
{render(dataProvider, provided, snapshot)}
</TruncatableText>
) : (
<ProviderContentWrapper
data-test-subj={`draggable-content-${dataProvider.queryMatch.field}`}
>
{render(dataProvider, provided, snapshot)}
</ProviderContentWrapper>
)}
</ProviderContainer>
</ConditionalPortal>
)}
</Draggable>
{droppableProvided.placeholder}
</div>
)}
</Droppable>
<ProviderContainer
{...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}
data-test-subj="providerContainer"
isDragging={snapshot.isDragging}
registerProvider={registerProvider}
style={{
...provided.draggableProps.style,
}}
>
{truncate && !snapshot.isDragging ? (
<TruncatableText data-test-subj="draggable-truncatable-content">
{render(dataProvider, provided, snapshot)}
</TruncatableText>
) : (
<ProviderContentWrapper
data-test-subj={`draggable-content-${dataProvider.queryMatch.field}`}
>
{render(dataProvider, provided, snapshot)}
</ProviderContentWrapper>
)}
</ProviderContainer>
</ConditionalPortal>
)}
</Draggable>
{droppableProvided.placeholder}
</div>
)}
</Droppable>
</DragDropErrorBoundary>
</Wrapper>
);
},
Expand Down

0 comments on commit ce31335

Please sign in to comment.