Browse Source

feat(dashboard): Add some Release Health widgets to library (#35033)

Adding two Release Health widgets to widget library.
Shruthi 2 years ago
parent
commit
57647c3a90

+ 1 - 0
static/app/components/modals/dashboardWidgetLibraryModal/index.tsx

@@ -69,6 +69,7 @@ function DashboardWidgetLibraryModal({
           errored={errored}
           setSelectedWidgets={setSelectedWidgets}
           setErrored={setErrored}
+          organization={organization}
         />
       </Body>
       <Footer>

+ 11 - 1
static/app/components/modals/dashboardWidgetLibraryModal/libraryTab.tsx

@@ -4,6 +4,8 @@ import styled from '@emotion/styled';
 import Alert from 'sentry/components/alert';
 import {t} from 'sentry/locale';
 import space from 'sentry/styles/space';
+import {Organization} from 'sentry/types';
+import {WidgetType} from 'sentry/views/dashboardsV2/types';
 import {
   DEFAULT_WIDGETS,
   WidgetTemplate,
@@ -12,6 +14,7 @@ import WidgetLibraryCard from 'sentry/views/dashboardsV2/widgetLibrary/widgetCar
 
 type Props = {
   errored: boolean;
+  organization: Organization;
   selectedWidgets: WidgetTemplate[];
   setErrored: (errored: boolean) => void;
   setSelectedWidgets: (widgets: WidgetTemplate[]) => void;
@@ -20,9 +23,16 @@ type Props = {
 function DashboardWidgetLibraryTab({
   selectedWidgets,
   errored,
+  organization,
   setSelectedWidgets,
   setErrored,
 }: Props) {
+  let defaultWidgets = DEFAULT_WIDGETS;
+  if (!!!organization.features.includes('dashboards-releases')) {
+    defaultWidgets = defaultWidgets.filter(
+      widget => !!!(widget.widgetType === WidgetType.RELEASE)
+    );
+  }
   return (
     <Fragment>
       {errored && !!!selectedWidgets.length ? (
@@ -33,7 +43,7 @@ function DashboardWidgetLibraryTab({
         </Alert>
       ) : null}
       <WidgetLibraryGrid>
-        {DEFAULT_WIDGETS.map((widgetCard, index) => {
+        {defaultWidgets.map((widgetCard, index) => {
           return (
             <WidgetLibraryCard
               data-test-id={`widget-library-card-${index}`}

+ 1 - 0
static/app/views/dashboardsV2/widgetBuilder/widgetBuilder.tsx

@@ -1222,6 +1222,7 @@ function WidgetBuilder({
             </MainWrapper>
             <Side>
               <WidgetLibrary
+                organization={organization}
                 widgetBuilderNewDesign={widgetBuilderNewDesign}
                 onWidgetSelect={prebuiltWidget => {
                   setLatestLibrarySelectionTitle(prebuiltWidget.title);

+ 10 - 2
static/app/views/dashboardsV2/widgetBuilder/widgetLibrary/index.tsx

@@ -6,7 +6,8 @@ import {openWidgetBuilderOverwriteModal} from 'sentry/actionCreators/modal';
 import {OverwriteWidgetModalProps} from 'sentry/components/modals/widgetBuilder/overwriteWidgetModal';
 import {t} from 'sentry/locale';
 import space from 'sentry/styles/space';
-import {DisplayType} from 'sentry/views/dashboardsV2/types';
+import {Organization} from 'sentry/types';
+import {DisplayType, WidgetType} from 'sentry/views/dashboardsV2/types';
 import {
   getTopNConvertedDefaultWidgets,
   WidgetTemplate,
@@ -19,6 +20,7 @@ import {Card} from './card';
 interface Props {
   bypassOverwriteModal: boolean;
   onWidgetSelect: (widget: WidgetTemplate) => void;
+  organization: Organization;
   widgetBuilderNewDesign: boolean;
 }
 
@@ -26,9 +28,15 @@ export function WidgetLibrary({
   bypassOverwriteModal,
   onWidgetSelect,
   widgetBuilderNewDesign,
+  organization,
 }: Props) {
   const theme = useTheme();
-  const defaultWidgets = getTopNConvertedDefaultWidgets();
+  let defaultWidgets = getTopNConvertedDefaultWidgets();
+  if (!!!organization.features.includes('dashboards-releases')) {
+    defaultWidgets = defaultWidgets.filter(
+      widget => !!!(widget.widgetType === WidgetType.RELEASE)
+    );
+  }
 
   function getLibrarySelectionHandler(
     widget: OverwriteWidgetModalProps['widget'],

+ 49 - 0
static/app/views/dashboardsV2/widgetLibrary/data.tsx

@@ -52,6 +52,55 @@ export const DEFAULT_WIDGETS: Readonly<Array<WidgetTemplate>> = [
       },
     ],
   },
+  {
+    id: undefined,
+    title: t('Crash Rates for Recent Releases'),
+    description: t('Percentage of crashed sessions for latest releases.'),
+    displayType: DisplayType.LINE,
+    widgetType: WidgetType.RELEASE,
+    interval: '5m',
+    queries: [
+      {
+        name: '',
+        conditions: '',
+        fields: ['crash_rate(session)', 'release'],
+        aggregates: ['crash_rate(session)'],
+        columns: ['release'],
+        orderby: '-release',
+      },
+    ],
+  },
+  {
+    id: undefined,
+    title: t('User Session Health by Project'),
+    description: t('Breakdown of user sessions by project.'),
+    displayType: DisplayType.TABLE,
+    widgetType: WidgetType.RELEASE,
+    interval: '5m',
+    queries: [
+      {
+        name: '',
+        conditions: '',
+        fields: [
+          'project',
+          'count_abnormal(user)',
+          'count_crashed(user)',
+          'count_errored(user)',
+          'count_healthy(user)',
+          'count_unique(user)',
+        ],
+        aggregates: [
+          'count_abnormal(user)',
+          'count_crashed(user)',
+          'count_errored(user)',
+          'count_healthy(user)',
+          'count_unique(user)',
+        ],
+        columns: ['project'],
+        orderby: '-count_unique(user)',
+      },
+    ],
+  },
   {
     id: undefined,
     title: t('LCP by Country'),