Browse Source

ref(js): useLegacyStore for SystemAlerts (#29140)

Evan Purkhiser 3 years ago
parent
commit
00ec5f8a2a

+ 11 - 8
static/app/stores/alertStore.tsx

@@ -3,21 +3,24 @@ import Reflux from 'reflux';
 import AlertActions from 'app/actions/alertActions';
 import {defined} from 'app/utils';
 import localStorage from 'app/utils/localStorage';
+import {Theme} from 'app/utils/theme';
+
+import {CommonStoreInterface} from './types';
 
 type Alert = {
-  message: string;
-  type: 'warning' | 'warn' | 'error';
+  message: React.ReactNode;
+  type: keyof Theme['alert'];
   expireAfter?: number;
   key?: number;
   id?: string;
   url?: string;
   neverExpire?: boolean;
   noDuplicates?: boolean;
+  onClose?: () => void;
 };
 
-type AlertStoreInterface = {
+type AlertStoreInterface = CommonStoreInterface<Alert[]> & {
   init(): void;
-  getInitialState(): Alert[];
   onAddAlert(alert: Alert): void;
   onCloseAlert(alert: Alert, duration?: number): void;
 };
@@ -37,10 +40,6 @@ const storeConfig: Reflux.StoreDefinition & Internals & AlertStoreInterface = {
     this.count = 0;
   },
 
-  getInitialState() {
-    return this.alerts;
-  },
-
   onAddAlert(alert) {
     const alertAlreadyExists = this.alerts.some(a => a.id === alert.id);
     if (alertAlreadyExists && alert.noDuplicates) {
@@ -103,6 +102,10 @@ const storeConfig: Reflux.StoreDefinition & Internals & AlertStoreInterface = {
     this.alerts = this.alerts.filter(item => alert !== item);
     this.trigger(this.alerts);
   },
+
+  getState() {
+    return this.alerts;
+  },
 };
 
 const AlertStore = Reflux.createStore(storeConfig) as Reflux.Store & AlertStoreInterface;

+ 5 - 16
static/app/views/app/alertMessage.tsx

@@ -7,30 +7,19 @@ import Button from 'app/components/button';
 import ExternalLink from 'app/components/links/externalLink';
 import {IconCheckmark, IconClose, IconWarning} from 'app/icons';
 import {t} from 'app/locale';
+import AlertStore from 'app/stores/alertStore';
 import space from 'app/styles/space';
 
-type AlertType = {
-  /**
-   * A lot of alerts coming from getsentry do not have an `id`
-   */
-  id?: string;
-  message: React.ReactNode;
-  type: 'success' | 'error' | 'warning' | 'info';
-  url?: string;
-  onClose?: () => void;
-};
-
 type Props = {
-  alert: AlertType;
+  alert: ReturnType<typeof AlertStore['getState']>[number];
   system: boolean;
 };
 
 const AlertMessage = ({alert, system}: Props) => {
-  const handleCloseAlert = () => {
-    AlertActions.closeAlert(alert);
-  };
+  const handleClose = () => AlertActions.closeAlert(alert);
 
   const {url, message, type} = alert;
+
   const icon =
     type === 'success' ? (
       <IconCheckmark size="md" isCircled />
@@ -46,7 +35,7 @@ const AlertMessage = ({alert, system}: Props) => {
       <StyledCloseButton
         icon={<IconClose size="md" isCircled />}
         aria-label={t('Close')}
-        onClick={alert.onClose ?? handleCloseAlert}
+        onClick={alert.onClose ?? handleClose}
         size="zero"
         borderless
       />

+ 10 - 35
static/app/views/app/systemAlerts.tsx

@@ -1,45 +1,20 @@
-import * as React from 'react';
-import {ThemeProvider} from '@emotion/react';
-
 import AlertStore from 'app/stores/alertStore';
-import {lightTheme} from 'app/utils/theme';
+import {useLegacyStore} from 'app/stores/useLegacyStore';
 
 import AlertMessage from './alertMessage';
 
 type Props = {className?: string};
-type Alert = React.ComponentProps<typeof AlertMessage>['alert'];
-type State = {
-  alerts: Array<Alert>;
-};
-
-class SystemAlerts extends React.Component<Props, State> {
-  state = this.getInitialState();
-
-  getInitialState(): State {
-    return {
-      alerts: AlertStore.getInitialState() as Alert[],
-    };
-  }
-
-  componentWillUnmount() {
-    this.unlistener?.();
-  }
 
-  unlistener = AlertStore.listen((alerts: Alert[]) => this.setState({alerts}), undefined);
+function SystemAlerts(props: Props) {
+  const alerts = useLegacyStore(AlertStore);
 
-  render() {
-    const {className} = this.props;
-    const {alerts} = this.state;
-    return (
-      <ThemeProvider theme={lightTheme}>
-        <div className={className}>
-          {alerts.map((alert, index) => (
-            <AlertMessage alert={alert} key={`${alert.id}-${index}`} system />
-          ))}
-        </div>
-      </ThemeProvider>
-    );
-  }
+  return (
+    <div {...props}>
+      {alerts.map((alert, index) => (
+        <AlertMessage alert={alert} key={`${alert.id}-${index}`} system />
+      ))}
+    </div>
+  );
 }
 
 export default SystemAlerts;