Browse Source

ref(ts): Convert IssueListTagFilter (#21313)

* wip refactor to tsx, need to wait for sidebar changes

* use new tagvalueloader type

* comments
David Wang 4 years ago
parent
commit
f4d15fa6ce

+ 1 - 0
src/sentry/static/sentry/app/types/index.tsx

@@ -1288,6 +1288,7 @@ export type Tag = {
   values?: string[];
   totalValues?: number;
   predefined?: boolean;
+  isInput?: boolean;
 };
 
 export type TagCollection = {[key: string]: Tag};

+ 2 - 5
src/sentry/static/sentry/app/views/issueList/sidebar.tsx

@@ -22,7 +22,6 @@ type DefaultProps = {
 };
 
 type Props = DefaultProps & {
-  orgId: string;
   tagValueLoader: TagValueLoader;
   loading?: boolean;
 };
@@ -36,7 +35,6 @@ const IssueListSidebar = createReactClass<Props, State>({
   displayName: 'IssueListSidebar',
 
   propTypes: {
-    orgId: PropTypes.string.isRequired,
     tags: PropTypes.objectOf(SentryTypes.Tag).isRequired,
     query: PropTypes.string,
     onQueryChange: PropTypes.func.isRequired,
@@ -72,7 +70,7 @@ const IssueListSidebar = createReactClass<Props, State>({
     }
   },
 
-  onSelectTag(tag: Tag, value: string) {
+  onSelectTag(tag: Tag, value: string | null) {
     const newQuery = {...this.state.queryObj};
     if (value) {
       newQuery[tag.key] = value;
@@ -123,7 +121,7 @@ const IssueListSidebar = createReactClass<Props, State>({
   },
 
   render() {
-    const {loading, orgId, tagValueLoader, tags} = this.props;
+    const {loading, tagValueLoader, tags} = this.props;
     return (
       <div className="stream-sidebar">
         {loading ? (
@@ -152,7 +150,6 @@ const IssueListSidebar = createReactClass<Props, State>({
                 key={tag.key}
                 tag={tag}
                 onSelect={this.onSelectTag}
-                orgId={orgId}
                 tagValueLoader={tagValueLoader}
               />
             ))}

+ 46 - 36
src/sentry/static/sentry/app/views/issueList/tagFilter.jsx → src/sentry/static/sentry/app/views/issueList/tagFilter.tsx

@@ -1,42 +1,45 @@
 import debounce from 'lodash/debounce';
-import PropTypes from 'prop-types';
 import React from 'react';
 
 import {Client} from 'app/api';
 import {addErrorMessage} from 'app/actionCreators/indicator';
 import {t, tct} from 'app/locale';
 import SelectControl from 'app/components/forms/selectControl';
-
-class IssueListTagFilter extends React.Component {
-  static tagValueToSelectFormat = ({value}) => ({
-    value,
-    label: value,
-  });
-
-  static propTypes = {
-    tag: PropTypes.object.isRequired,
-    value: PropTypes.string,
-    onSelect: PropTypes.func,
-    tagValueLoader: PropTypes.func.isRequired,
-  };
-
-  static defaultProps = {
-    tag: {},
-    value: '',
+import {Tag, TagValue} from 'app/types';
+
+import {TagValueLoader} from './types';
+
+const defaultProps = {
+  value: '',
+};
+
+type SelectOption = Record<'value' | 'label', string>;
+
+type Props = {
+  tag: Tag;
+  onSelect: (tag: Tag, value: string | null) => void;
+  tagValueLoader: TagValueLoader;
+} & typeof defaultProps;
+
+type State = {
+  query: string;
+  isLoading: boolean;
+  value: string | null;
+  textValue: string;
+  options?: SelectOption[];
+};
+
+class IssueListTagFilter extends React.Component<Props, State> {
+  static defaultProps = defaultProps;
+
+  state: State = {
+    query: '',
+    isLoading: false,
+    value: this.props.value,
+    textValue: this.props.value,
   };
 
-  constructor(...args) {
-    super(...args);
-    this.state = {
-      query: '',
-      isLoading: false,
-      value: this.props.value,
-      textValue: this.props.value,
-    };
-    this.api = new Client();
-  }
-
-  UNSAFE_componentWillReceiveProps(nextProps) {
+  UNSAFE_componentWillReceiveProps(nextProps: Props) {
     if (nextProps.value !== this.state.value) {
       this.setState({
         value: nextProps.value,
@@ -52,6 +55,8 @@ class IssueListTagFilter extends React.Component {
     this.api.clear();
   }
 
+  api = new Client();
+
   handleLoadOptions = () => {
     const {tag, tagValueLoader} = this.props;
     const {textValue} = this.state;
@@ -70,7 +75,12 @@ class IssueListTagFilter extends React.Component {
       .then(resp => {
         this.setState({
           isLoading: false,
-          options: Object.values(resp).map(IssueListTagFilter.tagValueToSelectFormat),
+          options: Object.values(resp).map(
+            ({value}: TagValue): SelectOption => ({
+              value,
+              label: value,
+            })
+          ),
         });
       })
       .catch(() => {
@@ -85,7 +95,7 @@ class IssueListTagFilter extends React.Component {
       });
   };
 
-  handleChangeInput = e => {
+  handleChangeInput = (e: React.ChangeEvent<HTMLInputElement>) => {
     const value = e.target.value;
     this.setState({
       textValue: value,
@@ -93,7 +103,7 @@ class IssueListTagFilter extends React.Component {
     this.debouncedTextChange(value);
   };
 
-  debouncedTextChange = debounce(function (text) {
+  debouncedTextChange = debounce(text => {
     this.handleChange(text);
   }, 150);
 
@@ -110,12 +120,12 @@ class IssueListTagFilter extends React.Component {
     );
   };
 
-  handleChangeSelect = valueObj => {
+  handleChangeSelect = (valueObj: SelectOption | null) => {
     const value = valueObj ? valueObj.value : null;
     this.handleChange(value);
   };
 
-  handleChangeSelectInput = value => {
+  handleChangeSelectInput = (value: string) => {
     this.setState(
       {
         textValue: value,
@@ -124,7 +134,7 @@ class IssueListTagFilter extends React.Component {
     );
   };
 
-  handleChange = value => {
+  handleChange = (value: string | null) => {
     const {onSelect, tag} = this.props;
 
     this.setState(