Browse Source

Assistant fixes (#7846)

* Assistant fixes

- Remove steps that don't have an anchor
- Make issue guide work with thread interface
- Adjust language in guides
adhiraj 7 years ago
parent
commit
f1f4b69df9

+ 15 - 16
src/sentry/assistant/guides.py

@@ -12,15 +12,14 @@ GUIDES = {
             {
                 'title': _('Stacktrace'),
                 'message': _(
-                    'See the sequence of function calls that led to the error, and global/local '
-                    'variables for each stack frame.'),
+                    'See the sequence of function calls that led to the error, and in some cases '
+                    'global/local variables for each stack frame.'),
                 'target': 'exception',
             },
             {
                 'title': _('Breadcrumbs'),
                 'message': _(
-                    'Breadcrumbs (when sent with the event) appear below the stacktrace and show '
-                    'you a trail of events that happened prior to the error. They\'re '
+                    'Breadcrumbs are a trail of events that happened prior to the error. They\'re '
                     'similar to traditional logs but can record more rich structured data. '
                     'When Sentry is used with web frameworks, breadcrumbs are automatically '
                     'captured for events like database calls and network requests.'),
@@ -29,10 +28,10 @@ GUIDES = {
             {
                 'title': _('Tags'),
                 'message': _(
-                    'Tags are arbitrary key-value pairs sent with every event. You can filter '
-                    'events by tags, like searching for all events from a specific machine, '
-                    'browser, release etc. The sidebar on the right shows you the '
-                    'distribution of tags for all events in this event group.'),
+                    'Tags are arbitrary key-value pairs you can send with an event. Events can be '
+                    'filtered by tags, allowing you to do things like search for all events from '
+                    'a specific machine, browser or release. The sidebar on the right shows you '
+                    'the distribution of tags for all events in this event group.'),
                 'target': 'tags',
             },
             {
@@ -46,7 +45,7 @@ GUIDES = {
             {
                 'title': _('Issue Number'),
                 'message': _(
-                    'This is a unique identifier for the issue, and can be included in a commit '
+                    'This is a unique identifier for the issue and can be included in a commit '
                     'message to tell Sentry to resolve the issue when the commit gets deployed. '
                     'See <a href="https://docs.sentry.io/learn/releases/">Releases</a> '
                     'to learn more.'),
@@ -62,13 +61,12 @@ GUIDES = {
             {
                 'title': _('Ignore, Delete and Discard'),
                 'message': _(
-                    'Ignoring an issue silences notifications and removes it from your feeds by '
-                    'default. Deleting an issue deletes the data associated with an issue and '
-                    'causes a new issue to be created if the same error happens again. Delete '
-                    '& Discard (available on the medium plan and higher) deletes most of the data '
-                    'associated with the issue and discards future events matching the issue '
-                    'before it reaches your stream. This is useful to permanently ignore errors '
-                    'you don\'t care about.'),
+                    'Ignoring an issue silences notifications and removes it from your feeds. '
+                    'Deleting an issue deletes its data and causes a new issue to be created if it '
+                    'happens again. Delete & Discard (available on the medium plan and higher) '
+                    'deletes most of the issue\'s data and discards future events matching the '
+                    'issue before they reach your stream. This is useful to permanently ignore '
+                    'errors you don\'t care about.'),
                 'target': 'ignore_delete_discard',
             },
         ],
@@ -92,6 +90,7 @@ GUIDES = {
                              'touched by those commits, files observed in the stacktrace, and '
                              'authors of those files. Learn more about releases '
                              '<a href="https://docs.sentry.io/learn/releases/">here</a>.'),
+                'target': 'releases',
             },
         ]
     },

+ 1 - 4
src/sentry/static/sentry/app/components/events/interfaces/crashHeader.jsx

@@ -21,7 +21,6 @@ const CrashHeader = createReactClass({
     newestFirst: PropTypes.bool.isRequired,
     stackType: PropTypes.string, // 'original', 'minified', or falsy (none)
     onChange: PropTypes.func,
-    hasGuideAnchor: PropTypes.bool,
   },
 
   mixins: [
@@ -99,9 +98,7 @@ const CrashHeader = createReactClass({
     return (
       <div className="crash-title">
         {this.props.beforeTitle}
-        {this.props.hasGuideAnchor ? (
-          <GuideAnchor target="exception" type="text" />
-        ) : null}
+        <GuideAnchor target="exception" type="text" />
         <h3 className="pull-left">
           {this.props.title}
           <small style={{marginLeft: 5}}>

+ 0 - 1
src/sentry/static/sentry/app/components/events/interfaces/exception.jsx

@@ -47,7 +47,6 @@ class ExceptionInterface extends React.Component {
       <CrashHeader
         group={group}
         title={t('Exception')}
-        hasGuideAnchor={true}
         platform={event.platform}
         exception={data}
         stackView={stackView}

+ 0 - 1
src/sentry/static/sentry/app/components/events/interfaces/stacktrace.jsx

@@ -56,7 +56,6 @@ class StacktraceInterface extends React.Component {
         title={t('Stacktrace')}
         group={group}
         platform={evt.platform}
-        hasGuideAnchor={true}
         stacktrace={data}
         stackView={stackView}
         newestFirst={newestFirst}

+ 14 - 4
src/sentry/static/sentry/app/stores/guideStore.jsx

@@ -1,4 +1,5 @@
 import Reflux from 'reflux';
+import $ from 'jquery';
 import GuideActions from '../actions/guideActions';
 import HookStore from './hookStore';
 
@@ -49,7 +50,6 @@ const GuideStore = Reflux.createStore({
       cb('assistant.guide_next', {
         guide: this.state.currentGuide.id,
         cue: this.state.currentGuide.cue,
-        step: this.state.currentStep,
       })
     );
   },
@@ -66,9 +66,10 @@ const GuideStore = Reflux.createStore({
 
   updateCurrentGuide() {
     let availableTargets = [...this.state.anchors].map(a => a.props.target);
+
+    // Select the first guide that hasn't been seen in this session and has all
+    // required anchors on the page.
     let bestGuideKey = Object.keys(this.state.guides).find(key => {
-      // Only show a guide if it hasn't been seen in this session before and every
-      // anchor needed by the guide is on the page.
       let guide = this.state.guides[key];
       let seen = this.state.guidesSeen.has(guide.id);
       let allTargetsPresent = guide.required_targets.every(
@@ -76,7 +77,16 @@ const GuideStore = Reflux.createStore({
       );
       return !seen && allTargetsPresent;
     });
-    let bestGuide = bestGuideKey ? this.state.guides[bestGuideKey] : null;
+
+    let bestGuide = null;
+    if (bestGuideKey) {
+      bestGuide = $.extend(true, {}, this.state.guides[bestGuideKey]);
+      // Remove steps that don't have an anchor on the page.
+      bestGuide.steps = bestGuide.steps.filter(
+        step => step.target && availableTargets.indexOf(step.target) >= 0
+      );
+    }
+
     if (bestGuide !== this.state.currentGuide) {
       this.state.currentGuide = bestGuide;
       this.state.currentStep = 0;

+ 3 - 0
tests/js/spec/stores/guideStore.spec.jsx

@@ -13,6 +13,7 @@ describe('GuideStore', function() {
       steps: [
         {message: 'Message 1', target: 'target 1', title: '1. Title 1'},
         {message: 'Message 2', target: 'target 2', title: '2. Title 2'},
+        {message: 'Message 3', target: 'target 3', title: '3. Title 3'},
       ],
     },
   };
@@ -45,6 +46,8 @@ describe('GuideStore', function() {
     GuideStore.onRegisterAnchor(anchor1);
     GuideStore.onRegisterAnchor(anchor2);
     GuideStore.onFetchSucceeded(data);
+    // GuideStore should prune steps that don't have anchors.
+    expect(GuideStore.state.currentGuide.steps).toHaveLength(2);
     GuideStore.onNextStep();
     expect(GuideStore.state.currentStep).toEqual(1);
     GuideStore.onNextStep();