From b96d7fe4bf66c63b880212fe2539da15fb0950f2 Mon Sep 17 00:00:00 2001 From: David Wang Date: Fri, 8 Oct 2021 14:54:56 -0700 Subject: [PATCH 1/8] using teams utility for fetching teams --- .../discover/teamKeyTransactionField.tsx | 6 +-- .../app/views/performance/landing/content.tsx | 35 ++++++------ .../app/views/performance/landing/index.tsx | 37 +++++++------ .../teamKeyTransactionButton.tsx | 47 ++++++++-------- .../vitalDetail/vitalDetailContent.tsx | 53 ++++++++++--------- 5 files changed, 94 insertions(+), 84 deletions(-) diff --git a/static/app/utils/discover/teamKeyTransactionField.tsx b/static/app/utils/discover/teamKeyTransactionField.tsx index 143d2b32593245..03c90a47cd6705 100644 --- a/static/app/utils/discover/teamKeyTransactionField.tsx +++ b/static/app/utils/discover/teamKeyTransactionField.tsx @@ -7,10 +7,9 @@ import TeamKeyTransaction, { import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTransactionsManager'; import Tooltip from 'app/components/tooltip'; import {IconStar} from 'app/icons'; -import {Organization, Project, Team} from 'app/types'; +import {Organization, Project} from 'app/types'; import {defined} from 'app/utils'; import withProjects from 'app/utils/withProjects'; -import withTeams from 'app/utils/withTeams'; class TitleStar extends Component { render() { @@ -34,7 +33,6 @@ class TitleStar extends Component { } type BaseProps = { - teams: Team[]; organization: Organization; isKeyTransaction: boolean; }; @@ -112,4 +110,4 @@ function TeamKeyTransactionFieldWrapper({ ); } -export default withTeams(withProjects(TeamKeyTransactionFieldWrapper)); +export default withProjects(TeamKeyTransactionFieldWrapper); diff --git a/static/app/views/performance/landing/content.tsx b/static/app/views/performance/landing/content.tsx index a594ba140854a4..28ff08154c676f 100644 --- a/static/app/views/performance/landing/content.tsx +++ b/static/app/views/performance/landing/content.tsx @@ -5,6 +5,7 @@ import {Location} from 'history'; import DropdownControl, {DropdownItem} from 'app/components/dropdownControl'; import SearchBar from 'app/components/events/searchBar'; +import LoadingIndicator from 'app/components/loadingIndicator'; import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTransactionsManager'; import {MAX_QUERY_LENGTH} from 'app/constants'; import {t} from 'app/locale'; @@ -13,10 +14,9 @@ import {Organization, Project, Team} from 'app/types'; import {trackAnalyticsEvent} from 'app/utils/analytics'; import EventView from 'app/utils/discover/eventView'; import {generateAggregateFields} from 'app/utils/discover/fields'; -import {isActiveSuperuser} from 'app/utils/isActiveSuperuser'; import {decodeScalar} from 'app/utils/queryString'; +import Teams from 'app/utils/teams'; import {MutableSearch} from 'app/utils/tokenizeSearch'; -import withTeams from 'app/utils/withTeams'; import Charts from '../charts/index'; import { @@ -265,14 +265,11 @@ class LandingContent extends Component { }; render() { - const {organization, location, eventView, projects, teams, handleSearch} = this.props; + const {organization, location, eventView, projects, handleSearch} = this.props; const currentLandingDisplay = getCurrentLandingDisplay(location, projects, eventView); const filterString = getTransactionSearchQuery(location, eventView.query); - const isSuperuser = isActiveSuperuser(); - const userTeams = teams.filter(({isMember}) => isMember || isSuperuser); - return ( @@ -308,14 +305,22 @@ class LandingContent extends Component { ))} - - {this.renderSelectedDisplay(currentLandingDisplay.field)} - + + {({teams, initiallyLoaded}) => + initiallyLoaded ? ( + + {this.renderSelectedDisplay(currentLandingDisplay.field)} + + ) : ( + + ) + } + ); } @@ -331,4 +336,4 @@ const SearchContainer = styled('div')` } `; -export default withRouter(withTeams(LandingContent)); +export default withRouter(LandingContent); diff --git a/static/app/views/performance/landing/index.tsx b/static/app/views/performance/landing/index.tsx index 82622d514a910d..049109ec66e79c 100644 --- a/static/app/views/performance/landing/index.tsx +++ b/static/app/views/performance/landing/index.tsx @@ -6,18 +6,18 @@ import Button from 'app/components/button'; import SearchBar from 'app/components/events/searchBar'; import GlobalSdkUpdateAlert from 'app/components/globalSdkUpdateAlert'; import * as Layout from 'app/components/layouts/thirds'; +import LoadingIndicator from 'app/components/loadingIndicator'; import NavTabs from 'app/components/navTabs'; import PageHeading from 'app/components/pageHeading'; import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTransactionsManager'; import {MAX_QUERY_LENGTH} from 'app/constants'; import {t} from 'app/locale'; import space from 'app/styles/space'; -import {Organization, Project, Team} from 'app/types'; +import {Organization, Project} from 'app/types'; import EventView from 'app/utils/discover/eventView'; import {generateAggregateFields} from 'app/utils/discover/fields'; -import {isActiveSuperuser} from 'app/utils/isActiveSuperuser'; import {OpBreakdownFilterProvider} from 'app/utils/performance/contexts/operationBreakdownFilter'; -import withTeams from 'app/utils/withTeams'; +import Teams from 'app/utils/teams'; import Filter, {SpanOperationBreakdownFilter} from '../transactionSummary/filter'; import {getTransactionSearchQuery} from '../utils'; @@ -39,7 +39,6 @@ type Props = { eventView: EventView; location: Location; projects: Project[]; - teams: Team[]; shouldShowOnboarding: boolean; setError: (msg: string | undefined) => void; handleSearch: (searchQuery: string) => void; @@ -60,7 +59,6 @@ function _PerformanceLanding(props: Props) { location, eventView, projects, - teams, handleSearch, handleTrendsClick, shouldShowOnboarding, @@ -69,9 +67,6 @@ function _PerformanceLanding(props: Props) { const currentLandingDisplay = getCurrentLandingDisplay(location, projects, eventView); const filterString = getTransactionSearchQuery(location, eventView.query); - const isSuperuser = isActiveSuperuser(); - const userTeams = teams.filter(({isMember}) => isMember || isSuperuser); - const [spanFilter, setSpanFilter] = useState(SpanOperationBreakdownFilter.None); const showOnboarding = shouldShowOnboarding; @@ -136,14 +131,22 @@ function _PerformanceLanding(props: Props) { maxQueryLength={MAX_QUERY_LENGTH} /> - - - + + {({teams, initiallyLoaded}) => + initiallyLoaded ? ( + + + + ) : ( + + ) + } + @@ -151,7 +154,7 @@ function _PerformanceLanding(props: Props) { ); } -export const PerformanceLanding = withTeams(_PerformanceLanding); +export const PerformanceLanding = _PerformanceLanding; const StyledHeading = styled(PageHeading)` line-height: 40px; diff --git a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx index 68e16134b2b602..0faf1c31f6e274 100644 --- a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx +++ b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx @@ -11,9 +11,8 @@ import {t, tn} from 'app/locale'; import {Organization, Project, Team} from 'app/types'; import {defined} from 'app/utils'; import EventView from 'app/utils/discover/eventView'; -import {isActiveSuperuser} from 'app/utils/isActiveSuperuser'; +import Teams from 'app/utils/teams'; import withProjects from 'app/utils/withProjects'; -import withTeams from 'app/utils/withTeams'; /** * This can't be a function component because `TeamKeyTransaction` uses @@ -82,7 +81,6 @@ type WrapperProps = BaseProps & { function TeamKeyTransactionButtonWrapper({ eventView, organization, - teams, projects, ...props }: WrapperProps) { @@ -96,28 +94,29 @@ function TeamKeyTransactionButtonWrapper({ return ; } - const isSuperuser = isActiveSuperuser(); - const userTeams = teams.filter(({isMember}) => isMember || isSuperuser); - return ( - - - {results => ( - - )} - - + + {({teams}) => ( + + + {results => ( + + )} + + + )} + ); } -export default withTeams(withProjects(TeamKeyTransactionButtonWrapper)); +export default withProjects(TeamKeyTransactionButtonWrapper); diff --git a/static/app/views/performance/vitalDetail/vitalDetailContent.tsx b/static/app/views/performance/vitalDetail/vitalDetailContent.tsx index 4c64c7d755b43b..3506796901f733 100644 --- a/static/app/views/performance/vitalDetail/vitalDetailContent.tsx +++ b/static/app/views/performance/vitalDetail/vitalDetailContent.tsx @@ -11,21 +11,21 @@ import ButtonBar from 'app/components/buttonBar'; import {CreateAlertFromViewButton} from 'app/components/createAlertButton'; import SearchBar from 'app/components/events/searchBar'; import * as Layout from 'app/components/layouts/thirds'; +import LoadingIndicator from 'app/components/loadingIndicator'; import {getParams} from 'app/components/organizations/globalSelectionHeader/getParams'; import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTransactionsManager'; import {IconChevron} from 'app/icons'; import {IconFlag} from 'app/icons/iconFlag'; import {t} from 'app/locale'; import space from 'app/styles/space'; -import {Organization, Project, Team} from 'app/types'; +import {Organization, Project} from 'app/types'; import {generateQueryWithTag} from 'app/utils'; import EventView from 'app/utils/discover/eventView'; import {WebVital} from 'app/utils/discover/fields'; -import {isActiveSuperuser} from 'app/utils/isActiveSuperuser'; import {decodeScalar} from 'app/utils/queryString'; +import Teams from 'app/utils/teams'; import {MutableSearch} from 'app/utils/tokenizeSearch'; import withProjects from 'app/utils/withProjects'; -import withTeams from 'app/utils/withTeams'; import Breadcrumb from '../breadcrumb'; import {getTransactionSearchQuery} from '../utils'; @@ -42,7 +42,6 @@ type Props = { eventView: EventView; organization: Organization; projects: Project[]; - teams: Team[]; router: InjectedRouter; vitalName: WebVital; @@ -178,7 +177,7 @@ class VitalDetailContent extends React.Component { } render() { - const {location, eventView, organization, vitalName, projects, teams} = this.props; + const {location, eventView, organization, vitalName, projects} = this.props; const {incompatibleAlertNotice} = this.state; const query = decodeScalar(location.query.query, ''); @@ -188,9 +187,6 @@ class VitalDetailContent extends React.Component { const summaryConditions = getSummaryConditions(filterString); const description = vitalDescription[vitalName]; - const isSuperuser = isActiveSuperuser(); - const userTeams = teams.filter(({isMember}) => isMember || isSuperuser); - return ( @@ -238,21 +234,30 @@ class VitalDetailContent extends React.Component { - - - + + + {({teams, initiallyLoaded}) => + initiallyLoaded ? ( + +
+ + ) : ( + + ) + } + @@ -273,4 +278,4 @@ const StyledVitalInfo = styled('div')` margin-bottom: ${space(3)}; `; -export default withTeams(withProjects(VitalDetailContent)); +export default withProjects(VitalDetailContent); From 11f68fd5a8f03abd0ddb6a84e1a67657a94644f2 Mon Sep 17 00:00:00 2001 From: David Wang Date: Mon, 11 Oct 2021 12:45:40 -0700 Subject: [PATCH 2/8] fixing tests --- .../transactionSummary/teamKeyTransactionButton.tsx | 3 +-- tests/js/spec/views/performance/content.spec.jsx | 2 ++ tests/js/spec/views/performance/landing/index.spec.tsx | 3 +++ tests/js/spec/views/performance/vitalDetail/index.spec.jsx | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx index 0faf1c31f6e274..031683e2844f20 100644 --- a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx +++ b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx @@ -8,7 +8,7 @@ import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTr import Tooltip from 'app/components/tooltip'; import {IconStar} from 'app/icons'; import {t, tn} from 'app/locale'; -import {Organization, Project, Team} from 'app/types'; +import {Organization, Project} from 'app/types'; import {defined} from 'app/utils'; import EventView from 'app/utils/discover/eventView'; import Teams from 'app/utils/teams'; @@ -45,7 +45,6 @@ class TitleButton extends Component { type BaseProps = { organization: Organization; transactionName: string; - teams: Team[]; }; type Props = BaseProps & diff --git a/tests/js/spec/views/performance/content.spec.jsx b/tests/js/spec/views/performance/content.spec.jsx index 2eb5f636a081fe..71f9fbaf535217 100644 --- a/tests/js/spec/views/performance/content.spec.jsx +++ b/tests/js/spec/views/performance/content.spec.jsx @@ -6,6 +6,7 @@ import {act} from 'sentry-test/reactTestingLibrary'; import * as globalSelection from 'app/actionCreators/globalSelection'; import ProjectsStore from 'app/stores/projectsStore'; +import TeamStore from 'app/stores/teamStore'; import {OrganizationContext} from 'app/views/organizationContext'; import PerformanceContent from 'app/views/performance/content'; import {DEFAULT_MAX_DURATION} from 'app/views/performance/trends/utils'; @@ -63,6 +64,7 @@ function initializeTrendsData(query, addDefaultQuery = true) { describe('Performance > Content', function () { beforeEach(function () { + act(() => void TeamStore.loadInitialData([])); browserHistory.push = jest.fn(); jest.spyOn(globalSelection, 'updateDateTime'); diff --git a/tests/js/spec/views/performance/landing/index.spec.tsx b/tests/js/spec/views/performance/landing/index.spec.tsx index c027103538ca5d..36599443acc4b1 100644 --- a/tests/js/spec/views/performance/landing/index.spec.tsx +++ b/tests/js/spec/views/performance/landing/index.spec.tsx @@ -1,6 +1,8 @@ import {mountWithTheme} from 'sentry-test/enzyme'; import {initializeData} from 'sentry-test/performance/initializePerformanceData'; +import {act} from 'sentry-test/reactTestingLibrary'; +import TeamStore from 'app/stores/teamStore'; import EventView from 'app/utils/discover/eventView'; import {OrganizationContext} from 'app/views/organizationContext'; import {PerformanceLanding} from 'app/views/performance/landing'; @@ -28,6 +30,7 @@ const WrappedComponent = ({data}) => { describe('Performance > Landing > Index', function () { let eventStatsMock: any; let eventsV2Mock: any; + act(() => void TeamStore.loadInitialData([])); beforeEach(function () { // @ts-expect-error MockApiClient.addMockResponse({ diff --git a/tests/js/spec/views/performance/vitalDetail/index.spec.jsx b/tests/js/spec/views/performance/vitalDetail/index.spec.jsx index bd4e12f330299a..a97e08adffbfed 100644 --- a/tests/js/spec/views/performance/vitalDetail/index.spec.jsx +++ b/tests/js/spec/views/performance/vitalDetail/index.spec.jsx @@ -5,6 +5,7 @@ import {initializeOrg} from 'sentry-test/initializeOrg'; import {act} from 'sentry-test/reactTestingLibrary'; import ProjectsStore from 'app/stores/projectsStore'; +import TeamStore from 'app/stores/teamStore'; import {OrganizationContext} from 'app/views/organizationContext'; import VitalDetail from 'app/views/performance/vitalDetail/'; @@ -39,6 +40,7 @@ const WrappedComponent = ({organization, ...rest}) => { describe('Performance > VitalDetail', function () { beforeEach(function () { + act(() => void TeamStore.loadInitialData([])); browserHistory.push = jest.fn(); MockApiClient.addMockResponse({ url: '/organizations/org-slug/projects/', From 312b09f70b0078884ade7f3f087e5df0ef389f75 Mon Sep 17 00:00:00 2001 From: David Wang Date: Mon, 11 Oct 2021 13:06:40 -0700 Subject: [PATCH 3/8] fixing tsx --- static/app/views/performance/landing/content.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/static/app/views/performance/landing/content.tsx b/static/app/views/performance/landing/content.tsx index 28ff08154c676f..886aa7de552307 100644 --- a/static/app/views/performance/landing/content.tsx +++ b/static/app/views/performance/landing/content.tsx @@ -10,7 +10,7 @@ import * as TeamKeyTransactionManager from 'app/components/performance/teamKeyTr import {MAX_QUERY_LENGTH} from 'app/constants'; import {t} from 'app/locale'; import space from 'app/styles/space'; -import {Organization, Project, Team} from 'app/types'; +import {Organization, Project} from 'app/types'; import {trackAnalyticsEvent} from 'app/utils/analytics'; import EventView from 'app/utils/discover/eventView'; import {generateAggregateFields} from 'app/utils/discover/fields'; @@ -52,7 +52,6 @@ type Props = { eventView: EventView; location: Location; projects: Project[]; - teams: Team[]; setError: (msg: string | undefined) => void; handleSearch: (searchQuery: string) => void; } & WithRouterProps; From c622078c0f05115a5373b728cf2b30373d6653b6 Mon Sep 17 00:00:00 2001 From: David Wang Date: Tue, 12 Oct 2021 11:42:00 -0700 Subject: [PATCH 4/8] useTeams and loading state for button --- .../teamKeyTransactionButton.tsx | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx index 031683e2844f20..b3124896b876c9 100644 --- a/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx +++ b/static/app/views/performance/transactionSummary/teamKeyTransactionButton.tsx @@ -11,7 +11,7 @@ import {t, tn} from 'app/locale'; import {Organization, Project} from 'app/types'; import {defined} from 'app/utils'; import EventView from 'app/utils/discover/eventView'; -import Teams from 'app/utils/teams'; +import useTeams from 'app/utils/useTeams'; import withProjects from 'app/utils/withProjects'; /** @@ -83,6 +83,8 @@ function TeamKeyTransactionButtonWrapper({ projects, ...props }: WrapperProps) { + const {teams, initiallyLoaded} = useTeams({provideUserTeams: true}); + if (eventView.project.length !== 1) { return ; } @@ -94,27 +96,24 @@ function TeamKeyTransactionButtonWrapper({ } return ( - - {({teams}) => ( - - - {results => ( - - )} - - - )} - + + + {({isLoading, ...results}) => ( + + )} + + ); } From d2c5abd5e022a1368e310d91ece9744018dce85c Mon Sep 17 00:00:00 2001 From: David Wang Date: Tue, 12 Oct 2021 11:47:24 -0700 Subject: [PATCH 5/8] function component should use hook --- .../app/views/performance/landing/index.tsx | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/static/app/views/performance/landing/index.tsx b/static/app/views/performance/landing/index.tsx index 049109ec66e79c..b0c6982e046079 100644 --- a/static/app/views/performance/landing/index.tsx +++ b/static/app/views/performance/landing/index.tsx @@ -17,7 +17,7 @@ import {Organization, Project} from 'app/types'; import EventView from 'app/utils/discover/eventView'; import {generateAggregateFields} from 'app/utils/discover/fields'; import {OpBreakdownFilterProvider} from 'app/utils/performance/contexts/operationBreakdownFilter'; -import Teams from 'app/utils/teams'; +import useTeams from 'app/utils/useTeams'; import Filter, {SpanOperationBreakdownFilter} from '../transactionSummary/filter'; import {getTransactionSearchQuery} from '../utils'; @@ -64,6 +64,8 @@ function _PerformanceLanding(props: Props) { shouldShowOnboarding, } = props; + const {teams, initiallyLoaded} = useTeams({provideUserTeams: true}); + const currentLandingDisplay = getCurrentLandingDisplay(location, projects, eventView); const filterString = getTransactionSearchQuery(location, eventView.query); @@ -131,22 +133,18 @@ function _PerformanceLanding(props: Props) { maxQueryLength={MAX_QUERY_LENGTH} /> - - {({teams, initiallyLoaded}) => - initiallyLoaded ? ( - - - - ) : ( - - ) - } - + {initiallyLoaded ? ( + + + + ) : ( + + )} From defcc8b45d398fb2ef5cd3a33172e2c5cee9ffbf Mon Sep 17 00:00:00 2001 From: David Wang Date: Wed, 13 Oct 2021 11:41:07 -0700 Subject: [PATCH 6/8] directly export performance landing --- static/app/views/performance/landing/index.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/static/app/views/performance/landing/index.tsx b/static/app/views/performance/landing/index.tsx index b0c6982e046079..3c15c096fc7b8f 100644 --- a/static/app/views/performance/landing/index.tsx +++ b/static/app/views/performance/landing/index.tsx @@ -53,7 +53,7 @@ const fieldToViewMap: Record> = { [LandingDisplayField.MOBILE]: MobileView, }; -function _PerformanceLanding(props: Props) { +export function PerformanceLanding(props: Props) { const { organization, location, @@ -152,8 +152,6 @@ function _PerformanceLanding(props: Props) { ); } -export const PerformanceLanding = _PerformanceLanding; - const StyledHeading = styled(PageHeading)` line-height: 40px; `; From 75830ae22751ab47a3e5b1ebdca3c24216d7a965 Mon Sep 17 00:00:00 2001 From: David Wang Date: Wed, 3 Nov 2021 15:00:22 -0700 Subject: [PATCH 7/8] stackTrace --- .../events/interfaces/stackTrace.tsx | 89 ------------------- 1 file changed, 89 deletions(-) delete mode 100644 static/app/components/events/interfaces/stackTrace.tsx diff --git a/static/app/components/events/interfaces/stackTrace.tsx b/static/app/components/events/interfaces/stackTrace.tsx deleted file mode 100644 index d47db9f218f967..00000000000000 --- a/static/app/components/events/interfaces/stackTrace.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import {useState} from 'react'; - -import EventDataSection from 'app/components/events/eventDataSection'; -import CrashContent from 'app/components/events/interfaces/crashContent'; -import CrashActions from 'app/components/events/interfaces/crashHeader/crashActions'; -import CrashTitle from 'app/components/events/interfaces/crashHeader/crashTitle'; -import {t} from 'app/locale'; -import {Group, Project} from 'app/types'; -import {Event} from 'app/types/event'; -import {STACK_TYPE, STACK_VIEW} from 'app/types/stacktrace'; - -import NoStackTraceMessage from './noStackTraceMessage'; -import {isStacktraceNewestFirst} from './utils'; - -type CrashContentProps = React.ComponentProps; - -type Props = Pick< - CrashContentProps, - 'groupingCurrentLevel' | 'hasHierarchicalGrouping' -> & { - event: Event; - type: string; - data: NonNullable; - projectId: Project['id']; - groupingCurrentLevel?: Group['metadata']['current_level']; - hideGuide?: boolean; -}; - -function StacktraceInterface({ - hideGuide = false, - projectId, - event, - data, - type, - hasHierarchicalGrouping, - groupingCurrentLevel, -}: Props) { - const [stackView, setStackView] = useState( - data.hasSystemFrames ? STACK_VIEW.APP : STACK_VIEW.FULL - ); - const [newestFirst, setNewestFirst] = useState(isStacktraceNewestFirst()); - - const stackTraceNotFound = !(data.frames ?? []).length; - - return ( - setNewestFirst(value.newestFirst) : undefined - } - /> - } - actions={ - !stackTraceNotFound && ( - setStackView(value.stackView ?? stackView)} - /> - ) - } - wrapTitle={false} - > - {stackTraceNotFound ? ( - - ) : ( - - )} - - ); -} - -export default StacktraceInterface; From 5f822c5d9cf7a1c3f44e168baad5495a415d9bc6 Mon Sep 17 00:00:00 2001 From: David Wang Date: Wed, 3 Nov 2021 15:02:33 -0700 Subject: [PATCH 8/8] stackTrace again --- .../events/interfaces/stackTrace.tsx | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 static/app/components/events/interfaces/stackTrace.tsx diff --git a/static/app/components/events/interfaces/stackTrace.tsx b/static/app/components/events/interfaces/stackTrace.tsx new file mode 100644 index 00000000000000..d47db9f218f967 --- /dev/null +++ b/static/app/components/events/interfaces/stackTrace.tsx @@ -0,0 +1,89 @@ +import {useState} from 'react'; + +import EventDataSection from 'app/components/events/eventDataSection'; +import CrashContent from 'app/components/events/interfaces/crashContent'; +import CrashActions from 'app/components/events/interfaces/crashHeader/crashActions'; +import CrashTitle from 'app/components/events/interfaces/crashHeader/crashTitle'; +import {t} from 'app/locale'; +import {Group, Project} from 'app/types'; +import {Event} from 'app/types/event'; +import {STACK_TYPE, STACK_VIEW} from 'app/types/stacktrace'; + +import NoStackTraceMessage from './noStackTraceMessage'; +import {isStacktraceNewestFirst} from './utils'; + +type CrashContentProps = React.ComponentProps; + +type Props = Pick< + CrashContentProps, + 'groupingCurrentLevel' | 'hasHierarchicalGrouping' +> & { + event: Event; + type: string; + data: NonNullable; + projectId: Project['id']; + groupingCurrentLevel?: Group['metadata']['current_level']; + hideGuide?: boolean; +}; + +function StacktraceInterface({ + hideGuide = false, + projectId, + event, + data, + type, + hasHierarchicalGrouping, + groupingCurrentLevel, +}: Props) { + const [stackView, setStackView] = useState( + data.hasSystemFrames ? STACK_VIEW.APP : STACK_VIEW.FULL + ); + const [newestFirst, setNewestFirst] = useState(isStacktraceNewestFirst()); + + const stackTraceNotFound = !(data.frames ?? []).length; + + return ( + setNewestFirst(value.newestFirst) : undefined + } + /> + } + actions={ + !stackTraceNotFound && ( + setStackView(value.stackView ?? stackView)} + /> + ) + } + wrapTitle={false} + > + {stackTraceNotFound ? ( + + ) : ( + + )} + + ); +} + +export default StacktraceInterface;