Browse Source

fix(inbox): Use new tag component for inbox tags (#21952)

Scott Cooper 4 years ago
parent
commit
b44fa1c080

+ 11 - 1
src/sentry/static/sentry/app/components/eventOrGroupExtraDetails.tsx

@@ -41,7 +41,11 @@ function EventOrGroupExtraDetails({data, showAssignee, params, organization}: Pr
 
   return (
     <GroupExtra>
-      {isUnhandled && hasInbox && <UnhandledTag />}
+      {isUnhandled && hasInbox && (
+        <TagWrapper>
+          <UnhandledTag />
+        </TagWrapper>
+      )}
       {shortId && (
         <GroupShortId
           shortId={shortId}
@@ -115,6 +119,12 @@ const GroupExtra = styled('div')`
   }
 `;
 
+const TagWrapper = styled('div')`
+  & > div {
+    margin-right: 0;
+  }
+`;
+
 const StyledTimes = styled(Times)`
   margin-right: 0;
 `;

+ 33 - 64
src/sentry/static/sentry/app/components/group/inboxReason.tsx

@@ -1,12 +1,12 @@
 import React from 'react';
-import styled from '@emotion/styled';
 import moment from 'moment';
+import styled from '@emotion/styled';
 
 import {t} from 'app/locale';
 import {IconSound, IconSwitch, IconSync, IconWarning} from 'app/icons';
-import space from 'app/styles/space';
 import {Group} from 'app/types';
-import Tooltip from 'app/components/tooltip';
+import Tag from 'app/components/tag';
+import DateTime from 'app/components/dateTime';
 
 const GroupInboxReason = {
   NEW: 0,
@@ -20,84 +20,53 @@ type Props = {
 };
 
 const InboxReason = ({data}: Props) => {
-  const {reason, reason_details} = data.inbox || {};
+  const {reason, reason_details, date_added: dateAdded} = data.inbox || {};
 
   let reasonIcon: React.ReactNode;
   let reasonBadgeText: string;
-  let tooltipText: string;
-
-  const tooltipWindowCount = t('%(count)s events within %(window)s occured', {
-    count: reason_details?.count || 0,
-    window: moment.duration(reason_details?.window || 0, 'minutes').humanize(),
-  });
+  let tooltipText: string | undefined;
 
   if (reason === GroupInboxReason.UNIGNORED) {
-    reasonIcon = <IconSound size="11px" color="purple300" />;
+    reasonIcon = <IconSound />;
     reasonBadgeText = t('Unignored');
-    tooltipText = 'This issue was unignored';
+    tooltipText = t('%(count)s events within %(window)s', {
+      count: reason_details?.count || 0,
+      window: moment.duration(reason_details?.window || 0, 'minutes').humanize(),
+    });
   } else if (reason === GroupInboxReason.REGRESSION) {
-    reasonIcon = <IconSync size="11px" color="purple300" />;
+    reasonIcon = <IconSync />;
     reasonBadgeText = t('Regression');
-    tooltipText = 'This issue was a regression';
+    tooltipText = t('Issue was previously resolved.');
   } else if (reason === GroupInboxReason.MANUAL) {
-    reasonIcon = <IconSwitch size="11px" color="purple300" />;
+    reasonIcon = <IconSwitch />;
     reasonBadgeText = t('Manual');
-    tooltipText = 'This issue was moved manually';
+    // TODO(scttcper): Add tooltip text for a manual move
+    // Moved to inbox by {full_name}.
   } else {
-    reasonIcon = <IconWarning size="11px" color="purple300" />;
+    reasonIcon = <IconWarning />;
     reasonBadgeText = t('New Issue');
-    tooltipText = 'This is a new issue';
   }
 
+  const tooltip = (
+    <React.Fragment>
+      {tooltipText && <div>{tooltipText}</div>}
+      {dateAdded && (
+        <DateWrapper>
+          <DateTime date={dateAdded} />
+        </DateWrapper>
+      )}
+    </React.Fragment>
+  );
+
   return (
-    <Container>
-      <Tooltip
-        title={
-          <TooltipTitle>
-            {tooltipText}
-            <br />
-            {tooltipWindowCount}
-          </TooltipTitle>
-        }
-      >
-        <Wrapper>
-          {reasonIcon}
-          <div>{reasonBadgeText}</div>
-        </Wrapper>
-      </Tooltip>
-    </Container>
+    <Tag icon={reasonIcon} tooltipText={tooltip}>
+      {reasonBadgeText}
+    </Tag>
   );
 };
 
-const Container = styled('div')`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
-
-const Wrapper = styled('div')`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  padding: ${space(0.25)} ${space(0.75)};
-
-  background-color: ${p => p.theme.gray100};
-  color: ${p => p.theme.subText};
-  font-size: ${p => p.theme.fontSizeExtraSmall};
-  text-align: center;
-  border-radius: 17px;
-
-  > * :not(:last-child) {
-    margin-right: ${space(0.5)};
-  }
-`;
-
-const TooltipTitle = styled('div')`
-  text-align: left;
+export default InboxReason;
 
-  > * :last-child {
-    font-weight: 400;
-  }
+const DateWrapper = styled('div')`
+  color: ${p => p.theme.gray200};
 `;
-
-export default InboxReason;

+ 17 - 52
src/sentry/static/sentry/app/components/group/timesBadge.tsx

@@ -1,11 +1,10 @@
 import React from 'react';
 import styled from '@emotion/styled';
-import PropTypes from 'prop-types';
 
 import {t} from 'app/locale';
 import {IconClock} from 'app/icons';
-import space from 'app/styles/space';
 import TimeSince from 'app/components/timeSince';
+import Tag from 'app/components/tag';
 
 /**
  * Used in new inbox
@@ -18,61 +17,27 @@ type Props = {
   firstSeen: string;
 };
 
-const Times = ({lastSeen, firstSeen}: Props) => {
+const TimesBadge = ({lastSeen, firstSeen}: Props) => {
   return (
-    <Container>
-      <Wrapper>
-        {lastSeen && (
-          <React.Fragment>
-            <StyledIconClock size="11px" color="purple300" />
-            <TimeSince date={lastSeen} suffix={t('ago')} shorten />
-          </React.Fragment>
-        )}
-        {firstSeen && lastSeen && (
-          <Seperator className="hidden-xs hidden-sm">&nbsp;|&nbsp;</Seperator>
-        )}
-        {firstSeen && (
-          <TimeSince
-            date={firstSeen}
-            suffix={t('old')}
-            className="hidden-xs hidden-sm"
-            shorten
-          />
-        )}
-      </Wrapper>
-    </Container>
+    <Tag icon={lastSeen ? <IconClock /> : undefined}>
+      {lastSeen && <TimeSince date={lastSeen} suffix={t('ago')} shorten />}
+      {firstSeen && lastSeen && (
+        <Seperator className="hidden-xs hidden-sm">&nbsp;|&nbsp;</Seperator>
+      )}
+      {firstSeen && (
+        <TimeSince
+          date={firstSeen}
+          suffix={t('old')}
+          className="hidden-xs hidden-sm"
+          shorten
+        />
+      )}
+    </Tag>
   );
 };
-Times.propTypes = {
-  lastSeen: PropTypes.string,
-  firstSeen: PropTypes.string,
-};
-
-const Container = styled('div')`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
-
-const Wrapper = styled('div')`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  padding: ${space(0.25)} ${space(0.75)};
-
-  background-color: ${p => p.theme.gray100};
-  color: ${p => p.theme.subText};
-  font-size: ${p => p.theme.fontSizeExtraSmall};
-  text-align: center;
-  border-radius: 17px;
-`;
-
-const StyledIconClock = styled(IconClock)`
-  margin-right: ${space(0.5)};
-`;
 
 const Seperator = styled('span')`
   color: ${p => p.theme.subText};
 `;
 
-export default Times;
+export default TimesBadge;

+ 25 - 12
src/sentry/static/sentry/app/components/stream/group.tsx

@@ -31,7 +31,7 @@ import {t} from 'app/locale';
 import Link from 'app/components/links/link';
 import {queryToObj} from 'app/utils/stream';
 import {callIfFunction} from 'app/utils/callIfFunction';
-import Times from 'app/components/group/timesBadge';
+import TimesBadge from 'app/components/group/timesBadge';
 import InboxReason from 'app/components/group/inboxReason';
 
 const DiscoveryExclusionFields: string[] = [
@@ -395,16 +395,20 @@ class StreamGroup extends React.Component<Props, State> {
         {hasInbox && (
           <React.Fragment>
             {inboxTabActive && (
-              <Box width={80} mx={2} className="hidden-xs hidden-sm">
-                <InboxReason data={data} />
-              </Box>
+              <ReasonBox width={95} mx={2} className="hidden-xs hidden-sm">
+                <BadgeWrapper>
+                  <InboxReason data={data} />
+                </BadgeWrapper>
+              </ReasonBox>
             )}
-            <Box width={150} mx={2} className="hidden-xs hidden-sm">
-              <StyledTimes
-                lastSeen={data.lifetime?.lastSeen || data.lastSeen}
-                firstSeen={data.lifetime?.firstSeen || data.firstSeen}
-              />
-            </Box>
+            <TimesBox width={170} mx={2} className="hidden-xs hidden-sm">
+              <BadgeWrapper>
+                <TimesBadge
+                  lastSeen={data.lifetime?.lastSeen || data.lastSeen}
+                  firstSeen={data.lifetime?.firstSeen || data.firstSeen}
+                />
+              </BadgeWrapper>
+            </TimesBox>
           </React.Fragment>
         )}
       </Wrapper>
@@ -422,6 +426,14 @@ const GroupSummary = styled(Box)`
   overflow: hidden;
 `;
 
+const ReasonBox = styled(Box)`
+  margin: 0 ${space(0.25)} 0 ${space(1)};
+`;
+
+const TimesBox = styled(Box)`
+  margin: 0 ${space(1.5)} 0 ${space(0.5)};
+`;
+
 const GroupCheckbox = styled(Box)`
   align-self: flex-start;
   & input[type='checkbox'] {
@@ -486,8 +498,9 @@ const MenuItemText = styled('div')`
   padding-right: ${space(1)};
 `;
 
-const StyledTimes = styled(Times)`
-  margin-right: 0;
+const BadgeWrapper = styled('div')`
+  display: flex;
+  justify-content: center;
 `;
 
 export default withGlobalSelection(withOrganization(StreamGroup));

+ 2 - 2
src/sentry/static/sentry/app/components/tag.tsx

@@ -21,11 +21,11 @@ type Props = React.HTMLAttributes<HTMLSpanElement> & {
   /**
    * Icon on the left side.
    */
-  icon?: React.ReactElement;
+  icon?: React.ReactNode;
   /**
    * Text to show up on a hover.
    */
-  tooltipText?: React.ReactElement | string;
+  tooltipText?: React.ComponentProps<typeof Tooltip>['title'];
   /**
    * Makes the tag clickable. Use for internal links handled by react router.
    * If no icon is passed, it defaults to IconOpen (can be removed by passing icon={null})

+ 4 - 6
src/sentry/static/sentry/app/views/issueList/actions.tsx

@@ -801,15 +801,13 @@ const AssigneesLabel = styled('div')`
 `;
 
 const ReasonSpacerLabel = styled('div')`
-  width: 80px;
-  margin-left: ${space(2)};
-  margin-right: ${space(2)};
+  width: 95px;
+  margin: 0 ${space(0.25)} 0 ${space(1)};
 `;
 
 const TimesSpacerLabel = styled('div')`
-  width: 150px;
-  margin-left: ${space(2)};
-  margin-right: ${space(2)};
+  width: 170px;
+  margin: 0 ${space(1.5)} 0 ${space(0.5)};
 `;
 
 // New icons are misaligned inside bootstrap buttons.