Browse Source

ref(ts) Update TagDistributionMeter to typescript (#16794)

Mark Story 5 years ago
parent
commit
1570450d97

+ 51 - 16
src/sentry/static/sentry/app/components/tagDistributionMeter.jsx → src/sentry/static/sentry/app/components/tagDistributionMeter.tsx

@@ -1,5 +1,6 @@
 import React from 'react';
 import {Link} from 'react-router';
+import {LocationDescriptor} from 'history';
 import PropTypes from 'prop-types';
 import styled from '@emotion/styled';
 import isPropValid from '@emotion/is-prop-valid';
@@ -10,7 +11,36 @@ import overflowEllipsis from 'app/styles/overflowEllipsis';
 import {percent} from 'app/utils';
 import Tooltip from 'app/components/tooltip';
 
-export default class TagDistributionMeter extends React.Component {
+type DefaultProps = {
+  isLoading: boolean;
+  hasError: boolean;
+  renderLoading: () => React.ReactNode;
+  renderEmpty: () => React.ReactNode;
+  renderError: () => React.ReactNode;
+};
+
+export type TagSegment = {
+  count: number;
+  name: string;
+  value: string;
+  url: LocationDescriptor;
+  isOther?: boolean;
+};
+
+type Props = DefaultProps & {
+  title: string;
+  segments: TagSegment[];
+  totalValues: number;
+  onTagClick?: (title: string, value: TagSegment) => void;
+};
+
+type SegmentValue = {
+  to: LocationDescriptor;
+  onClick: () => void;
+  index: number;
+};
+
+export default class TagDistributionMeter extends React.Component<Props> {
   static propTypes = {
     title: PropTypes.string.isRequired,
     totalValues: PropTypes.number,
@@ -30,7 +60,7 @@ export default class TagDistributionMeter extends React.Component {
     onTagClick: PropTypes.func,
   };
 
-  static defaultProps = {
+  static defaultProps: DefaultProps = {
     isLoading: false,
     hasError: false,
     renderLoading: () => null,
@@ -102,25 +132,20 @@ export default class TagDistributionMeter extends React.Component {
             </React.Fragment>
           );
 
-          const segmentProps = {
-            isOther: value.isOther,
+          const segmentProps: SegmentValue = {
             index,
-          };
-          if (!value.isOther) {
-            segmentProps.to = value.url;
-            segmentProps.onClick = () => {
+            to: value.url,
+            onClick: () => {
               if (onTagClick) {
                 onTagClick(title, value);
               }
-            };
-          } else {
-            segmentProps.as = 'span';
-          }
+            },
+          };
 
           return (
             <div key={value.value} style={{width: pct + '%'}}>
               <Tooltip title={tooltipHtml} containerDisplayMode="block">
-                <Segment {...segmentProps} />
+                {value.isOther ? <OtherSegment /> : <Segment {...segmentProps} />}
               </Tooltip>
             </div>
           );
@@ -141,6 +166,7 @@ export default class TagDistributionMeter extends React.Component {
         name: t('Other'),
         value: 'other',
         count: totalValues - totalVisible,
+        url: '',
       });
     }
 
@@ -175,7 +201,7 @@ const SegmentBar = styled('div')`
   border-radius: 2px;
 `;
 
-const Title = styled('div', {shouldForwardProp: isPropValid})`
+const Title = styled('div')`
   display: flex;
   font-size: ${p => p.theme.fontSizeSmall};
   justify-content: space-between;
@@ -204,11 +230,20 @@ const Percent = styled('div')`
   color: ${p => p.theme.gray4};
 `;
 
-const Segment = styled(Link, {shouldForwardProp: isPropValid})`
+const OtherSegment = styled('span')`
+  display: block;
+  width: 100%;
+  height: 16px;
+  color: inherit;
+  outline: none;
+  background-color: ${COLORS[COLORS.length - 1]};
+`;
+
+const Segment = styled(Link, {shouldForwardProp: isPropValid})<SegmentValue>`
   display: block;
   width: 100%;
   height: 16px;
   color: inherit;
   outline: none;
-  background-color: ${p => (p.isOther ? COLORS[COLORS.length - 1] : COLORS[p.index])};
+  background-color: ${p => COLORS[p.index]};
 `;

+ 4 - 4
src/sentry/static/sentry/app/views/eventsV2/tags.tsx

@@ -10,14 +10,14 @@ import {Client} from 'app/api';
 import SentryTypes from 'app/sentryTypes';
 import EmptyStateWarning from 'app/components/emptyStateWarning';
 import Placeholder from 'app/components/placeholder';
-import TagDistributionMeter from 'app/components/tagDistributionMeter';
+import TagDistributionMeter, {TagSegment} from 'app/components/tagDistributionMeter';
 import withApi from 'app/utils/withApi';
 import {Organization} from 'app/types';
 import {generateQueryWithTag} from 'app/utils';
 import {trackAnalyticsEvent} from 'app/utils/analytics';
 import {SectionHeading} from './styles';
 
-import {fetchTagFacets, fetchTotalCount, Tag, TagTopValue} from './utils';
+import {fetchTagFacets, fetchTotalCount, Tag} from './utils';
 import EventView, {isAPIPayloadSimilar} from './eventView';
 
 type Props = {
@@ -103,7 +103,7 @@ class Tags extends React.Component<Props, State> {
     const {organization, eventView} = this.props;
     const {totalValues} = this.state;
 
-    const segments: TagTopValue[] = tag.topValues.map(segment => {
+    const segments: TagSegment[] = tag.topValues.map(segment => {
       const url = eventView.getResultsViewUrlTarget(organization.slug);
       url.query = generateQueryWithTag(url.query, {
         key: tag.key,
@@ -119,7 +119,7 @@ class Tags extends React.Component<Props, State> {
         key={tag.key}
         title={tag.key}
         segments={segments}
-        totalValues={totalValues}
+        totalValues={Number(totalValues)}
         renderLoading={() => <StyledPlaceholder height="16px" />}
         onTagClick={this.onTagClick}
       />

+ 2 - 10
src/sentry/static/sentry/app/views/eventsV2/utils.tsx

@@ -15,6 +15,7 @@ import {Event, Organization, OrganizationSummary} from 'app/types';
 import {Client} from 'app/api';
 import {getTitle} from 'app/utils/events';
 import {getUtcDateString} from 'app/utils/dates';
+import {TagSegment} from 'app/components/tagDistributionMeter';
 import {URL_PARAM} from 'app/constants/globalSelectionHeader';
 import {disableMacros} from 'app/views/discover/result/utils';
 import {appendTagCondition} from 'app/utils/queryString';
@@ -97,18 +98,9 @@ export function isAggregateField(field: string): boolean {
   );
 }
 
-export type TagTopValue = {
-  name: string;
-  url: {
-    pathname: string;
-    query: any;
-  };
-  value: string;
-};
-
 export type Tag = {
   key: string;
-  topValues: Array<TagTopValue>;
+  topValues: Array<TagSegment>;
 };
 
 /**

+ 2 - 1
tests/js/spec/components/group/tagDistributionMeter.spec.jsx

@@ -66,7 +66,8 @@ describe('TagDistributionMeter', function() {
 
     it('should call renderSegments() if values present', function() {
       element.setState({loading: false, error: false});
-      expect(element.find('Segment').length).toEqual(3);
+      expect(element.find('Segment').length).toEqual(2);
+      expect(element.find('OtherSegment').length).toEqual(1);
     });
   });
 });