From 1b0cd8d169372405c743d6fa71347e922fb53ddb Mon Sep 17 00:00:00 2001
From: Tom Robinson <tlrobinson@gmail.com>
Date: Thu, 18 May 2017 13:30:29 -0700
Subject: [PATCH] Fix React component Flow types

---
 .../components/widgets/PublicLinksListing.jsx | 13 +++---
 .../components/widgets/SecretKeyWidget.jsx    |  2 +-
 .../src/metabase/components/ActionButton.jsx  |  3 +-
 .../metabase/components/ConstrainToScreen.jsx |  4 +-
 .../src/metabase/components/CopyButton.jsx    |  2 +-
 .../src/metabase/components/CopyWidget.jsx    |  3 +-
 .../metabase/components/ShrinkableList.jsx    |  3 +-
 .../dashboard/components/Dashboard.jsx        | 19 ++++++---
 .../dashboard/components/DashboardHeader.jsx  | 15 +++----
 .../dashboard/hoc/DashboardControls.jsx       |  3 +-
 .../src/metabase/meta/types/Visualization.js  |  6 +--
 .../parameters/components/Parameters.jsx      | 40 ++++++++++---------
 .../components/widgets/CategoryWidget.jsx     |  2 +-
 .../widgets/DateAllOptionsWidget.jsx          |  3 +-
 .../metabase/public/components/EmbedFrame.jsx |  9 ++++-
 .../components/widgets/AdvancedEmbedPane.jsx  |  3 +-
 .../widgets/AdvancedSettingsPane.jsx          |  3 +-
 .../public/components/widgets/CodeSample.jsx  | 12 ++----
 .../components/widgets/EmbedCodePane.jsx      |  7 +++-
 .../components/widgets/EmbedModalContent.jsx  | 35 ++++++++--------
 .../public/components/widgets/EmbedWidget.jsx | 23 +++++++++--
 .../public/components/widgets/SharingPane.jsx | 18 ++++-----
 .../metabase/public/containers/PublicApp.jsx  |  4 +-
 .../public/containers/PublicDashboard.jsx     |  4 +-
 .../public/containers/PublicQuestion.jsx      |  2 +-
 frontend/src/metabase/public/lib/code.js      | 16 ++++++--
 frontend/src/metabase/public/lib/types.js     | 11 +++++
 .../qb/components/TimeseriesFilterWidget.jsx  |  8 ++--
 .../components/TimeseriesGroupingWidget.jsx   |  4 +-
 .../components/ActionsWidget.jsx              | 11 ++++-
 .../filters/DateOperatorSelector.jsx          |  8 ++--
 .../components/filters/FilterList.jsx         | 12 +++---
 .../components/filters/FilterPopover.jsx      | 19 +++++----
 .../components/filters/FilterWidget.jsx       | 13 +++---
 .../components/filters/OperatorSelector.jsx   |  2 +-
 .../components/filters/pickers/DatePicker.jsx | 18 ++++++---
 .../filters/pickers/NumberPicker.jsx          |  9 +++--
 .../filters/pickers/RelativeDatePicker.jsx    |  2 +-
 .../filters/pickers/SelectPicker.jsx          |  4 +-
 .../filters/pickers/SpecificDatePicker.jsx    |  2 +-
 .../components/filters/pickers/TextPicker.jsx | 11 ++++-
 .../components/ChartClickActions.jsx          |  5 ++-
 .../visualizations/components/FunnelBar.jsx   |  4 +-
 .../components/FunnelNormal.jsx               |  6 ++-
 .../components/LineAreaBarChart.jsx           |  5 ++-
 .../visualizations/components/PinMap.jsx      |  5 ++-
 .../components/TableInteractive.jsx           |  2 +-
 .../visualizations/components/TableSimple.jsx |  3 +-
 .../components/Visualization.jsx              | 18 +++++----
 frontend/src/metabase/visualizations/index.js |  1 +
 .../visualizations/lib/LineAreaBarRenderer.js | 10 ++---
 .../visualizations/visualizations/Funnel.jsx  |  5 ++-
 .../visualizations/visualizations/Map.jsx     |  4 +-
 .../visualizations/PieChart.jsx               |  4 +-
 .../visualizations/Progress.jsx               |  4 +-
 .../visualizations/visualizations/Scalar.jsx  |  4 +-
 .../visualizations/visualizations/Table.jsx   |  9 ++++-
 57 files changed, 304 insertions(+), 173 deletions(-)
 create mode 100644 frontend/src/metabase/public/lib/types.js

diff --git a/frontend/src/metabase/admin/settings/components/widgets/PublicLinksListing.jsx b/frontend/src/metabase/admin/settings/components/widgets/PublicLinksListing.jsx
index 49f5dfc9e88..8e2d000e936 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/PublicLinksListing.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/PublicLinksListing.jsx
@@ -20,10 +20,10 @@ type PublicLink = {
 };
 
 type Props = {
-    load:         () => Promise<PublicLink[]>,
-    revoke:       (link: PublicLink) => Promise<void>,
-    getUrl:       (link: PublicLink) => string,
-    getPublicUrl: (link: PublicLink) => string,
+    load:           () => Promise<PublicLink[]>,
+    revoke?:        (link: PublicLink) => Promise<void>,
+    getUrl:         (link: PublicLink) => string,
+    getPublicUrl?:  (link: PublicLink) => string,
     noLinksMessage: string,
     type: string
 };
@@ -33,7 +33,7 @@ type State = {
     error: ?any
 };
 
