From d9edcb845375ea3719b86640860110ce260979ca Mon Sep 17 00:00:00 2001
From: Tom Robinson <tlrobinson@gmail.com>
Date: Tue, 18 Sep 2018 16:11:37 -0700
Subject: [PATCH] Fix flow

---
 .../src/metabase/components/ButtonGroup.jsx   | 15 ++++++-
 frontend/src/metabase/lib/formatting.js       | 41 +++++++++++++++----
 .../components/TableInteractive.jsx           |  2 +-
 .../metabase/visualizations/lib/settings.js   |  1 -
 .../visualizations/visualizations/Scalar.jsx  |  4 +-
 .../visualizations/visualizations/Table.jsx   |  4 +-
 6 files changed, 55 insertions(+), 12 deletions(-)

diff --git a/frontend/src/metabase/components/ButtonGroup.jsx b/frontend/src/metabase/components/ButtonGroup.jsx
index 7083eeaad17..286af5c1a4c 100644
--- a/frontend/src/metabase/components/ButtonGroup.jsx
+++ b/frontend/src/metabase/components/ButtonGroup.jsx
@@ -4,6 +4,19 @@ import React from "react";
 
 import cx from "classnames";
 
+type Value = any;
+type Option = any;
+
+type Props = {
+  value: Value,
+  onChange: (value: Value) => void,
+  options: Option[],
+  optionNameFn?: (o: Option) => string | React$Element<any>,
+  optionValueFn?: (o: Option) => Value,
+  optionKeyFn?: (o: Option) => string,
+  className?: string,
+};
+
 const ButtonGroup = ({
   value,
   onChange,
@@ -12,7 +25,7 @@ const ButtonGroup = ({
   optionValueFn = o => o.value,
   optionKeyFn = optionValueFn,
   className,
-}) => {
+}: Props) => {
   return (
     <div className={cx(className, "rounded bordered flex")}>
       {options.map((o, index) => (
diff --git a/frontend/src/metabase/lib/formatting.js b/frontend/src/metabase/lib/formatting.js
index c97dcfd01ca..f1f2ccdfe95 100644
--- a/frontend/src/metabase/lib/formatting.js
+++ b/frontend/src/metabase/lib/formatting.js
@@ -38,17 +38,19 @@ import type { DatetimeUnit } from "metabase/meta/types/Query";
 import type { Moment } from "metabase/meta/types";
 
 export type FormattingOptions = {
+  // GENERIC
   column?: Column | Field,
   majorWidth?: number,
   type?: "axis" | "cell" | "tooltip",
   jsx?: boolean,
   // render links for type/URLs, type/Email, etc
   rich?: boolean,
-  // number options:
   compact?: boolean,
   // always format as the start value rather than the range, e.x. for bar histogram
   noRange?: boolean,
+  // NUMBER
   // TODO: docoument these:
+  number_style?: null | "decimal" | "percent" | "scientific" | "currency",
   prefix?: string,
   suffix?: string,
   scale?: number,
@@ -61,8 +63,21 @@ export type FormattingOptions = {
   useGrouping?: boolean,
   // decimals sets both minimumFractionDigits and maximumFractionDigits
   decimals?: number,
+  // STRING
+  view_as?: "link" | "email_link" | "image",
+  link_text?: string,
+  // DATE/TIME
+  // date/timeout style string that is used to derive a date_format or time_format for different units, see metabase/lib/formatting/date
+  date_style?: string,
+  time_style?: string,
+  date_format?: string,
+  date_abbreviate?: boolean,
+  time_format?: string,
+  time_enabled?: null | "minutes" | "seconds" | "milliseconds",
 };
 
+type FormattedString = string | React$Element<any>;
+
 const DEFAULT_NUMBER_OPTIONS: FormattingOptions = {
   compact: false,
   maximumFractionDigits: 2,
@@ -105,6 +120,7 @@ const RANGE_SEPARATOR = ` – `;
 export function numberFormatterForOptions(options: FormattingOptions) {
   options = { ...getDefaultNumberOptions(options), ...options };
   // if we don't provide a locale much of the formatting doens't work
+  // $FlowFixMe: doesn't know about Intl.NumberFormat
   return new Intl.NumberFormat(options.locale || "en", {
     style: options.number_style,
     currency: options.currency,
@@ -146,7 +162,10 @@ export function formatNumber(number: number, options: FormattingOptions = {}) {
   }
 }
 
-function formatNumberScientific(value: number, options: FormattingOptions) {
+function formatNumberScientific(
+  value: number,
+  options: FormattingOptions,
+): FormattedString {
   if (options.maximumFractionDigits) {
     value = d3.round(value, options.maximumFractionDigits);
   }
@@ -207,12 +226,19 @@ export function formatCoordinate(
 
 export function formatRange(
   range: [number, number],
-  formatter: (value: number) => string,
+  formatter: (value: number) => any,
   options: FormattingOptions = {},
 ) {
-  return range
-    .map(value => formatter(value, options))
-    .join(` ${RANGE_SEPARATOR} `);
+  const [start, end] = range.map(value => formatter(value, options));
+  if ((options.jsx && typeof start !== "string") || typeof end !== "string") {
+    return (
+      <span>
+        {start} {RANGE_SEPARATOR} {end}
+      </span>
+    );
+  } else {
+    return `${start} ${RANGE_SEPARATOR} ${start}`;
+  }
 }
 
 function formatMajorMinor(major, minor, options = {}) {
@@ -327,7 +353,7 @@ function formatDateTime(value, options) {
       options,
     );
   } else {
-    if (options.show_time === false) {
+    if (options.time_enabled === false) {
       return m.format(options.date_abbreviate ? "ll" : "LL");
     } else {
       return m.format(options.date_abbreviate ? "llll" : "LLLL");
@@ -486,6 +512,7 @@ export function formatValue(value: Value, options: FormattingOptions = {}) {
         </span>
       );
     } else {
+      // $FlowFixMe: doesn't understand formatted is a string
       return `${options.prefix || ""}${formatted}${options.suffix || ""}`;
     }
   } else {
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
index c8025df11fb..468a1bd9202 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive.jsx
+++ b/frontend/src/metabase/visualizations/components/TableInteractive.jsx
@@ -160,7 +160,7 @@ export default class TableInteractive extends Component {
     }
   }
 
-  _getColumnSettings(props) {
+  _getColumnSettings(props: Props) {
     return props.data && props.data.cols.map(col => props.settings.column(col));
   }
 
diff --git a/frontend/src/metabase/visualizations/lib/settings.js b/frontend/src/metabase/visualizations/lib/settings.js
index 605de962f63..034c16692d4 100644
--- a/frontend/src/metabase/visualizations/lib/settings.js
+++ b/frontend/src/metabase/visualizations/lib/settings.js
@@ -208,7 +208,6 @@ export function getSettingsWidgets(
 ) {
   return Object.keys(settingDefs)
     .map(settingId =>
-      // $FlowFixMe: doesn't understand settingDef is a SettingDef
       getSettingWidget(
         settingDefs,
         settingId,
diff --git a/frontend/src/metabase/visualizations/visualizations/Scalar.jsx b/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
index a1d0c03c455..7e0ed33454a 100644
--- a/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Scalar.jsx
@@ -17,6 +17,8 @@ import cx from "classnames";
 import _ from "underscore";
 
 import type { VisualizationProps } from "metabase/meta/types/Visualization";
+import type { Column } from "metabase/meta/types/Dataset";
+import type { VisualizationSettings } from "metabase/meta/types/Card";
 
 // convert legacy `scalar.*` visualization settings to format options
 function legacyScalarSettingsToFormatOptions(settings) {
@@ -126,7 +128,7 @@ export default class Scalar extends Component {
     },
   };
 
-  _getColumnIndex(cols, settings) {
+  _getColumnIndex(cols: Column[], settings: VisualizationSettings) {
     const columnIndex = _.findIndex(
       cols,
       col => col.name === settings["scalar.field"],
diff --git a/frontend/src/metabase/visualizations/visualizations/Table.jsx b/frontend/src/metabase/visualizations/visualizations/Table.jsx
index cd330466680..dc4869f6078 100644
--- a/frontend/src/metabase/visualizations/visualizations/Table.jsx
+++ b/frontend/src/metabase/visualizations/visualizations/Table.jsx
@@ -130,7 +130,9 @@ export default class Table extends Component {
     }
     if (isString(column)) {
       let defaultValue = null;
-      const options = [{ name: t`Off`, value: null }];
+      const options: { name: string, value: null | string }[] = [
+        { name: t`Off`, value: null },
+      ];
       if (!column.special_type || isURL(column)) {
         defaultValue = "link";
         options.push({ name: t`Link`, value: "link" });
-- 
GitLab