Browse Source

ref(metrics): Refactor metrics stores to the new format (#32414)

Matej Minar 3 years ago
parent
commit
82a72b6dac

+ 20 - 12
static/app/stores/metricsMetaStore.tsx

@@ -3,28 +3,36 @@ import Reflux from 'reflux';
 import MetricsMetaActions from 'sentry/actions/metricsMetaActions';
 import {MetricsMeta, MetricsMetaCollection} from 'sentry/types';
 
-type MetricsMetaStoreInterface = {
-  getAllFields(): MetricsMetaCollection;
+import {CommonStoreInterface} from './types';
+
+type State = {
+  metricsMeta: MetricsMetaCollection;
+};
+
+type Internals = {
+  metricsMeta: MetricsMetaCollection;
+};
+
+type MetricsMetaStoreInterface = CommonStoreInterface<State> & {
   onLoadSuccess(data: MetricsMeta[]): void;
   reset(): void;
-  state: MetricsMetaCollection;
 };
 
-const storeConfig: Reflux.StoreDefinition & MetricsMetaStoreInterface = {
-  state: {},
+const storeConfig: Reflux.StoreDefinition & Internals & MetricsMetaStoreInterface = {
+  metricsMeta: {},
 
   init() {
-    this.state = {};
     this.listenTo(MetricsMetaActions.loadMetricsMetaSuccess, this.onLoadSuccess);
   },
 
   reset() {
-    this.state = {};
-    this.trigger(this.state);
+    this.metricsMeta = {};
+    this.trigger(this.metricsMeta);
   },
 
-  getAllFields() {
-    return this.state;
+  getState() {
+    const {metricsMeta} = this;
+    return {metricsMeta};
   },
 
   onLoadSuccess(data) {
@@ -36,8 +44,8 @@ const storeConfig: Reflux.StoreDefinition & MetricsMetaStoreInterface = {
       return acc;
     }, {});
 
-    this.state = {...this.state, ...newFields};
-    this.trigger(this.state);
+    this.metricsMeta = {...this.metricsMeta, ...newFields};
+    this.trigger(this.metricsMeta);
   },
 };
 

+ 23 - 15
static/app/stores/metricsTagStore.tsx

@@ -3,31 +3,39 @@ import Reflux from 'reflux';
 import MetricsTagActions from 'sentry/actions/metricTagActions';
 import {MetricsTag, MetricsTagCollection} from 'sentry/types';
 
-type MetricsTagStoreInterface = {
-  getAllTags(): MetricsTagCollection;
-  onLoadTagsSuccess(data: MetricsTag[]): void;
+import {CommonStoreInterface} from './types';
+
+type State = {
+  metricsTags: MetricsTagCollection;
+};
+
+type Internals = {
+  metricsTags: MetricsTagCollection;
+};
+
+type MetricsTagStoreInterface = CommonStoreInterface<State> & {
+  onLoadSuccess(data: MetricsTag[]): void;
   reset(): void;
-  state: MetricsTagCollection;
 };
 
-const storeConfig: Reflux.StoreDefinition & MetricsTagStoreInterface = {
-  state: {},
+const storeConfig: Reflux.StoreDefinition & Internals & MetricsTagStoreInterface = {
+  metricsTags: {},
 
   init() {
-    this.state = {};
-    this.listenTo(MetricsTagActions.loadMetricsTagsSuccess, this.onLoadTagsSuccess);
+    this.listenTo(MetricsTagActions.loadMetricsTagsSuccess, this.onLoadSuccess);
   },
 
   reset() {
-    this.state = {};
-    this.trigger(this.state);
+    this.metricsTags = {};
+    this.trigger(this.metricsTags);
   },
 
-  getAllTags() {
-    return this.state;
+  getState() {
+    const {metricsTags} = this;
+    return {metricsTags};
   },
 
-  onLoadTagsSuccess(data) {
+  onLoadSuccess(data) {
     const newTags = data.reduce<MetricsTagCollection>((acc, tag) => {
       acc[tag.key] = {
         ...tag,
@@ -36,8 +44,8 @@ const storeConfig: Reflux.StoreDefinition & MetricsTagStoreInterface = {
       return acc;
     }, {});
 
-    this.state = {...this.state, ...newTags};
-    this.trigger(this.state);
+    this.metricsTags = {...this.metricsTags, ...newTags};
+    this.trigger(this.metricsTags);
   },
 };
 

+ 13 - 33
static/app/utils/withMetricsMeta.tsx

@@ -1,6 +1,7 @@
 import * as React from 'react';
 
 import MetricsMetaStore from 'sentry/stores/metricsMetaStore';
+import {useLegacyStore} from 'sentry/stores/useLegacyStore';
 import {MetricsMetaCollection} from 'sentry/types';
 import getDisplayName from 'sentry/utils/getDisplayName';
 
@@ -8,42 +9,21 @@ export type InjectedMetricsMetaProps = {
   metricsMeta: MetricsMetaCollection;
 };
 
-type State = {
-  metricsMeta: MetricsMetaCollection;
-};
-
 function withMetricsMeta<P extends InjectedMetricsMetaProps>(
   WrappedComponent: React.ComponentType<P>
 ) {
-  class WithMetricMeta extends React.Component<
-    Omit<P, keyof InjectedMetricsMetaProps>,
-    State
-  > {
-    static displayName = `withMetricsMeta(${getDisplayName(WrappedComponent)})`;
-
-    state: State = {
-      metricsMeta: MetricsMetaStore.getAllFields(),
-    };
-
-    componentWillUnmount() {
-      this.unsubscribe();
-    }
-    unsubscribe = MetricsMetaStore.listen(
-      (metricsMeta: MetricsMetaCollection) => this.setState({metricsMeta}),
-      undefined
-    );
-
-    render() {
-      const {metricsMeta, ...props} = this.props as P;
-      return (
-        <WrappedComponent
-          {...({metricsMeta: metricsMeta ?? this.state.metricsMeta, ...props} as P)}
-        />
-      );
-    }
-  }
-
-  return WithMetricMeta;
+  type Props = Omit<P, keyof InjectedMetricsMetaProps> &
+    Partial<InjectedMetricsMetaProps>;
+
+  const WithMetricsMeta: React.FC<Props> = props => {
+    const {metricsMeta} = useLegacyStore(MetricsMetaStore);
+
+    return <WrappedComponent {...(props as P)} metricsMeta={metricsMeta} />;
+  };
+
+  WithMetricsMeta.displayName = `withMetricsMeta(${getDisplayName(WrappedComponent)})`;
+
+  return WithMetricsMeta;
 }
 
 export default withMetricsMeta;

+ 13 - 33
static/app/utils/withMetricsTags.tsx

@@ -1,6 +1,7 @@
 import * as React from 'react';
 
 import MetricsTagStore from 'sentry/stores/metricsTagStore';
+import {useLegacyStore} from 'sentry/stores/useLegacyStore';
 import {MetricsTagCollection} from 'sentry/types';
 import getDisplayName from 'sentry/utils/getDisplayName';
 
@@ -8,42 +9,21 @@ export type InjectedMetricsTagsProps = {
   metricsTags: MetricsTagCollection;
 };
 
-type State = {
-  metricsTags: MetricsTagCollection;
-};
-
 function withMetricsTags<P extends InjectedMetricsTagsProps>(
   WrappedComponent: React.ComponentType<P>
 ) {
-  class WithMetricTags extends React.Component<
-    Omit<P, keyof InjectedMetricsTagsProps>,
-    State
-  > {
-    static displayName = `withMetricsTags(${getDisplayName(WrappedComponent)})`;
-
-    state: State = {
-      metricsTags: MetricsTagStore.getAllTags(),
-    };
-
-    componentWillUnmount() {
-      this.unsubscribe();
-    }
-    unsubscribe = MetricsTagStore.listen(
-      (metricsTags: MetricsTagCollection) => this.setState({metricsTags}),
-      undefined
-    );
-
-    render() {
-      const {metricsTags, ...props} = this.props as P;
-      return (
-        <WrappedComponent
-          {...({metricsTags: metricsTags ?? this.state.metricsTags, ...props} as P)}
-        />
-      );
-    }
-  }
-
-  return WithMetricTags;
+  type Props = Omit<P, keyof InjectedMetricsTagsProps> &
+    Partial<InjectedMetricsTagsProps>;
+
+  const WithMetricsTags: React.FC<Props> = props => {
+    const {metricsTags} = useLegacyStore(MetricsTagStore);
+
+    return <WrappedComponent {...(props as P)} metricsTags={metricsTags} />;
+  };
+
+  WithMetricsTags.displayName = `withMetricsTags(${getDisplayName(WrappedComponent)})`;
+
+  return WithMetricsTags;
 }
 
 export default withMetricsTags;

+ 3 - 1
tests/js/spec/components/modals/addDashboardWidgetModal.spec.jsx

@@ -149,7 +149,9 @@ describe('Modals -> AddDashboardWidgetModal', function () {
 
   beforeEach(function () {
     TagStore.onLoadTagsSuccess(tags);
-    MetricsTagStore.onLoadTagsSuccess(metricsTags);
+    act(() => {
+      MetricsTagStore.onLoadSuccess(metricsTags);
+    });
     MetricsMetaStore.onLoadSuccess(metricsMeta);
     MockApiClient.addMockResponse({
       url: '/organizations/org-slug/dashboards/widgets/',

+ 4 - 4
tests/js/spec/stores/metricsMetaStore.spec.tsx

@@ -9,8 +9,8 @@ describe('MetricsMetaStore', function () {
     it('should add a new fields and trigger the new addition', () => {
       jest.spyOn(MetricsMetaStore, 'trigger');
 
-      const fields = MetricsMetaStore.getAllFields();
-      expect(fields).toEqual({});
+      const {metricsMeta} = MetricsMetaStore.getState();
+      expect(metricsMeta).toEqual({});
 
       MetricsMetaStore.onLoadSuccess([
         {
@@ -25,8 +25,8 @@ describe('MetricsMetaStore', function () {
         },
       ]);
 
-      const updatedFields = MetricsMetaStore.getAllFields();
-      expect(updatedFields).toEqual({
+      const {metricsMeta: updatedMetricsMeta} = MetricsMetaStore.getState();
+      expect(updatedMetricsMeta).toEqual({
         'sentry.sessions.session': {
           name: 'sentry.sessions.session',
           type: 'counter',

+ 6 - 6
tests/js/spec/stores/metricsTagStore.spec.jsx → tests/js/spec/stores/metricsTagStore.spec.tsx

@@ -5,21 +5,21 @@ describe('MetricsTagStore', function () {
     MetricsTagStore.reset();
   });
 
-  describe('onLoadTagsSuccess()', () => {
+  describe('onLoadSuccess()', () => {
     it('should add a new tags and trigger the new addition', () => {
       jest.spyOn(MetricsTagStore, 'trigger');
 
-      const tags = MetricsTagStore.getAllTags();
-      expect(tags).toEqual({});
+      const {metricsTags} = MetricsTagStore.getState();
+      expect(metricsTags).toEqual({});
 
-      MetricsTagStore.onLoadTagsSuccess([
+      MetricsTagStore.onLoadSuccess([
         {key: 'environment'},
         {key: 'release'},
         {key: 'session.status'},
       ]);
 
-      const updatedTags = MetricsTagStore.getAllTags();
-      expect(updatedTags).toEqual({
+      const {metricsTags: metricsNewTags} = MetricsTagStore.getState();
+      expect(metricsNewTags).toEqual({
         environment: {key: 'environment'},
         release: {key: 'release'},
         'session.status': {key: 'session.status'},

+ 15 - 13
tests/js/spec/utils/withMetricsMeta.spec.tsx

@@ -1,4 +1,4 @@
-import {mountWithTheme, screen} from 'sentry-test/reactTestingLibrary';
+import {act, mountWithTheme, screen} from 'sentry-test/reactTestingLibrary';
 
 import MetricsMetaStore from 'sentry/stores/metricsMetaStore';
 import withMetricsMeta, {InjectedMetricsMetaProps} from 'sentry/utils/withMetricsMeta';
@@ -32,18 +32,20 @@ describe('withMetricsMeta HoC', function () {
     // Should forward props.
     expect(screen.getByText('value')).toBeInTheDocument();
 
-    MetricsMetaStore.onLoadSuccess([
-      {
-        name: 'sentry.sessions.session',
-        type: 'counter',
-        operations: ['sum'],
-      },
-      {
-        name: 'sentry.sessions.session.error',
-        type: 'set',
-        operations: ['count_unique'],
-      },
-    ]);
+    act(() => {
+      MetricsMetaStore.onLoadSuccess([
+        {
+          name: 'sentry.sessions.session',
+          type: 'counter',
+          operations: ['sum'],
+        },
+        {
+          name: 'sentry.sessions.session.error',
+          type: 'set',
+          operations: ['count_unique'],
+        },
+      ]);
+    });
 
     // Should forward prop
     expect(screen.getByText('value')).toBeInTheDocument();

+ 8 - 6
tests/js/spec/utils/withMetricsTags.spec.tsx

@@ -1,4 +1,4 @@
-import {mountWithTheme, screen} from 'sentry-test/reactTestingLibrary';
+import {act, mountWithTheme, screen} from 'sentry-test/reactTestingLibrary';
 
 import MetricsTagStore from 'sentry/stores/metricsTagStore';
 import withMetricsTags, {InjectedMetricsTagsProps} from 'sentry/utils/withMetricsTags';
@@ -32,11 +32,13 @@ describe('withMetricsTags HoC', function () {
     // Should forward props.
     expect(screen.getByText('value')).toBeInTheDocument();
 
-    MetricsTagStore.onLoadTagsSuccess([
-      {key: 'environment'},
-      {key: 'release'},
-      {key: 'session.status'},
-    ]);
+    act(() => {
+      MetricsTagStore.onLoadSuccess([
+        {key: 'environment'},
+        {key: 'release'},
+        {key: 'session.status'},
+      ]);
+    });
 
     // Should forward prop
     expect(screen.getByText('value')).toBeInTheDocument();