-export default class PublicLinksListing extends Component<*, Props, State> {
+export default class PublicLinksListing extends Component {
     props: Props;
     state: State;
 
@@ -59,6 +59,9 @@ export default class PublicLinksListing extends Component<*, Props, State> {
     }
 
     async revoke(link: PublicLink) {
+        if (!this.props.revoke) {
+            return;
+        }
         try {
             await this.props.revoke(link);
             this.load();
diff --git a/frontend/src/metabase/admin/settings/components/widgets/SecretKeyWidget.jsx b/frontend/src/metabase/admin/settings/components/widgets/SecretKeyWidget.jsx
index 192e2b305c0..3db15bf88fe 100644
--- a/frontend/src/metabase/admin/settings/components/widgets/SecretKeyWidget.jsx
+++ b/frontend/src/metabase/admin/settings/components/widgets/SecretKeyWidget.jsx
@@ -13,7 +13,7 @@ type Props = {
     setting: {}
 };
 
-export default class SecretKeyWidget extends Component<*, Props, *> {
+export default class SecretKeyWidget extends Component {
     props: Props;
 
     _generateToken = async () => {
diff --git a/frontend/src/metabase/components/ActionButton.jsx b/frontend/src/metabase/components/ActionButton.jsx
index 168d2c71a6e..148742f2575 100644
--- a/frontend/src/metabase/components/ActionButton.jsx
+++ b/frontend/src/metabase/components/ActionButton.jsx
@@ -26,7 +26,8 @@ type State = {
     result: null|"success"|"failed",
 }
 
-export default class ActionButton extends Component<*, Props, State> {
+export default class ActionButton extends Component {
+    props: Props;
     state: State;
 
     timeout: ?any;
diff --git a/frontend/src/metabase/components/ConstrainToScreen.jsx b/frontend/src/metabase/components/ConstrainToScreen.jsx
index 354878bbc8f..aee7690bd18 100644
--- a/frontend/src/metabase/components/ConstrainToScreen.jsx
+++ b/frontend/src/metabase/components/ConstrainToScreen.jsx
@@ -11,7 +11,9 @@ type Props = {
     children: React$Element<any>
 };
 
-export default class ConstrainToScreen extends Component<*, Props, *> {
+export default class ConstrainToScreen extends Component {
+    props: Props;
+
     static defaultProps = {
         directions: ["top", "bottom"],
         padding: 10
diff --git a/frontend/src/metabase/components/CopyButton.jsx b/frontend/src/metabase/components/CopyButton.jsx
index 76a51cbf538..996ba43d1c0 100644
--- a/frontend/src/metabase/components/CopyButton.jsx
+++ b/frontend/src/metabase/components/CopyButton.jsx
@@ -15,7 +15,7 @@ type State = {
     copied: boolean
 };
 
-export default class CopyWidget extends Component<*, Props, State> {
+export default class CopyWidget extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/components/CopyWidget.jsx b/frontend/src/metabase/components/CopyWidget.jsx
index 01a3b485407..62d5e963a25 100644
--- a/frontend/src/metabase/components/CopyWidget.jsx
+++ b/frontend/src/metabase/components/CopyWidget.jsx
@@ -8,8 +8,9 @@ type Props = {
     value: string
 };
 
-export default class CopyWidget extends Component<*, Props, *> {
+export default class CopyWidget extends Component {
     props: Props;
+
     render() {
         const { value } = this.props;
         return (
diff --git a/frontend/src/metabase/components/ShrinkableList.jsx b/frontend/src/metabase/components/ShrinkableList.jsx
index 457841fd15c..3bae345fb74 100644
--- a/frontend/src/metabase/components/ShrinkableList.jsx
+++ b/frontend/src/metabase/components/ShrinkableList.jsx
@@ -17,7 +17,8 @@ type State = {
 };
 
 @ExplicitSize
-export default class ShrinkableList extends Component<*, Props, State> {
+export default class ShrinkableList extends Component {
+    props: Props;
     state: State = {
         isShrunk: null
     }
diff --git a/frontend/src/metabase/dashboard/components/Dashboard.jsx b/frontend/src/metabase/dashboard/components/Dashboard.jsx
index 6a63a2900da..e9c8458e90b 100644
--- a/frontend/src/metabase/dashboard/components/Dashboard.jsx
+++ b/frontend/src/metabase/dashboard/components/Dashboard.jsx
@@ -18,7 +18,7 @@ import type { LocationDescriptor, ApiError, QueryParams } from "metabase/meta/ty
 
 import type { Card, CardId, VisualizationSettings } from "metabase/meta/types/Card";
 import type { DashboardWithCards, DashboardId, DashCardId } from "metabase/meta/types/Dashboard";
-import type { RevisionId } from "metabase/meta/types/Revision";
+import type { Revision, RevisionId } from "metabase/meta/types/Revision";
 import type { Parameter, ParameterId, ParameterValues, ParameterOption } from "metabase/meta/types/Parameter";
 
 type Props = {
@@ -27,7 +27,9 @@ type Props = {
     dashboardId:            DashboardId,
     dashboard:              DashboardWithCards,
     cards:                  Card[],
+    revisions:              { [key: string]: Revision[] },
 
+    isAdmin:                boolean,
     isEditable:             boolean,
     isEditing:              boolean,
     isEditingParameter:     boolean,
@@ -48,7 +50,7 @@ type Props = {
     setDashboardAttributes: ({ [attribute: string]: any }) => void,
     fetchDashboardCardData: (options: { reload: bool, clear: bool }) => Promise<void>,
 
-    setEditingParameter:    (parameterId: ParameterId) => void,
+    setEditingParameter:    (parameterId: ?ParameterId) => void,
     setEditingDashboard:    (isEditing: boolean) => void,
 
     addParameter:               (option: ParameterOption) => Promise<Parameter>,
@@ -59,9 +61,15 @@ type Props = {
 
     editingParameter:       ?Parameter,
 
+    refreshPeriod:          number,
+    refreshElapsed:         number,
     isFullscreen:           boolean,
     isNightMode:            boolean,
+
     onRefreshPeriodChange:  (?number) => void,
+    onNightModeChange:      (boolean) => void,
+    onFullscreenChange:     (boolean) => void,
+
     loadDashboardParams:    () => void,
 
     onReplaceAllDashCardVisualizationSettings: (dashcardId: DashCardId, settings: VisualizationSettings) => void,
@@ -76,8 +84,9 @@ type State = {
 }
 
 @DashboardControls
-export default class Dashboard extends Component<*, Props, State> {
-    state = {
+export default class Dashboard extends Component {
+    props: Props;
+    state: State = {
         error: null,
     };
 
@@ -197,7 +206,7 @@ export default class Dashboard extends Component<*, Props, State> {
                             onEditingChange={this.setEditing}
                             setDashboardAttribute={this.setDashboardAttribute}
                             addParameter={this.props.addParameter}
-                            parameters={parametersWidget}
+                            parametersWidget={parametersWidget}
                         />
                     </header>
                     {!isFullscreen && parametersWidget &&
diff --git a/frontend/src/metabase/dashboard/components/DashboardHeader.jsx b/frontend/src/metabase/dashboard/components/DashboardHeader.jsx
index 388589a93ab..7e9a0cfcabc 100644
--- a/frontend/src/metabase/dashboard/components/DashboardHeader.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardHeader.jsx
@@ -44,7 +44,7 @@ type Props = {
     refreshPeriod:          ?number,
     refreshElapsed:         ?number,
 
-    parameters:             React$Element<*>[],
+    parametersWidget:       React$Element<*>,
 
     addCardToDashboard:     ({ dashId: DashCardId, cardId: CardId }) => void,
     archiveDashboard:        (dashboardId: DashboardId) => void,
@@ -58,7 +58,7 @@ type Props = {
     addParameter:           (option: ParameterOption) => Promise<Parameter>,
     setEditingParameter:    (parameterId: ?ParameterId) => void,
 
-    onEditingChange:        () => void,
+    onEditingChange:        (isEditing: boolean) => void,
     onRefreshPeriodChange:  (?number) => void,
     onNightModeChange:      (boolean) => void,
     onFullscreenChange:     (boolean) => void,
@@ -70,8 +70,9 @@ type State = {
     modal: null|"parameters",
 }
 
-export default class DashboardHeader extends Component<*, Props, State> {
-    state = {
+export default class DashboardHeader extends Component {
+    props: Props;
+    state: State = {
         modal: null,
     };
 
@@ -174,7 +175,7 @@ export default class DashboardHeader extends Component<*, Props, State> {
     }
 
     getHeaderButtons() {
-        const { dashboard, parameters, isEditing, isFullscreen, isEditable, isAdmin } = this.props;
+        const { dashboard, parametersWidget, isEditing, isFullscreen, isEditable, isAdmin } = this.props;
         const isEmpty = !dashboard || dashboard.ordered_cards.length === 0;
         const canEdit = isEditable && !!dashboard;
 
@@ -183,8 +184,8 @@ export default class DashboardHeader extends Component<*, Props, State> {
 
         const buttons = [];
 
-        if (isFullscreen && parameters) {
-            buttons.push(parameters);
+        if (isFullscreen && parametersWidget) {
+            buttons.push(parametersWidget);
         }
 
         if (isEditing) {
diff --git a/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx b/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
index f291c2a50ad..37722f5dd89 100644
--- a/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
+++ b/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
@@ -35,9 +35,10 @@ const TICK_PERIOD = 0.25; // seconds
  */
 export default (ComposedComponent: ReactClass<any>) =>
     connect(null, { replace })(
-        class extends Component<*, Props, State> {
+        class extends Component {
             static displayName = "DashboardControls["+(ComposedComponent.displayName || ComposedComponent.name)+"]";
 
+            props: Props;
             state: State = {
                 isFullscreen: false,
                 isNightMode: false,
diff --git a/frontend/src/metabase/meta/types/Visualization.js b/frontend/src/metabase/meta/types/Visualization.js
index e172b2037c2..75b6f11e09c 100644
--- a/frontend/src/metabase/meta/types/Visualization.js
+++ b/frontend/src/metabase/meta/types/Visualization.js
@@ -57,10 +57,8 @@ export type ClickActionPopoverProps = {
     onClose: () => void,
 }
 
-// type Visualization = Component<*, VisualizationProps, *>;
-
-// $FlowFixMe
-export type Series = { card: Card, data: DatasetData }[] & { _raw: Series }
+export type SingleSeries = { card: Card, data: DatasetData };
+export type Series = SingleSeries[] & { _raw: Series }
 
 export type VisualizationProps = {
     series: Series,
diff --git a/frontend/src/metabase/parameters/components/Parameters.jsx b/frontend/src/metabase/parameters/components/Parameters.jsx
index 22ab38f1d39..9e9bfec2dc6 100644
--- a/frontend/src/metabase/parameters/components/Parameters.jsx
+++ b/frontend/src/metabase/parameters/components/Parameters.jsx
@@ -14,8 +14,8 @@ type Props = {
     className?:                 string,
 
     parameters:                 Parameter[],
-    editingParameter:           ?Parameter,
-    parameterValues:            ParameterValues,
+    editingParameter?:           ?Parameter,
+    parameterValues?:           ParameterValues,
 
     isFullscreen?:              boolean,
     isNightMode?:               boolean,
@@ -24,16 +24,18 @@ type Props = {
     vertical?:                  boolean,
     commitImmediately?:         boolean,
 
-    query:                      QueryParams,
+    query?:                     QueryParams,
 
-    setParameterName:           (parameterId: ParameterId, name: string) => void,
-    setParameterValue:          (parameterId: ParameterId, value: string) => void,
-    setParameterDefaultValue:   (parameterId: ParameterId, defaultValue: string) => void,
-    removeParameter:            (parameterId: ParameterId) => void,
-    setEditingParameter:        (parameterId: ParameterId) => void,
+    setParameterName?:          (parameterId: ParameterId, name: string) => void,
+    setParameterValue?:         (parameterId: ParameterId, value: string) => void,
+    setParameterDefaultValue?:  (parameterId: ParameterId, defaultValue: string) => void,
+    removeParameter?:           (parameterId: ParameterId) => void,
+    setEditingParameter?:       (parameterId: ParameterId) => void,
 }
 
-export default class Parameters extends Component<*, Props, *> {
+export default class Parameters extends Component {
+    props: Props;
+
     defaultProps = {
         syncQueryString: false,
         vertical: false,
@@ -43,11 +45,13 @@ export default class Parameters extends Component<*, Props, *> {
     componentWillMount() {
         // sync parameters from URL query string
         const { parameters, setParameterValue, query } = this.props;
-        for (const parameter of parameters) {
-            if (query && query[parameter.slug] != null) {
-                setParameterValue(parameter.id, query[parameter.slug]);
-            } else if (parameter.default != null) {
-                setParameterValue(parameter.id, parameter.default);
+        if (setParameterValue) {
+            for (const parameter of parameters) {
+                if (query && query[parameter.slug] != null) {
+                    setParameterValue(parameter.id, query[parameter.slug]);
+                } else if (parameter.default != null) {
+                    setParameterValue(parameter.id, parameter.default);
+                }
             }
         }
     }
@@ -112,10 +116,10 @@ export default class Parameters extends Component<*, Props, *> {
                         editingParameter={editingParameter}
                         setEditingParameter={setEditingParameter}
 
-                        setName={(name) => setParameterName(parameter.id, name)}
-                        setValue={(value) => setParameterValue(parameter.id, value)}
-                        setDefaultValue={(value) => setParameterDefaultValue(parameter.id, value)}
-                        remove={() => removeParameter(parameter.id)}
+                        setName={setParameterName && ((name) => setParameterName(parameter.id, name))}
+                        setValue={setParameterValue && ((value) => setParameterValue(parameter.id, value))}
+                        setDefaultValue={setParameterDefaultValue && ((value) => setParameterDefaultValue(parameter.id, value))}
+                        remove={removeParameter && (() => removeParameter(parameter.id))}
 
                         commitImmediately={commitImmediately}
                     />
diff --git a/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx b/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx
index c995b515c3a..cd0ed861169 100644
--- a/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/CategoryWidget.jsx
@@ -19,7 +19,7 @@ type State = {
     searchRegex: ?RegExp,
 }
 
-export default class CategoryWidget extends Component<*, Props, State> {
+export default class CategoryWidget extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx b/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx
index c29fd85d6f7..8f8e0b4c834 100644
--- a/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx
+++ b/frontend/src/metabase/parameters/components/widgets/DateAllOptionsWidget.jsx
@@ -61,7 +61,8 @@ type Props = {
 
 type State = { filter: FieldFilter };
 
-export default class DateAllOptionsWidget extends Component<*, Props, State> {
+export default class DateAllOptionsWidget extends Component {
+    props: Props;
     state: State;
 
     constructor(props: Props) {
diff --git a/frontend/src/metabase/public/components/EmbedFrame.jsx b/frontend/src/metabase/public/components/EmbedFrame.jsx
index 76c9443c931..c302bba0c0f 100644
--- a/frontend/src/metabase/public/components/EmbedFrame.jsx
+++ b/frontend/src/metabase/public/components/EmbedFrame.jsx
@@ -32,9 +32,14 @@ type Props = {
     setParameterValue: (id: string, value: string) => void
 }
 
+type State = {
+    innerScroll: boolean
+}
+
 @withRouter
-export default class EmbedFrame extends Component<*, Props, *> {
-    state = {
+export default class EmbedFrame extends Component {
+    props: Props;
+    state: State = {
         innerScroll: true
     }
 
diff --git a/frontend/src/metabase/public/components/widgets/AdvancedEmbedPane.jsx b/frontend/src/metabase/public/components/widgets/AdvancedEmbedPane.jsx
index cf40db04da5..91a3c6081c6 100644
--- a/frontend/src/metabase/public/components/widgets/AdvancedEmbedPane.jsx
+++ b/frontend/src/metabase/public/components/widgets/AdvancedEmbedPane.jsx
@@ -11,7 +11,8 @@ import PreviewPane from "./PreviewPane";
 import EmbedCodePane from "./EmbedCodePane";
 
 import type { Parameter, ParameterId } from "metabase/meta/types/Parameter";
-import type { Pane, EmbedType, EmbeddableResource, EmbeddingParams, DisplayOptions } from "./EmbedModalContent";
+import type { Pane, EmbedType, DisplayOptions } from "./EmbedModalContent";
+import type { EmbeddableResource, EmbeddingParams } from "metabase/public/lib/types";
 
 import _ from "underscore";
 
diff --git a/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx b/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx
index 79af697674f..858030f8ddc 100644
--- a/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx
+++ b/frontend/src/metabase/public/components/widgets/AdvancedSettingsPane.jsx
@@ -16,7 +16,8 @@ const getIconForParameter = (parameter) =>
     parameter.type.indexOf("date/") === 0 ? "calendar" :
     "unknown";
 
-import type { EmbedType, EmbeddableResource, EmbeddingParams, DisplayOptions } from "./EmbedModalContent";
+import type { EmbedType, DisplayOptions } from "./EmbedModalContent";
+import type { EmbeddableResource, EmbeddingParams } from "metabase/public/lib/types";
 import type { Parameter, ParameterId } from "metabase/meta/types/Parameter";
 
 type Props = {
diff --git a/frontend/src/metabase/public/components/widgets/CodeSample.jsx b/frontend/src/metabase/public/components/widgets/CodeSample.jsx
index f236fd875b1..c998e906298 100644
--- a/frontend/src/metabase/public/components/widgets/CodeSample.jsx
+++ b/frontend/src/metabase/public/components/widgets/CodeSample.jsx
@@ -9,25 +9,21 @@ import AceEditor from "metabase/components/TextEditor";
 
 import _ from "underscore";
 
-type CodeSampleOption = {
-    name: string,
-    value: string,
-    source: () => string,
-    mode: string
-};
+import type { CodeSampleOption } from "metabase/public/lib/code";
 
 type Props = {
     className?: string,
     title?: string,
     options?: Array<CodeSampleOption>,
-    onChangeOption: (option: ?CodeSampleOption) => void
+    onChangeOption?: (option: ?CodeSampleOption) => void
 };
 
 type State = {
     name: ?string,
 };
 
-export default class CodeSample extends Component<*, Props, State> {
+export default class CodeSample extends Component {
+    props: Props;
     state: State;
 
     constructor(props: Props) {
diff --git a/frontend/src/metabase/public/components/widgets/EmbedCodePane.jsx b/frontend/src/metabase/public/components/widgets/EmbedCodePane.jsx
index 3958f551e00..173b9f0ec12 100644
--- a/frontend/src/metabase/public/components/widgets/EmbedCodePane.jsx
+++ b/frontend/src/metabase/public/components/widgets/EmbedCodePane.jsx
@@ -15,7 +15,8 @@ import "ace/mode-ruby";
 import "ace/mode-html";
 import "ace/mode-jsx";
 
-import type { EmbedType, EmbeddableResource, EmbeddingParams, DisplayOptions } from "./EmbedModalContent";
+import type { EmbedType, DisplayOptions } from "./EmbedModalContent";
+import type { EmbeddableResource, EmbeddingParams } from "metabase/public/lib/types";
 
 type Props = {
     className: string,
@@ -30,7 +31,9 @@ type Props = {
     displayOptions: DisplayOptions
 }
 
-export default class EmbedCodePane extends Component<*, Props, *> {
+export default class EmbedCodePane extends Component {
+    props: Props;
+
     _embedSample: ?CodeSample;
 
     render() {
diff --git a/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx b/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx
index 8e45a64699f..4133454a0d0 100644
--- a/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx
+++ b/frontend/src/metabase/public/components/widgets/EmbedModalContent.jsx
@@ -14,36 +14,36 @@ import { getSignedPreviewUrl, getUnsignedPreviewUrl, getSignedToken } from "meta
 import { getSiteUrl, getEmbeddingSecretKey, getIsPublicSharingEnabled, getIsApplicationEmbeddingEnabled } from "metabase/selectors/settings";
 import { getUserIsAdmin } from "metabase/selectors/user";
 
-import type { Parameter, ParameterId } from "metabase/meta/types/Parameter";
-
 import MetabaseAnalytics from "metabase/lib/analytics";
 
+import type { Parameter, ParameterId } from "metabase/meta/types/Parameter";
+import type { EmbeddableResource, EmbeddingParams } from "metabase/public/lib/types";
+
 export type Pane = "preview"|"code";
 export type EmbedType = null|"simple"|"application";
 
-export type EmbeddingParams = {
-    [key: string]: string
-}
-
 export type DisplayOptions = {
     theme: ?string,
     bordered: boolean,
     titled: boolean,
 }
 
-export type EmbeddableResource = {
-    id: string,
-    public_uuid: string,
-    embedding_params: EmbeddingParams
-}
-
 type Props = {
     className?: string,
-    siteUrl: string,
-    secretKey: string,
     resource: EmbeddableResource,
     resourceType: string,
     resourceParameters: Parameter[],
+
+    isAdmin: boolean,
+    siteUrl: string,
+    secretKey: string,
+
+    // Flow doesn't understand these are provided by @connect?
+    // isPublicSharingEnabled: bool,
+    // isApplicationEmbeddingEnabled: bool,
+
+    getPublicUrl: (resource: EmbeddableResource, extension: ?string) => string,
+
     onUpdateEnableEmbedding: (enable_embedding: bool) => Promise<void>,
     onUpdateEmbeddingParams: (embedding_params: EmbeddingParams) => Promise<void>,
     onCreatePublicLink: () => Promise<void>,
@@ -56,10 +56,9 @@ type State = {
     embedType: EmbedType,
     embeddingParams: EmbeddingParams,
     displayOptions: DisplayOptions,
-    parameterValues: { [id: ParameterId]: string }
+    parameterValues: { [id: ParameterId]: string },
 };
 
-
 const mapStateToProps = (state, props) => ({
     isAdmin:                        getUserIsAdmin(state, props),
     siteUrl:                        getSiteUrl(state, props),
@@ -69,7 +68,8 @@ const mapStateToProps = (state, props) => ({
 })
 
 @connect(mapStateToProps)
-export default class EmbedModalContent extends Component<*, Props, State> {
+export default class EmbedModalContent extends Component {
+    props: Props;
     state: State;
 
     constructor(props: Props) {
@@ -168,6 +168,7 @@ export default class EmbedModalContent extends Component<*, Props, State> {
                         {/* Center only using margins because  */}
                         <div className="ml-auto mr-auto" style={{maxWidth: 1040}}>
                             <SharingPane
+                                // $FlowFixMe: Flow doesn't understand these are provided by @connect?
                                 {...this.props}
                                 publicUrl={getUnsignedPreviewUrl(siteUrl, resourceType, resource.public_uuid, displayOptions)}
                                 iframeUrl={getUnsignedPreviewUrl(siteUrl, resourceType, resource.public_uuid, displayOptions)}
diff --git a/frontend/src/metabase/public/components/widgets/EmbedWidget.jsx b/frontend/src/metabase/public/components/widgets/EmbedWidget.jsx
index 05a759a4ba8..af42e388e7f 100644
--- a/frontend/src/metabase/public/components/widgets/EmbedWidget.jsx
+++ b/frontend/src/metabase/public/components/widgets/EmbedWidget.jsx
@@ -12,12 +12,29 @@ import EmbedModalContent from "./EmbedModalContent";
 
 import cx from "classnames";
 
+import type { EmbeddableResource, EmbeddingParams } from "metabase/public/lib/types";
+import type { Parameter } from "metabase/meta/types/Parameter";
+
 type Props = {
     className?: string,
-    resourceType: string
+
+    resource: EmbeddableResource,
+    resourceType: string,
+    resourceParameters:  Parameter[],
+
+    siteUrl: string,
+    secretKey: string,
+    isAdmin: boolean,
+
+    getPublicUrl: (resource: EmbeddableResource, extension: ?string) => string,
+
+    onUpdateEnableEmbedding: (enable_embedding: bool) => Promise<void>,
+    onUpdateEmbeddingParams: (embedding_params: EmbeddingParams) => Promise<void>,
+    onCreatePublicLink: () => Promise<void>,
+    onDisablePublicLink: () => Promise<void>,
 };
 
-export default class EmbedWidget extends Component<*, Props, *> {
+export default class EmbedWidget extends Component {
     props: Props;
 
     _modal: ?ModalWithTrigger
@@ -38,7 +55,7 @@ export default class EmbedWidget extends Component<*, Props, *> {
             >
                 <EmbedModalContent
                     {...this.props}
-                    onClose={() => this._modal && this._modal.close()}
+                    onClose={() => { this._modal && this._modal.close() }}
                     className="full-height"
                 />
             </ModalWithTrigger>
diff --git a/frontend/src/metabase/public/components/widgets/SharingPane.jsx b/frontend/src/metabase/public/components/widgets/SharingPane.jsx
index 5e89500a23e..25100f1aec3 100644
--- a/frontend/src/metabase/public/components/widgets/SharingPane.jsx
+++ b/frontend/src/metabase/public/components/widgets/SharingPane.jsx
@@ -12,7 +12,8 @@ import { getPublicEmbedHTML } from "metabase/public/lib/code";
 
 import cx from "classnames";
 
-import type { EmbedType, EmbeddableResource } from "./EmbedModalContent";
+import type { EmbedType } from "./EmbedModalContent";
+import type { EmbeddableResource } from "metabase/public/lib/types";
 
 import MetabaseAnalytics from "metabase/lib/analytics";
 
@@ -20,9 +21,12 @@ type Props = {
     resourceType: string,
     resource: EmbeddableResource,
     extensions?: string[],
+
     isAdmin: bool,
+
     isPublicSharingEnabled: bool,
     isApplicationEmbeddingEnabled: bool,
+
     onCreatePublicLink: () => Promise<void>,
     onDisablePublicLink: () => Promise<void>,
     getPublicUrl: (resource: EmbeddableResource, extension: ?string) => string,
@@ -33,15 +37,11 @@ type State = {
     extension: ?string,
 };
 
-export default class SharingPane extends Component<*, Props, State> {
+export default class SharingPane extends Component {
     props: Props;
-    state: State;
-    constructor(props: Props) {
-        super(props);
-        this.state = {
-            extension: null
-        };
-    }
+    state: State = {
+        extension: null
+    };
 
     static defaultProps = {
         extensions: []
diff --git a/frontend/src/metabase/public/containers/PublicApp.jsx b/frontend/src/metabase/public/containers/PublicApp.jsx
index 9405c6015ae..4d41faef88d 100644
--- a/frontend/src/metabase/public/containers/PublicApp.jsx
+++ b/frontend/src/metabase/public/containers/PublicApp.jsx
@@ -16,7 +16,9 @@ const mapStateToProps = (state, props) => ({
 });
 
 @connect(mapStateToProps)
-export default class PublicApp extends Component<*, Props, *> {
+export default class PublicApp extends Component {
+    props: Props;
+
     render() {
         const { children, errorPage } = this.props;
         if (errorPage) {
diff --git a/frontend/src/metabase/public/containers/PublicDashboard.jsx b/frontend/src/metabase/public/containers/PublicDashboard.jsx
index 6fed2ce5ba6..aa9c4f505ef 100644
--- a/frontend/src/metabase/public/containers/PublicDashboard.jsx
+++ b/frontend/src/metabase/public/containers/PublicDashboard.jsx
@@ -63,7 +63,9 @@ type Props = {
 
 @connect(mapStateToProps, mapDispatchToProps)
 @DashboardControls
-export default class PublicDashboard extends Component<*, Props, *> {
+export default class PublicDashboard extends Component {
+    props: Props;
+
     // $FlowFixMe
     async componentWillMount() {
         const { initialize, fetchDashboard, fetchDashboardCardData, setErrorPage, location, params: { uuid, token }}  = this.props;
diff --git a/frontend/src/metabase/public/containers/PublicQuestion.jsx b/frontend/src/metabase/public/containers/PublicQuestion.jsx
index 5e94aa74f8f..1978c7c98de 100644
--- a/frontend/src/metabase/public/containers/PublicQuestion.jsx
+++ b/frontend/src/metabase/public/containers/PublicQuestion.jsx
@@ -45,7 +45,7 @@ const mapDispatchToProps = {
 
 @connect(null, mapDispatchToProps)
 @ExplicitSize
-export default class PublicQuestion extends Component<*, Props, State> {
+export default class PublicQuestion extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/public/lib/code.js b/frontend/src/metabase/public/lib/code.js
index a0d5b217701..b1184956a38 100644
--- a/frontend/src/metabase/public/lib/code.js
+++ b/frontend/src/metabase/public/lib/code.js
@@ -1,25 +1,33 @@
+/* @flow */
 
 import { optionsToHashParams } from "./embed";
 
-export const getPublicEmbedOptions = ({ iframeUrl }) => [
+export type CodeSampleOption = {
+    name: string,
+    source: () => string,
+    mode?: string,
+    embedOption?: string
+};
+
+export const getPublicEmbedOptions = ({ iframeUrl }: { iframeUrl: string }): CodeSampleOption[] => [
     { name: "HTML",    source: () => html({ iframeUrl: `"${iframeUrl}"` }), mode: "ace/mode/html" }
 ];
 
-export const getSignedEmbedOptions = () => [
+export const getSignedEmbedOptions = (): CodeSampleOption[] => [
     { name: "Mustache",   source: () => html({ iframeUrl: `"{{iframeUrl}}"`, mode: "ace/mode/html" })},
     { name: "Pug / Jade", source: () =>  pug({ iframeUrl: `iframeUrl` })},
     { name: "ERB",        source: () => html({ iframeUrl: `"<%= @iframe_url %>"` })},
     { name: "JSX",        source: () =>  jsx({ iframeUrl: `{iframeUrl}`,     mode: "ace/mode/jsx" })},
 ];
 
-export const getSignTokenOptions = (params) => [
+export const getSignTokenOptions = (params: any): CodeSampleOption[] => [
     { name: "Node.js", source: () => node(params),    mode: "ace/mode/javascript", embedOption: "Pug / Jade" },
     { name: "Ruby",    source: () => ruby(params),    mode: "ace/mode/ruby",       embedOption: "ERB" },
     { name: "Python",  source: () => python(params),  mode: "ace/mode/python" },
     { name: "Clojure", source: () => clojure(params), mode: "ace/mode/clojure" },
 ];
 
-export const getPublicEmbedHTML = (iframeUrl) => html({ iframeUrl: JSON.stringify(iframeUrl )});
+export const getPublicEmbedHTML = (iframeUrl: string): string => html({ iframeUrl: JSON.stringify(iframeUrl )});
 
 const html = ({ iframeUrl }) =>
 `<iframe
diff --git a/frontend/src/metabase/public/lib/types.js b/frontend/src/metabase/public/lib/types.js
new file mode 100644
index 00000000000..7aa0f341524
--- /dev/null
+++ b/frontend/src/metabase/public/lib/types.js
@@ -0,0 +1,11 @@
+/* @flow */
+
+export type EmbeddingParams = {
+    [key: string]: string
+}
+
+export type EmbeddableResource = {
+    id: string,
+    public_uuid: string,
+    embedding_params: EmbeddingParams
+}
diff --git a/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx b/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx
index 23a1601f49a..a7bc8ac5372 100644
--- a/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx
+++ b/frontend/src/metabase/qb/components/TimeseriesFilterWidget.jsx
@@ -30,7 +30,7 @@ import type { TableMetadata } from "metabase/meta/types/Metadata";
 import type { FieldFilter } from "metabase/meta/types/Query";
 
 type Props = {
-    className: string,
+    className?: string,
     card: CardObject,
     tableMetadata: TableMetadata,
     setDatasetQuery: (
@@ -45,8 +45,10 @@ type State = {
     currentFilter: any
 };
 
-export default class TimeseriesFilterWidget extends Component<*, Props, State> {
-    state = {
+export default class TimeseriesFilterWidget extends Component {
+    props: Props;
+    state: State = {
+        // $FlowFixMe
         filter: null,
         filterIndex: -1,
         currentFilter: null
diff --git a/frontend/src/metabase/qb/components/TimeseriesGroupingWidget.jsx b/frontend/src/metabase/qb/components/TimeseriesGroupingWidget.jsx
index c5adb221ad6..c037ce0f097 100644
--- a/frontend/src/metabase/qb/components/TimeseriesGroupingWidget.jsx
+++ b/frontend/src/metabase/qb/components/TimeseriesGroupingWidget.jsx
@@ -25,7 +25,9 @@ type Props = {
     ) => void
 };
 
-export default class TimeseriesGroupingWidget extends Component<*, Props, *> {
+export default class TimeseriesGroupingWidget extends Component {
+    props: Props;
+
     _popover: ?any;
 
     render() {
diff --git a/frontend/src/metabase/query_builder/components/ActionsWidget.jsx b/frontend/src/metabase/query_builder/components/ActionsWidget.jsx
index 981c66149e1..fba9d3ffc8d 100644
--- a/frontend/src/metabase/query_builder/components/ActionsWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/ActionsWidget.jsx
@@ -24,12 +24,19 @@ type Props = {
     setCardAndRun: (card: Card) => void
 };
 
+type State = {
+    isVisible: boolean,
+    isOpen: boolean,
+    selectedActionIndex: ?number
+};
+
 const CIRCLE_SIZE = 48;
 const NEEDLE_SIZE = 20;
 const POPOVER_WIDTH = 350;
 
-export default class ActionsWidget extends Component<*, Props, *> {
-    state = {
+export default class ActionsWidget extends Component {
+    props: Props;
+    state: State = {
         isVisible: false,
         isOpen: false,
         selectedActionIndex: null
diff --git a/frontend/src/metabase/query_builder/components/filters/DateOperatorSelector.jsx b/frontend/src/metabase/query_builder/components/filters/DateOperatorSelector.jsx
index 5aca73f9400..1ac002057af 100644
--- a/frontend/src/metabase/query_builder/components/filters/DateOperatorSelector.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/DateOperatorSelector.jsx
@@ -8,12 +8,10 @@ import { titleCase } from "humanize-plus";
 
 import Icon from "metabase/components/Icon";
 
-type Operator = {
-    name: string
-}
+import type { Operator } from "./pickers/DatePicker";
 
 type Props = {
-    operator: string,
+    operator: ?string,
     operators: Operator[],
     onOperatorChange: (o: Operator) => void,
     hideTimeSelectors?: bool
@@ -23,7 +21,7 @@ type State = {
     expanded: bool
 };
 
-export default class DateOperatorSelector extends Component<*, Props, State> {
+export default class DateOperatorSelector extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/query_builder/components/filters/FilterList.jsx b/frontend/src/metabase/query_builder/components/filters/FilterList.jsx
index b83df09ce9e..b73ae5505d8 100644
--- a/frontend/src/metabase/query_builder/components/filters/FilterList.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/FilterList.jsx
@@ -6,21 +6,21 @@ import { findDOMNode } from 'react-dom';
 import FilterWidget from './FilterWidget.jsx';
 
 import type { Filter } from "metabase/meta/types/Query";
-import type { Table } from "metabase/meta/types/Table";
+import type { TableMetadata } from "metabase/meta/types/Metadata";
 
 type Props = {
     filters: Array<Filter>,
-    tableMetadata: Table,
-    removeFilter: (index: number) => void,
-    updateFilter: (index: number, filter: Filter) => void,
-    maxDisplayValues?: bool
+    tableMetadata: TableMetadata,
+    removeFilter?: (index: number) => void,
+    updateFilter?: (index: number, filter: Filter) => void,
+    maxDisplayValues?: number
 };
 
 type State = {
     shouldScroll: bool
 };
 
-export default class FilterList extends Component<*, Props, State> {
+export default class FilterList extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/query_builder/components/filters/FilterPopover.jsx b/frontend/src/metabase/query_builder/components/filters/FilterPopover.jsx
index e8aca1d2063..fbca456e1b2 100644
--- a/frontend/src/metabase/query_builder/components/filters/FilterPopover.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/FilterPopover.jsx
@@ -19,22 +19,22 @@ import { singularize } from "metabase/lib/formatting";
 
 import cx from "classnames";
 
-import type { FieldFilter, ConcreteField, ExpressionClause } from "metabase/meta/types/Query";
+import type { Filter, FieldFilter, ConcreteField, ExpressionClause } from "metabase/meta/types/Query";
 import type { TableMetadata, FieldMetadata, Operator } from "metabase/meta/types/Metadata";
 
 type Props = {
-    filter?: FieldFilter,
-    onCommitFilter: () => void,
+    filter?: Filter,
+    onCommitFilter: (filter: Filter) => void,
     onClose: () => void,
     tableMetadata: TableMetadata,
-    customFields: ExpressionClause
+    customFields?: ExpressionClause
 }
 
 type State = {
     filter: FieldFilter
 }
 
-export default class FilterPopover extends Component<*, Props, State> {
+export default class FilterPopover extends Component {
     props: Props;
     state: State;
 
@@ -199,7 +199,8 @@ export default class FilterPopover extends Component<*, Props, State> {
                 return (
                     <SelectPicker
                         options={operatorField.values}
-                        values={values}
+                        // $FlowFixMe
+                        values={(values: Array<string>)}
                         onValuesChange={onValuesChange}
                         placeholder={placeholder}
                         multi={operator.multi}
@@ -209,7 +210,8 @@ export default class FilterPopover extends Component<*, Props, State> {
             } else if (operatorField.type === "text") {
                 return (
                     <TextPicker
-                        values={values}
+                        // $FlowFixMe
+                        values={(values: Array<string>)}
                         onValuesChange={onValuesChange}
                         placeholder={placeholder}
                         multi={operator.multi}
@@ -219,7 +221,8 @@ export default class FilterPopover extends Component<*, Props, State> {
             } else if (operatorField.type === "number") {
                 return (
                     <NumberPicker
-                        values={values}
+                        // $FlowFixMe
+                        values={(values: Array<number|null>)}
                         onValuesChange={onValuesChange}
                         placeholder={placeholder}
                         multi={operator.multi}
diff --git a/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx b/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx
index 274faf29b88..6da831633bd 100644
--- a/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/FilterWidget.jsx
@@ -15,22 +15,23 @@ import { isDate } from "metabase/lib/schema_metadata";
 import cx from "classnames";
 import _ from "underscore";
 
-import type { FieldFilter } from "metabase/meta/types/Query";
+import type { Filter } from "metabase/meta/types/Query";
 import type { TableMetadata } from "metabase/meta/types/Metadata";
 
 type Props = {
-    filter: FieldFilter,
+    filter: Filter,
     tableMetadata: TableMetadata,
     index: number,
-    updateFilter: (index: number, field: FieldFilter) => void,
-    removeFilter: (index: number) => void,
+    updateFilter?: (index: number, field: Filter) => void,
+    removeFilter?: (index: number) => void,
     maxDisplayValues?: number
 }
 type State = {
     isOpen: bool
 }
 
-export default class FilterWidget extends Component<*, Props, State> {
+export default class FilterWidget extends Component {
+    props: Props;
     state: State;
 
     constructor(props: Props) {
@@ -144,7 +145,7 @@ export default class FilterWidget extends Component<*, Props, State> {
                     <FilterPopover
                         filter={this.props.filter}
                         tableMetadata={this.props.tableMetadata}
-                        onCommitFilter={(filter) => this.props.updateFilter(this.props.index, filter)}
+                        onCommitFilter={(filter) => this.props.updateFilter && this.props.updateFilter(this.props.index, filter)}
                         onClose={this.close}
                     />
                 </Popover>
diff --git a/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx b/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx
index b6acdcbde66..8c08585fde9 100644
--- a/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx
@@ -20,7 +20,7 @@ type State = {
     expanded: bool
 };
 
-export default class OperatorSelector extends Component<*, Props, State> {
+export default class OperatorSelector extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker.jsx
index 241aaaea4de..fd921191f55 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/DatePicker.jsx
@@ -69,7 +69,7 @@ type CurrentPickerState = {
     showUnits: boolean
 };
 
-class CurrentPicker extends Component<*, CurrentPickerProps, CurrentPickerState> {
+class CurrentPicker extends Component {
     props: CurrentPickerProps;
     state: CurrentPickerState;
 
@@ -223,13 +223,21 @@ type Props = {
     className?: string,
     filter: FieldFilter,
     onFilterChange: (filter: FieldFilter) => void,
-    className: ?string,
-    hideEmptinessOperators: boolean, // Don't show is empty / not empty dialog
+    hideEmptinessOperators?: boolean, // Don't show is empty / not empty dialog
     hideTimeSelectors?: boolean,
     includeAllTime?: boolean,
 }
 
-export default class DatePicker extends Component<*, Props, *> {
+type State = {
+    operators: Operator[]
+}
+
+export default class DatePicker extends Component {
+    props: Props;
+    state: State = {
+        operators: []
+    };
+
     static propTypes = {
         filter: PropTypes.array.isRequired,
         onFilterChange: PropTypes.func.isRequired,
@@ -244,7 +252,7 @@ export default class DatePicker extends Component<*, Props, *> {
         const operator = this._getOperator(operators) || operators[0];
         this.props.onFilterChange(operator.init(this.props.filter));
 
-        this.setState({operators})
+        this.setState({ operators })
     }
 
     _getOperator(operators: Operator[]) {
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/NumberPicker.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/NumberPicker.jsx
index 8fa6e7098ee..763d79577fc 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/NumberPicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/NumberPicker.jsx
@@ -7,9 +7,10 @@ import TextPicker from "./TextPicker.jsx";
 
 type Props = {
     values: Array<number|null>,
-    onValuesChange: (values: Array<number|null>) => void,
+    onValuesChange: (values: any[]) => void,
     placeholder?: string,
     multi?: bool,
+    onCommit: () => void,
 }
 
 type State = {
@@ -17,7 +18,7 @@ type State = {
     validations: bool[]
 }
 
-export default class NumberPicker extends Component<*, Props, State> {
+export default class NumberPicker extends Component {
     props: Props;
     state: State;
 
@@ -60,10 +61,12 @@ export default class NumberPicker extends Component<*, Props, State> {
     }
 
     render() {
+        // $FlowFixMe
+        const values: Array<string|null> = this.state.stringValues.slice(0, this.props.values.length);
         return (
             <TextPicker
                 {...this.props}
-                values={this.state.stringValues.slice(0, this.props.values.length)}
+                values={values}
                 validations={this.state.validations}
                 onValuesChange={(values) => this.onValuesChange(values)}
             />
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/RelativeDatePicker.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/RelativeDatePicker.jsx
index 50be208d149..0019b27ccd6 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/RelativeDatePicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/RelativeDatePicker.jsx
@@ -35,7 +35,7 @@ type State = {
     showUnits: bool
 }
 
-export default class RelativeDatePicker extends Component<*, Props, State> {
+export default class RelativeDatePicker extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/SelectPicker.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/SelectPicker.jsx
index 040d960c548..b325ab9cafc 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/SelectPicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/SelectPicker.jsx
@@ -19,7 +19,7 @@ type SelectOption = {
 type Props = {
     options: Array<SelectOption>,
     values: Array<string>,
-    onValuesChange: (values: any) => void,
+    onValuesChange: (values: any[]) => void,
     placeholder?: string,
     multi?: bool
 }
@@ -29,7 +29,7 @@ type State = {
     searchRegex: ?RegExp,
 }
 
-export default class SelectPicker extends Component<*, Props, State> {
+export default class SelectPicker extends Component {
     state: State;
     props: Props;
 
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/SpecificDatePicker.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/SpecificDatePicker.jsx
index 83d9ab5ae3a..4560c1febfd 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/SpecificDatePicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/SpecificDatePicker.jsx
@@ -27,7 +27,7 @@ type State = {
     showCalendar: bool
 }
 
-export default class SpecificDatePicker extends Component<*, Props, State> {
+export default class SpecificDatePicker extends Component {
     props: Props;
     state: State;
 
diff --git a/frontend/src/metabase/query_builder/components/filters/pickers/TextPicker.jsx b/frontend/src/metabase/query_builder/components/filters/pickers/TextPicker.jsx
index 29e58cb2e13..1009b1f2882 100644
--- a/frontend/src/metabase/query_builder/components/filters/pickers/TextPicker.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/pickers/TextPicker.jsx
@@ -9,14 +9,21 @@ import _ from "underscore";
 
 type Props = {
     values: Array<string|null>,
-    onValuesChange: (values: Array<string|null>) => void,
+    onValuesChange: (values: any[]) => void,
     validations: bool[],
     placeholder?: string,
     multi?: bool,
     onCommit: () => void,
 };
 
-export default class TextPicker extends Component<*, Props, *> {
+type State = {
+    fieldString: string,
+}
+
+export default class TextPicker extends Component {
+    props: Props;
+    state: State;
+
     static propTypes = {
         values: PropTypes.array.isRequired,
         onValuesChange: PropTypes.func.isRequired,
diff --git a/frontend/src/metabase/visualizations/components/ChartClickActions.jsx b/frontend/src/metabase/visualizations/components/ChartClickActions.jsx
index 13182daf6a5..73b71b471e6 100644
--- a/frontend/src/metabase/visualizations/components/ChartClickActions.jsx
+++ b/frontend/src/metabase/visualizations/components/ChartClickActions.jsx
@@ -52,7 +52,7 @@ Object.values(SECTIONS).map((section, index) => {
 });
 
 type Props = {
-    clicked: ClickObject,
+    clicked: ?ClickObject,
     clickActions: ?ClickAction[],
     onChangeCardAndRun: (card: ?Card) => void,
     onClose: () => void
@@ -62,7 +62,8 @@ type State = {
     popoverAction: ?ClickAction;
 }
 
-export default class ChartClickActions extends Component<*, Props, State> {
+export default class ChartClickActions extends Component {
+    props: Props;
     state: State = {
         popoverAction: null
     };
diff --git a/frontend/src/metabase/visualizations/components/FunnelBar.jsx b/frontend/src/metabase/visualizations/components/FunnelBar.jsx
index 1028592b937..50eb5245c74 100644
--- a/frontend/src/metabase/visualizations/components/FunnelBar.jsx
+++ b/frontend/src/metabase/visualizations/components/FunnelBar.jsx
@@ -9,7 +9,9 @@ import { assocIn } from "icepick";
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
-export default class BarFunnel extends Component<*, VisualizationProps, *> {
+export default class BarFunnel extends Component {
+    props: VisualizationProps;
+
     render() {
         return (
             <BarChart
diff --git a/frontend/src/metabase/visualizations/components/FunnelNormal.jsx b/frontend/src/metabase/visualizations/components/FunnelNormal.jsx
index 104b44a799a..17f43b109c8 100644
--- a/frontend/src/metabase/visualizations/components/FunnelNormal.jsx
+++ b/frontend/src/metabase/visualizations/components/FunnelNormal.jsx
@@ -27,7 +27,9 @@ type StepInfo = {
     clicked?: ClickObject,
 };
 
-export default class Funnel extends Component<*, VisualizationProps, *> {
+export default class Funnel extends Component {
+    props: VisualizationProps;
+
     render() {
         const { className, series, gridSize, hovered, onHoverChange, onVisualizationClick, visualizationIsClickable } = this.props;
 
@@ -35,7 +37,7 @@ export default class Funnel extends Component<*, VisualizationProps, *> {
         const metricIndex = 1;
         const cols = series[0].data.cols;
         // $FlowFixMe
-        const rows = series.map(s => s.data.rows[0]);
+        const rows: number[][] = series.map(s => s.data.rows[0]);
 
         const funnelSmallSize = gridSize && (gridSize.width < 7 || gridSize.height <= 5);
 
diff --git a/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx b/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
index 17a6b75f3aa..759c375e64b 100644
--- a/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
+++ b/frontend/src/metabase/visualizations/components/LineAreaBarChart.jsx
@@ -43,7 +43,9 @@ for (let i = 0; i < MAX_SERIES; i++) {
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
-export default class LineAreaBarChart extends Component<*, VisualizationProps, *> {
+export default class LineAreaBarChart extends Component {
+    props: VisualizationProps;
+
     static identifier: string;
     static renderer: (element: Element, props: VisualizationProps) => any;
 
@@ -186,6 +188,7 @@ export default class LineAreaBarChart extends Component<*, VisualizationProps, *
 
         let titleHeaderSeries, multiseriesHeaderSeries;
 
+        // $FlowFixMe
         let originalSeries = series._raw || series;
         let cardIds = _.uniq(originalSeries.map(s => s.card.id))
 
diff --git a/frontend/src/metabase/visualizations/components/PinMap.jsx b/frontend/src/metabase/visualizations/components/PinMap.jsx
index e642709d999..a5f1371878b 100644
--- a/frontend/src/metabase/visualizations/components/PinMap.jsx
+++ b/frontend/src/metabase/visualizations/components/PinMap.jsx
@@ -31,7 +31,10 @@ const MAP_COMPONENTS_BY_TYPE = {
     "tiles": LeafletTilePinMap,
 }
 
-export default class PinMap extends Component<*, Props, State> {
+export default class PinMap extends Component {
+    props: Props;
+    state: State;
+
     static uiName = "Pin Map";
     static identifier = "pin_map";
     static iconName = "pinmap";
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
index 32e26d8220e..af30802aff9 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive.jsx
+++ b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
@@ -49,7 +49,7 @@ type CellRendererProps = {
 type GridComponent = Component<void, void, void> & { recomputeGridSize: () => void }
 
 @ExplicitSize
-export default class TableInteractive extends Component<*, Props, State> {
+export default class TableInteractive extends Component {
     state: State;
     props: Props;
 
diff --git a/frontend/src/metabase/visualizations/components/TableSimple.jsx b/frontend/src/metabase/visualizations/components/TableSimple.jsx
index c79e1791020..d8ebaca1b90 100644
--- a/frontend/src/metabase/visualizations/components/TableSimple.jsx
+++ b/frontend/src/metabase/visualizations/components/TableSimple.jsx
@@ -32,7 +32,8 @@ type State = {
 }
 
 @ExplicitSize
-export default class TableSimple extends Component<*, Props, State> {
+export default class TableSimple extends Component {
+    props: Props;
     state: State;
 
     constructor(props: Props) {
diff --git a/frontend/src/metabase/visualizations/components/Visualization.jsx b/frontend/src/metabase/visualizations/components/Visualization.jsx
index f81cef63a66..d476580e73e 100644
--- a/frontend/src/metabase/visualizations/components/Visualization.jsx
+++ b/frontend/src/metabase/visualizations/components/Visualization.jsx
@@ -84,7 +84,7 @@ type Props = {
 
 type State = {
     series: ?Series,
-    CardVisualization: ?(Component<*, VisualizationSettings, *> & {
+    CardVisualization: ?(Component<void, VisualizationSettings, void> & {
         checkRenderable: (any, any) => void,
         noHeader: boolean
     }),
@@ -98,7 +98,7 @@ type State = {
 }
 
 @ExplicitSize
-export default class Visualization extends Component<*, Props, State> {
+export default class Visualization extends Component {
     state: State;
     props: Props;
 
@@ -414,12 +414,14 @@ export default class Visualization extends Component<*, Props, State> {
                     series={series}
                     hovered={hovered}
                 />
-                <ChartClickActions
-                    clicked={clicked}
-                    clickActions={clickActions}
-                    onChangeCardAndRun={this.props.onChangeCardAndRun ? this.handleOnChangeCardAndRun : null}
-                    onClose={() => this.setState({ clicked: null })}
-                />
+                { this.props.onChangeCardAndRun &&
+                    <ChartClickActions
+                        clicked={clicked}
+                        clickActions={clickActions}
+                        onChangeCardAndRun={this.handleOnChangeCardAndRun}
+                        onClose={() => this.setState({ clicked: null })}
+                    />
+                }
             </div>
         );
     }
diff --git a/frontend/src/metabase/visualizations/index.js b/frontend/src/metabase/visualizations/index.js
index 0297c20a1cc..f9d9595e62a 100644
--- a/frontend/src/metabase/visualizations/index.js
+++ b/frontend/src/metabase/visualizations/index.js
@@ -62,6 +62,7 @@ export function getVisualizationTransformed(series: Series) {
             series = CardVisualization.transformSeries(series);
         }
         if (series !== lastSeries) {
+            // $FlowFixMe
             series = [...series];
             // $FlowFixMe
             series._raw = lastSeries;
diff --git a/frontend/src/metabase/visualizations/lib/LineAreaBarRenderer.js b/frontend/src/metabase/visualizations/lib/LineAreaBarRenderer.js
index 0752437e658..89481add07b 100644
--- a/frontend/src/metabase/visualizations/lib/LineAreaBarRenderer.js
+++ b/frontend/src/metabase/visualizations/lib/LineAreaBarRenderer.js
@@ -35,7 +35,7 @@ import { parseTimestamp } from "metabase/lib/time";
 
 import { datasetContainsNoResults } from "metabase/lib/dataset";
 
-import type { Series, ClickObject } from "metabase/meta/types/Visualization"
+import type { SingleSeries, ClickObject } from "metabase/meta/types/Visualization"
 
 const MIN_PIXELS_PER_TICK = { x: 100, y: 32 };
 const BAR_PADDING_RATIO = 0.2;
@@ -109,7 +109,7 @@ function initChart(chart, element) {
 function applyChartTimeseriesXAxis(chart, settings, series, xValues, xDomain, xInterval) {
     // find the first nonempty single series
     // $FlowFixMe
-    const firstSeries: Series = _.find(series, (s) => !datasetContainsNoResults(s.data));
+    const firstSeries: SingleSeries = _.find(series, (s) => !datasetContainsNoResults(s.data));
 
     // setup an x-axis where the dimension is a timeseries
     let dimensionColumn = firstSeries.data.cols[0];
@@ -170,7 +170,7 @@ function applyChartTimeseriesXAxis(chart, settings, series, xValues, xDomain, xI
 function applyChartQuantitativeXAxis(chart, settings, series, xValues, xDomain, xInterval) {
     // find the first nonempty single series
     // $FlowFixMe
-    const firstSeries: Series = _.find(series, (s) => !datasetContainsNoResults(s.data));
+    const firstSeries: SingleSeries = _.find(series, (s) => !datasetContainsNoResults(s.data));
     const dimensionColumn = firstSeries.data.cols[0];
 
     if (settings["graph.x_axis.labels_enabled"]) {
@@ -211,7 +211,7 @@ function applyChartQuantitativeXAxis(chart, settings, series, xValues, xDomain,
 function applyChartOrdinalXAxis(chart, settings, series, xValues) {
     // find the first nonempty single series
     // $FlowFixMe
-    const firstSeries: Series = _.find(series, (s) => !datasetContainsNoResults(s.data));
+    const firstSeries: SingleSeries = _.find(series, (s) => !datasetContainsNoResults(s.data));
 
     const dimensionColumn = firstSeries.data.cols[0];
 
@@ -858,7 +858,7 @@ export default function lineAreaBar(element, { series, onHoverChange, onVisualiz
 
     // find the first nonempty single series
     // $FlowFixMe
-    const firstSeries: Series = _.find(series, (s) => !datasetContainsNoResults(s.data));
+    const firstSeries: SingleSeries = _.find(series, (s) => !datasetContainsNoResults(s.data));
 
     const isDimensionTimeseries = dimensionIsTimeseries(firstSeries.data);
     const isDimensionNumeric = dimensionIsNumeric(firstSeries.data);
diff --git a/frontend/src/metabase/visualizations/visualizations/Funnel.jsx b/frontend/src/metabase/visualizations/visualizations/Funnel.jsx
index 4050d610c05..dd73f1a37a5 100644
--- a/frontend/src/metabase/visualizations/visualizations/Funnel.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Funnel.jsx
@@ -17,7 +17,9 @@ import cx from "classnames";
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
-export default class Funnel extends Component<*, VisualizationProps, *> {
+export default class Funnel extends Component {
+    props: VisualizationProps;
+
     static uiName = "Funnel";
     static identifier = "funnel";
     static iconName = "funnel";
@@ -114,6 +116,7 @@ export default class Funnel extends Component<*, VisualizationProps, *> {
                 <div className={cx(className, "flex flex-column p1")}>
                     <LegendHeader
                         className="flex-no-shrink"
+                        // $FlowFixMe
                         series={series._raw || series}
                         actionButtons={actionButtons}
                         onChangeCardAndRun={onChangeCardAndRun}
diff --git a/frontend/src/metabase/visualizations/visualizations/Map.jsx b/frontend/src/metabase/visualizations/visualizations/Map.jsx
index cd65132915a..1be87044162 100644
--- a/frontend/src/metabase/visualizations/visualizations/Map.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Map.jsx
@@ -14,7 +14,9 @@ import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
 import _ from "underscore";
 
-export default class Map extends Component<*, VisualizationProps, *> {
+export default class Map extends Component {
+    props: VisualizationProps;
+
     static uiName = "Map";
     static identifier = "map";
     static iconName = "pinmap";
diff --git a/frontend/src/metabase/visualizations/visualizations/PieChart.jsx b/frontend/src/metabase/visualizations/visualizations/PieChart.jsx
index 73cc1b27ae7..aa494237f81 100644
--- a/frontend/src/metabase/visualizations/visualizations/PieChart.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/PieChart.jsx
@@ -31,9 +31,9 @@ const PERCENT_REGEX = /percent/i;
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
-type Props = VisualizationProps;
+export default class PieChart extends Component {
+    props: VisualizationProps;
 
-export default class PieChart extends Component<*, Props, *> {
     static uiName = "Pie";
     static identifier = "pie";
     static iconName = "pie";
diff --git a/frontend/src/metabase/visualizations/visualizations/Progress.jsx b/frontend/src/metabase/visualizations/visualizations/Progress.jsx
index 1cf8fa459e3..5141e68ec6a 100644
--- a/frontend/src/metabase/visualizations/visualizations/Progress.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Progress.jsx
@@ -17,7 +17,9 @@ const MAX_BAR_HEIGHT = 65;
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
-export default class Progress extends Component<*, VisualizationProps, *> {
+export default class Progress extends Component {
+    props: VisualizationProps;
+
     static uiName = "Progress";
     static identifier = "progress";
     static iconName = "progress";
diff --git a/frontend/src/metabase/visualizations/visualizations/Scalar.jsx b/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
index a973509d374..27aed59e259 100644
--- a/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
@@ -16,7 +16,9 @@ import d3 from "d3";
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
 
-export default class Scalar extends Component<*, VisualizationProps, *> {
+export default class Scalar extends Component {
+    props: VisualizationProps;
+
     static uiName = "Number";
     static identifier = "scalar";
     static iconName = "number";
diff --git a/frontend/src/metabase/visualizations/visualizations/Table.jsx b/frontend/src/metabase/visualizations/visualizations/Table.jsx
index d45ac9c8611..07840ddd15d 100644
--- a/frontend/src/metabase/visualizations/visualizations/Table.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Table.jsx
@@ -29,7 +29,8 @@ type State = {
     data: ?DatasetData
 }
 
-export default class Table extends Component<*, Props, State> {
+export default class Table extends Component {
+    props: Props;
     state: State;
 
     static uiName = "Table";
@@ -126,7 +127,13 @@ export default class Table extends Component<*, Props, State> {
         const sort = getIn(card, ["dataset_query", "query", "order_by"]) || null;
         const isPivoted = settings["table.pivot"];
         const TableComponent = isDashboard ? TableSimple : TableInteractive;
+
+        if (!data) {
+            return null;
+        }
+
         return (
+            // $FlowFixMe
             <TableComponent
                 {...this.props}
                 data={data}
-- 
GitLab