Просмотр исходного кода

feat(breadcrumbs): Sort breadcrumbs by newest -> oldest (#41540)

Fixes https://github.com/getsentry/sentry/issues/41212

The decision was made to reverse the order of the list to reduce
confusion caused by the reverse scroll direction. This also conveniently
makes the code a bit simpler since we don't need the `scrollToIndex`
anymore.
Malachi Willey 2 лет назад
Родитель
Сommit
f3db0c04d9

+ 10 - 31
static/app/components/events/interfaces/breadcrumbs/breadcrumbs.tsx

@@ -1,4 +1,4 @@
-import {useEffect, useRef, useState} from 'react';
+import {useCallback, useEffect, useRef, useState} from 'react';
 import {
   AutoSizer,
   CellMeasurer,
@@ -55,44 +55,28 @@ function Breadcrumbs({
   route,
   router,
 }: Props) {
-  const [scrollToIndex, setScrollToIndex] = useState<number | undefined>(undefined);
   const [scrollbarSize, setScrollbarSize] = useState(0);
   const entryIndex = event.entries.findIndex(
     entry => entry.type === EntryType.BREADCRUMBS
   );
 
-  let listRef: List | null = null;
+  const listRef = useRef<List>(null);
   const contentRef = useRef<HTMLDivElement>(null);
 
-  useEffect(() => {
-    updateGrid();
+  const updateGrid = useCallback(() => {
+    if (listRef.current) {
+      cache.clearAll();
+      listRef.current.forceUpdateGrid();
+    }
   }, []);
 
   useEffect(() => {
-    if (!!breadcrumbs.length && !scrollToIndex) {
-      setScrollToIndex(breadcrumbs.length - 1);
-      return;
-    }
-
     updateGrid();
-  }, [breadcrumbs]);
-
-  useEffect(() => {
-    if (scrollToIndex !== undefined) {
-      updateGrid();
-    }
-  }, [scrollToIndex]);
-
-  function updateGrid() {
-    if (listRef) {
-      cache.clearAll();
-      listRef.forceUpdateGrid();
-    }
-  }
+  }, [breadcrumbs, updateGrid]);
 
   function renderRow({index, key, parent, style}: ListRowProps) {
     const breadcrumb = breadcrumbs[index];
-    const isLastItem = breadcrumbs[breadcrumbs.length - 1].id === breadcrumb.id;
+    const isLastItem = breadcrumbs[0].id === breadcrumb.id;
     const {height} = style;
     return (
       <CellMeasurer
@@ -157,9 +141,7 @@ function Breadcrumbs({
         <AutoSizer disableHeight onResize={updateGrid}>
           {({width}) => (
             <StyledList
-              ref={(el: List | null) => {
-                listRef = el;
-              }}
+              ref={listRef}
               deferredMeasurementCache={cache}
               height={PANEL_MAX_HEIGHT}
               overscanRowCount={5}
@@ -168,9 +150,6 @@ function Breadcrumbs({
               rowRenderer={renderRow}
               width={width}
               onScrollbarPresenceChange={({size}) => setScrollbarSize(size)}
-              // when the component mounts, it scrolls to the last item
-              scrollToIndex={scrollToIndex}
-              scrollToAlignment={scrollToIndex ? 'end' : undefined}
             />
           )}
         </AutoSizer>

+ 3 - 2
static/app/components/events/interfaces/breadcrumbs/index.tsx

@@ -1,6 +1,7 @@
 import {Fragment, useEffect, useState} from 'react';
 import styled from '@emotion/styled';
 import omit from 'lodash/omit';
+import orderBy from 'lodash/orderBy';
 import pick from 'lodash/pick';
 
 import GuideAnchor from 'sentry/components/assistant/guideAnchor';
@@ -82,13 +83,13 @@ function BreadcrumbsContainer({
   }, []); // eslint-disable-line react-hooks/exhaustive-deps
 
   function loadBreadcrumbs() {
-    let crumbs = data.values;
+    let crumbs = orderBy(data.values, 'timestamp', 'desc');
 
     // Add the (virtual) breadcrumb based on the error or message event if possible.
     const virtualCrumb = getVirtualCrumb(event);
 
     if (virtualCrumb) {
-      crumbs = [...crumbs, virtualCrumb];
+      crumbs = [virtualCrumb, ...crumbs];
     }
 
     const transformedCrumbs = transformCrumbs(crumbs);