Просмотр исходного кода

fix(dashboards): Hide Issue Widgets if not feature flagged (#30930)

Hides any saved Issue Widgets on the dashboard from rendering if the user does not have the Issue Widgets feature flag on. This is in case we need to rollback the feature flag.
edwardgou-sentry 3 лет назад
Родитель
Сommit
290aa76ce9

+ 19 - 14
static/app/views/dashboardsV2/dashboard.tsx

@@ -29,7 +29,13 @@ import withPageFilters from 'sentry/utils/withPageFilters';
 import {DataSet} from './widget/utils';
 import AddWidget, {ADD_WIDGET_BUTTON_DRAG_ID} from './addWidget';
 import SortableWidget from './sortableWidget';
-import {DashboardDetails, DashboardWidgetSource, DisplayType, Widget} from './types';
+import {
+  DashboardDetails,
+  DashboardWidgetSource,
+  DisplayType,
+  Widget,
+  WidgetType,
+} from './types';
 
 export const DRAG_HANDLE_CLASS = 'widget-drag';
 const WIDGET_PREFIX = 'grid-item';
@@ -362,12 +368,12 @@ class Dashboard extends Component<Props, State> {
 
   renderGridDashboard() {
     const {layouts, isMobile} = this.state;
-    const {
-      isEditing,
-      dashboard: {widgets},
-      organization,
-      widgetLimitReached,
-    } = this.props;
+    const {isEditing, dashboard, organization, widgetLimitReached} = this.props;
+    let {widgets} = dashboard;
+    // Filter out any issue widgets if the user does not have the feature flag
+    if (!organization.features.includes('issues-in-dashboards')) {
+      widgets = widgets.filter(({widgetType}) => widgetType !== WidgetType.ISSUE);
+    }
 
     const canModifyLayout = !isMobile && isEditing;
 
@@ -400,13 +406,12 @@ class Dashboard extends Component<Props, State> {
   }
 
   renderDndDashboard = () => {
-    const {
-      isEditing,
-      onUpdate,
-      dashboard: {widgets},
-      organization,
-      widgetLimitReached,
-    } = this.props;
+    const {isEditing, onUpdate, dashboard, organization, widgetLimitReached} = this.props;
+    let {widgets} = dashboard;
+    // Filter out any issue widgets if the user does not have the feature flag
+    if (!organization.features.includes('issues-in-dashboards')) {
+      widgets = widgets.filter(({widgetType}) => widgetType !== WidgetType.ISSUE);
+    }
 
     const items = this.getWidgetIds();
 

+ 86 - 3
tests/js/spec/views/dashboardsV2/gridLayout/dashboard.spec.tsx

@@ -1,8 +1,12 @@
 import {mountWithTheme} from 'sentry-test/enzyme';
 import {initializeOrg} from 'sentry-test/initializeOrg';
+import {
+  mountWithTheme as rtlMountWithTheme,
+  screen,
+} from 'sentry-test/reactTestingLibrary';
 
 import Dashboard from 'sentry/views/dashboardsV2/dashboard';
-import {DisplayType, WidgetType} from 'sentry/views/dashboardsV2/types';
+import {DisplayType, Widget, WidgetType} from 'sentry/views/dashboardsV2/types';
 
 describe('Dashboards > Dashboard', () => {
   const organization = TestStubs.Organization({
@@ -14,8 +18,9 @@ describe('Dashboards > Dashboard', () => {
     title: 'Test Dashboard',
     widgets: [],
   };
-  const newWidget = {
-    title: 'Test Query',
+  const newWidget: Widget = {
+    id: '1',
+    title: 'Test Discover Widget',
     displayType: DisplayType.LINE,
     widgetType: WidgetType.DISCOVER,
     interval: '5m',
@@ -28,6 +33,21 @@ describe('Dashboards > Dashboard', () => {
       },
     ],
   };
+  const issueWidget: Widget = {
+    id: '2',
+    title: 'Test Issue Widget',
+    displayType: DisplayType.TABLE,
+    widgetType: WidgetType.ISSUE,
+    interval: '5m',
+    queries: [
+      {
+        name: '',
+        conditions: '',
+        fields: ['title'],
+        orderby: '',
+      },
+    ],
+  };
 
   let initialData;
 
@@ -39,6 +59,7 @@ describe('Dashboards > Dashboard', () => {
       body: [],
     });
   });
+
   it('dashboard adds new widget if component is mounted with newWidget prop', async () => {
     const mockHandleAddCustomWidget = jest.fn();
     const wrapper = mountWithTheme(
@@ -91,4 +112,66 @@ describe('Dashboards > Dashboard', () => {
     wrapper.update();
     expect(mockHandleAddCustomWidget).toHaveBeenCalled();
   });
+
+  it('dashboard does not display issue widgets if the user does not have issue widgets feature flag', async () => {
+    const mockHandleAddCustomWidget = jest.fn();
+    const mockDashboardWithIssueWidget = {
+      ...mockDashboard,
+      widgets: [newWidget, issueWidget],
+    };
+    rtlMountWithTheme(
+      <Dashboard
+        paramDashboardId="1"
+        dashboard={mockDashboardWithIssueWidget}
+        organization={initialData.organization}
+        isEditing={false}
+        onUpdate={() => undefined}
+        handleAddLibraryWidgets={() => undefined}
+        handleAddCustomWidget={mockHandleAddCustomWidget}
+        onSetWidgetToBeUpdated={() => undefined}
+        router={initialData.router}
+        location={initialData.location}
+        layout={[]}
+        onLayoutChange={() => undefined}
+        widgetLimitReached={false}
+      />
+    );
+    expect(screen.getByText('Test Discover Widget')).toBeInTheDocument();
+    expect(screen.queryByText('Test Issue Widget')).not.toBeInTheDocument();
+  });
+
+  it('dashboard displays issue widgets if the user has issue widgets feature flag', async () => {
+    const mockHandleAddCustomWidget = jest.fn();
+    const organizationWithFlag = TestStubs.Organization({
+      features: [
+        'dashboards-basic',
+        'dashboards-edit',
+        'dashboard-grid-layout',
+        'issues-in-dashboards',
+      ],
+    });
+    const mockDashboardWithIssueWidget = {
+      ...mockDashboard,
+      widgets: [newWidget, issueWidget],
+    };
+    rtlMountWithTheme(
+      <Dashboard
+        paramDashboardId="1"
+        dashboard={mockDashboardWithIssueWidget}
+        organization={organizationWithFlag}
+        isEditing={false}
+        onUpdate={() => undefined}
+        handleAddLibraryWidgets={() => undefined}
+        handleAddCustomWidget={mockHandleAddCustomWidget}
+        onSetWidgetToBeUpdated={() => undefined}
+        router={initialData.router}
+        location={initialData.location}
+        layout={[]}
+        onLayoutChange={() => undefined}
+        widgetLimitReached={false}
+      />
+    );
+    expect(screen.getByText('Test Discover Widget')).toBeInTheDocument();
+    expect(screen.getByText('Test Issue Widget')).toBeInTheDocument();
+  });
 });